mirror of
https://github.com/schoebel/mars
synced 2025-02-10 00:58:24 +00:00
mapfree: speedup rmmod
This commit is contained in:
parent
23d03eaf2f
commit
77b7ea1589
@ -44,6 +44,15 @@ EXPORT_SYMBOL_GPL(mapfree_period_sec);
|
|||||||
int mapfree_grace_keep_mb = 16;
|
int mapfree_grace_keep_mb = 16;
|
||||||
EXPORT_SYMBOL_GPL(mapfree_grace_keep_mb);
|
EXPORT_SYMBOL_GPL(mapfree_grace_keep_mb);
|
||||||
|
|
||||||
|
/* Internal reaction time.
|
||||||
|
* Not critical, except when waiting for rmmod ;)
|
||||||
|
*/
|
||||||
|
#define MAPFREE_SLEEP_JIFFIES (HZ / 10 + 1)
|
||||||
|
|
||||||
|
int mapfree_sleep_jiffies = MAPFREE_SLEEP_JIFFIES;
|
||||||
|
|
||||||
|
static DECLARE_WAIT_QUEUE_HEAD(mapfree_event);
|
||||||
|
|
||||||
struct mf_hash_anchor {
|
struct mf_hash_anchor {
|
||||||
struct rw_semaphore hash_mutex;
|
struct rw_semaphore hash_mutex;
|
||||||
struct list_head hash_anchor;
|
struct list_head hash_anchor;
|
||||||
@ -343,15 +352,15 @@ int mapfree_thread(void *data)
|
|||||||
{
|
{
|
||||||
struct mf_hash_anchor *mha = data;
|
struct mf_hash_anchor *mha = data;
|
||||||
|
|
||||||
while (!brick_thread_should_stop()) {
|
for (;;) {
|
||||||
struct mapfree_info *mf = NULL;
|
struct mapfree_info *mf = NULL;
|
||||||
struct list_head *tmp;
|
struct list_head *tmp;
|
||||||
long long eldest = 0;
|
long long eldest = 0;
|
||||||
|
bool is_empty = true;
|
||||||
|
|
||||||
brick_msleep(500);
|
wait_event_interruptible_timeout(mapfree_event,
|
||||||
|
!mapfree_period_sec,
|
||||||
if (mapfree_period_sec <= 0)
|
mapfree_sleep_jiffies);
|
||||||
continue;
|
|
||||||
|
|
||||||
down_read(&mha->hash_mutex);
|
down_read(&mha->hash_mutex);
|
||||||
|
|
||||||
@ -359,9 +368,14 @@ int mapfree_thread(void *data)
|
|||||||
tmp != &mha->hash_anchor;
|
tmp != &mha->hash_anchor;
|
||||||
tmp = tmp->next) {
|
tmp = tmp->next) {
|
||||||
struct mapfree_info *_mf = container_of(tmp, struct mapfree_info, mf_head);
|
struct mapfree_info *_mf = container_of(tmp, struct mapfree_info, mf_head);
|
||||||
|
|
||||||
|
if (_mf->mf_finished)
|
||||||
|
continue;
|
||||||
|
is_empty = false;
|
||||||
if (unlikely(!_mf->mf_jiffies)) {
|
if (unlikely(!_mf->mf_jiffies)) {
|
||||||
_mf->mf_jiffies = jiffies;
|
_mf->mf_jiffies = jiffies;
|
||||||
continue;
|
if (mapfree_period_sec > 0)
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if ((long long)jiffies - _mf->mf_jiffies > mapfree_period_sec * HZ &&
|
if ((long long)jiffies - _mf->mf_jiffies > mapfree_period_sec * HZ &&
|
||||||
(!mf || _mf->mf_jiffies < eldest)) {
|
(!mf || _mf->mf_jiffies < eldest)) {
|
||||||
@ -375,11 +389,18 @@ int mapfree_thread(void *data)
|
|||||||
up_read(&mha->hash_mutex);
|
up_read(&mha->hash_mutex);
|
||||||
|
|
||||||
if (!mf) {
|
if (!mf) {
|
||||||
|
if (!is_empty)
|
||||||
|
continue;
|
||||||
|
if (brick_thread_should_stop())
|
||||||
|
break;
|
||||||
|
brick_msleep(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapfree_pages(mf, mapfree_grace_keep_mb);
|
mapfree_pages(mf, mapfree_grace_keep_mb);
|
||||||
|
|
||||||
|
if (brick_thread_should_stop())
|
||||||
|
mf->mf_finished = true;
|
||||||
mf->mf_jiffies = jiffies;
|
mf->mf_jiffies = jiffies;
|
||||||
mapfree_put(mf);
|
mapfree_put(mf);
|
||||||
}
|
}
|
||||||
@ -496,6 +517,7 @@ int __init init_mars_mapfree(void)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
MARS_DBG("init_mapfree()\n");
|
MARS_DBG("init_mapfree()\n");
|
||||||
|
mapfree_sleep_jiffies = MAPFREE_SLEEP_JIFFIES;
|
||||||
for (i = 0; i < MAPFREE_HASH; i++) {
|
for (i = 0; i < MAPFREE_HASH; i++) {
|
||||||
struct task_struct *thread;
|
struct task_struct *thread;
|
||||||
|
|
||||||
@ -518,10 +540,16 @@ void exit_mars_mapfree(void)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
MARS_DBG("exit_mapfree()\n");
|
MARS_DBG("exit_mapfree()\n");
|
||||||
|
mapfree_period_sec = -1;
|
||||||
|
mapfree_sleep_jiffies = 1;
|
||||||
|
wake_up_interruptible_all(&mapfree_event);
|
||||||
|
|
||||||
for (i = 0; i < MAPFREE_HASH; i++) {
|
for (i = 0; i < MAPFREE_HASH; i++) {
|
||||||
if (likely(mf_table[i].hash_thread)) {
|
struct task_struct *thread = mf_table[i].hash_thread;
|
||||||
brick_thread_stop(mf_table[i].hash_thread);
|
|
||||||
|
if (thread) {
|
||||||
mf_table[i].hash_thread = NULL;
|
mf_table[i].hash_thread = NULL;
|
||||||
|
brick_thread_stop(thread);
|
||||||
}
|
}
|
||||||
CHECK_HEAD_EMPTY(&mf_table[i].hash_anchor);
|
CHECK_HEAD_EMPTY(&mf_table[i].hash_anchor);
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,7 @@ struct mapfree_info {
|
|||||||
loff_t mf_max;
|
loff_t mf_max;
|
||||||
long long mf_jiffies;
|
long long mf_jiffies;
|
||||||
unsigned int mf_hash;
|
unsigned int mf_hash;
|
||||||
|
bool mf_finished;
|
||||||
struct dirty_length mf_length[DIRTY_MAX];
|
struct dirty_length mf_length[DIRTY_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user