aboutsummaryrefslogtreecommitdiff
path: root/mm/swap.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-06-10 08:00:47 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-06-10 08:00:47 -0700
commit9557c3cfdaa792c7db04b86f47b5dd1e6dc5ec4f (patch)
tree7e3ec6a4ae1417c417156978f3bb792842ef04f0 /mm/swap.c
parent147d9e7bcad3b8d5465f6eea6292731e7f35dee8 (diff)
parent18aba41cbfbcd138e9f6d8d446427d8b7691c194 (diff)
Merge branch 'akpm' (patches from Andrew)
Merge misc fixes from Andrew Morton: "7 fixes" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: mm/fadvise.c: do not discard partial pages with POSIX_FADV_DONTNEED mm: introduce dedicated WQ_MEM_RECLAIM workqueue to do lru_add_drain_all kernel/relay.c: fix potential memory leak mm: thp: broken page count after commit aa88b68c3b1d revert "mm: memcontrol: fix possible css ref leak on oom" kasan: change memory hot-add error messages to info messages mm/hugetlb: fix huge page reserve accounting for private mappings
Diffstat (limited to 'mm/swap.c')
-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)
static DEFINE_PER_CPU(struct work_struct, lru_add_drain_work);
+/*
+ * lru_add_drain_wq is used to do lru_add_drain_all() from a WQ_MEM_RECLAIM
+ * workqueue, aiding in getting memory freed.
+ */
+static struct workqueue_struct *lru_add_drain_wq;
+
+static int __init lru_init(void)
+{
+ lru_add_drain_wq = alloc_workqueue("lru-add-drain", WQ_MEM_RECLAIM, 0);
+
+ if (WARN(!lru_add_drain_wq,
+ "Failed to create workqueue lru_add_drain_wq"))
+ return -ENOMEM;
+
+ return 0;
+}
+early_initcall(lru_init);
+
void lru_add_drain_all(void)
{
static DEFINE_MUTEX(lock);
@@ -686,7 +704,7 @@ void lru_add_drain_all(void)
pagevec_count(&per_cpu(lru_deactivate_pvecs, cpu)) ||
need_activate_page_drain(cpu)) {
INIT_WORK(work, lru_add_drain_per_cpu);
- schedule_work_on(cpu, work);
+ queue_work_on(cpu, lru_add_drain_wq, work);
cpumask_set_cpu(cpu, &has_work);
}
}