|
@@ -2173,6 +2173,7 @@ static int kswapd(void *p)
|
|
|
order = 0;
|
|
|
for ( ; ; ) {
|
|
|
unsigned long new_order;
|
|
|
+ int ret;
|
|
|
|
|
|
prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
|
|
|
new_order = pgdat->kswapd_max_order;
|
|
@@ -2184,19 +2185,23 @@ static int kswapd(void *p)
|
|
|
*/
|
|
|
order = new_order;
|
|
|
} else {
|
|
|
- if (!freezing(current))
|
|
|
+ if (!freezing(current) && !kthread_should_stop())
|
|
|
schedule();
|
|
|
|
|
|
order = pgdat->kswapd_max_order;
|
|
|
}
|
|
|
finish_wait(&pgdat->kswapd_wait, &wait);
|
|
|
|
|
|
- if (!try_to_freeze()) {
|
|
|
- /* We can speed up thawing tasks if we don't call
|
|
|
- * balance_pgdat after returning from the refrigerator
|
|
|
- */
|
|
|
+ ret = try_to_freeze();
|
|
|
+ if (kthread_should_stop())
|
|
|
+ break;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We can speed up thawing tasks if we don't call balance_pgdat
|
|
|
+ * after returning from the refrigerator
|
|
|
+ */
|
|
|
+ if (!ret)
|
|
|
balance_pgdat(pgdat, order);
|
|
|
- }
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -2451,6 +2456,17 @@ int kswapd_run(int nid)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Called by memory hotplug when all memory in a node is offlined.
|
|
|
+ */
|
|
|
+void kswapd_stop(int nid)
|
|
|
+{
|
|
|
+ struct task_struct *kswapd = NODE_DATA(nid)->kswapd;
|
|
|
+
|
|
|
+ if (kswapd)
|
|
|
+ kthread_stop(kswapd);
|
|
|
+}
|
|
|
+
|
|
|
static int __init kswapd_init(void)
|
|
|
{
|
|
|
int nid;
|