aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/swap.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/mm/swap.c b/mm/swap.c
index 95916142fc46..59f5fafa6e1f 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -667,6 +667,24 @@ static void lru_add_drain_per_cpu(struct work_struct *dummy)
667 667
668static DEFINE_PER_CPU(struct work_struct, lru_add_drain_work); 668static DEFINE_PER_CPU(struct work_struct, lru_add_drain_work);
669 669
670/*
671 * lru_add_drain_wq is used to do lru_add_drain_all() from a WQ_MEM_RECLAIM
672 * workqueue, aiding in getting memory freed.
673 */
674static struct workqueue_struct *lru_add_drain_wq;
675
676static int __init lru_init(void)
677{
678 lru_add_drain_wq = alloc_workqueue("lru-add-drain", WQ_MEM_RECLAIM, 0);
679
680 if (WARN(!lru_add_drain_wq,
681 "Failed to create workqueue lru_add_drain_wq"))
682 return -ENOMEM;
683
684 return 0;
685}
686early_initcall(lru_init);
687
670void lru_add_drain_all(void) 688void lru_add_drain_all(void)
671{ 689{
672 static DEFINE_MUTEX(lock); 690 static DEFINE_MUTEX(lock);
@@ -686,7 +704,7 @@ void lru_add_drain_all(void)
686 pagevec_count(&per_cpu(lru_deactivate_pvecs, cpu)) || 704 pagevec_count(&per_cpu(lru_deactivate_pvecs, cpu)) ||
687 need_activate_page_drain(cpu)) { 705 need_activate_page_drain(cpu)) {
688 INIT_WORK(work, lru_add_drain_per_cpu); 706 INIT_WORK(work, lru_add_drain_per_cpu);
689 schedule_work_on(cpu, work); 707 queue_work_on(cpu, lru_add_drain_wq, work);
690 cpumask_set_cpu(cpu, &has_work); 708 cpumask_set_cpu(cpu, &has_work);
691 } 709 }
692 } 710 }