diff options
| -rw-r--r-- | mm/uksm.c | 28 |
1 files changed, 24 insertions, 4 deletions
@@ -4586,14 +4586,32 @@ static int ksmd_should_run(void) return uksm_run & UKSM_RUN_MERGE; } +static void process_timeout(unsigned long data) +{ + wake_up_process((struct task_struct *)data); +} + static int uksm_scan_thread(void *nothing) { - long timeout = 60 * HZ; + long timeout = 120 * HZ, expire; + struct timer_list timer; + set_freezable(); set_user_nice(current, 15); + setup_deferrable_timer_on_stack(&timer, process_timeout, + (unsigned long)current); + while (!kthread_should_stop()) { - timeout = schedule_timeout_interruptible(timeout); + __set_current_state(TASK_INTERRUPTIBLE); + expire = jiffies + timeout; + mod_timer(&timer, expire); + schedule(); + del_singleshot_timer_sync(&timer); + + timeout = expire - jiffies; + if (timeout < 0) + timeout = 0; if (unlikely(try_to_freeze())) timeout = 5 * HZ; @@ -4609,15 +4627,17 @@ static int uksm_scan_thread(void *nothing) if (likely(ksmd_should_run())) { uksm_do_scan(); mutex_unlock(&uksm_thread_mutex); - timeout = uksm_sleep_jiffies - jiffies % uksm_sleep_jiffies; uksm_sleep_times++; } else { mutex_unlock(&uksm_thread_mutex); wait_event_freezable(uksm_thread_wait, ksmd_should_run() || kthread_should_stop()); - timeout = uksm_sleep_jiffies; } + timeout = uksm_sleep_jiffies; } + + destroy_timer_on_stack(&timer); + return 0; } |
