提交 878aee7d 编写于 作者: A Andrea Arcangeli 提交者: Linus Torvalds

thp: freeze khugepaged and ksmd

It's unclear why schedule friendly kernel threads can't be taken away by
the CPU through the scheduler itself.  It's safer to stop them as they can
trigger memory allocation, if kswapd also freezes itself to avoid
generating I/O they have too.
Signed-off-by: NAndrea Arcangeli <aarcange@redhat.com>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 8ee53820
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/mm_inline.h> #include <linux/mm_inline.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/khugepaged.h> #include <linux/khugepaged.h>
#include <linux/freezer.h>
#include <asm/tlb.h> #include <asm/tlb.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include "internal.h" #include "internal.h"
...@@ -2085,6 +2086,9 @@ static void khugepaged_do_scan(struct page **hpage) ...@@ -2085,6 +2086,9 @@ static void khugepaged_do_scan(struct page **hpage)
break; break;
#endif #endif
if (unlikely(kthread_should_stop() || freezing(current)))
break;
spin_lock(&khugepaged_mm_lock); spin_lock(&khugepaged_mm_lock);
if (!khugepaged_scan.mm_slot) if (!khugepaged_scan.mm_slot)
pass_through_head++; pass_through_head++;
...@@ -2147,6 +2151,9 @@ static void khugepaged_loop(void) ...@@ -2147,6 +2151,9 @@ static void khugepaged_loop(void)
if (hpage) if (hpage)
put_page(hpage); put_page(hpage);
#endif #endif
try_to_freeze();
if (unlikely(kthread_should_stop()))
break;
if (khugepaged_has_work()) { if (khugepaged_has_work()) {
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
if (!khugepaged_scan_sleep_millisecs) if (!khugepaged_scan_sleep_millisecs)
...@@ -2157,8 +2164,8 @@ static void khugepaged_loop(void) ...@@ -2157,8 +2164,8 @@ static void khugepaged_loop(void)
khugepaged_scan_sleep_millisecs)); khugepaged_scan_sleep_millisecs));
remove_wait_queue(&khugepaged_wait, &wait); remove_wait_queue(&khugepaged_wait, &wait);
} else if (khugepaged_enabled()) } else if (khugepaged_enabled())
wait_event_interruptible(khugepaged_wait, wait_event_freezable(khugepaged_wait,
khugepaged_wait_event()); khugepaged_wait_event());
} }
} }
...@@ -2166,6 +2173,7 @@ static int khugepaged(void *none) ...@@ -2166,6 +2173,7 @@ static int khugepaged(void *none)
{ {
struct mm_slot *mm_slot; struct mm_slot *mm_slot;
set_freezable();
set_user_nice(current, 19); set_user_nice(current, 19);
/* serialize with start_khugepaged() */ /* serialize with start_khugepaged() */
...@@ -2180,6 +2188,8 @@ static int khugepaged(void *none) ...@@ -2180,6 +2188,8 @@ static int khugepaged(void *none)
mutex_lock(&khugepaged_mutex); mutex_lock(&khugepaged_mutex);
if (!khugepaged_enabled()) if (!khugepaged_enabled())
break; break;
if (unlikely(kthread_should_stop()))
break;
} }
spin_lock(&khugepaged_mm_lock); spin_lock(&khugepaged_mm_lock);
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <linux/swap.h> #include <linux/swap.h>
#include <linux/ksm.h> #include <linux/ksm.h>
#include <linux/hash.h> #include <linux/hash.h>
#include <linux/freezer.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include "internal.h" #include "internal.h"
...@@ -1365,7 +1366,7 @@ static void ksm_do_scan(unsigned int scan_npages) ...@@ -1365,7 +1366,7 @@ static void ksm_do_scan(unsigned int scan_npages)
struct rmap_item *rmap_item; struct rmap_item *rmap_item;
struct page *uninitialized_var(page); struct page *uninitialized_var(page);
while (scan_npages--) { while (scan_npages-- && likely(!freezing(current))) {
cond_resched(); cond_resched();
rmap_item = scan_get_next_rmap_item(&page); rmap_item = scan_get_next_rmap_item(&page);
if (!rmap_item) if (!rmap_item)
...@@ -1383,6 +1384,7 @@ static int ksmd_should_run(void) ...@@ -1383,6 +1384,7 @@ static int ksmd_should_run(void)
static int ksm_scan_thread(void *nothing) static int ksm_scan_thread(void *nothing)
{ {
set_freezable();
set_user_nice(current, 5); set_user_nice(current, 5);
while (!kthread_should_stop()) { while (!kthread_should_stop()) {
...@@ -1391,11 +1393,13 @@ static int ksm_scan_thread(void *nothing) ...@@ -1391,11 +1393,13 @@ static int ksm_scan_thread(void *nothing)
ksm_do_scan(ksm_thread_pages_to_scan); ksm_do_scan(ksm_thread_pages_to_scan);
mutex_unlock(&ksm_thread_mutex); mutex_unlock(&ksm_thread_mutex);
try_to_freeze();
if (ksmd_should_run()) { if (ksmd_should_run()) {
schedule_timeout_interruptible( schedule_timeout_interruptible(
msecs_to_jiffies(ksm_thread_sleep_millisecs)); msecs_to_jiffies(ksm_thread_sleep_millisecs));
} else { } else {
wait_event_interruptible(ksm_thread_wait, wait_event_freezable(ksm_thread_wait,
ksmd_should_run() || kthread_should_stop()); ksmd_should_run() || kthread_should_stop());
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册