All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <20140922185736.GB6630@cmpxchg.org>

diff --git a/a/1.txt b/N1/1.txt
index 54985a3..82ac1b9 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -451,648 +451,3 @@ Thanks for your thorough review, Vladimir!
 Here is the delta patch:
 
 ---
-From 3601538347af756b9bfe05142ab21b5ae44f8cdd Mon Sep 17 00:00:00 2001
-From: Johannes Weiner <hannes@cmpxchg.org>
-Date: Mon, 22 Sep 2014 13:54:24 -0400
-Subject: [patch] mm: memcontrol: lockless page counters fix
-
-- renamed limited to failcnt again [vladimir]
-- base page counter range on on LONG_MAX [vladimir]
-- page_counter_read() [vladimir]
-- page_counter_sub() [vladimir]
-- rework the nofail charging [vladimir]
-- page_counter_reset_watermark() [vladimir]
-- fixed hugepage limit page alignment [vladimir]
-- fixed page_counter_sub() return value [vladimir]
-- fixed kmem's idea of unlimited [vladimir]
-- fixed tcp memcontrol's idea of unlimited [vladimir]
-- fixed tcp memcontrol's usage reporting [vladimir]
-- serialize page_counter_limit() callsites [vladimir]
----
- include/linux/memcontrol.h |  24 ++++++---
- include/net/sock.h         |   8 +--
- mm/hugetlb_cgroup.c        |  22 ++++----
- mm/memcontrol.c            | 123 +++++++++++++++++++++++++--------------------
- net/ipv4/tcp_memcontrol.c  |  18 ++++---
- 5 files changed, 115 insertions(+), 80 deletions(-)
-
-diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
-index bf8fb1a05597..a8b939376a5d 100644
---- a/include/linux/memcontrol.h
-+++ b/include/linux/memcontrol.h
-@@ -62,13 +62,13 @@ struct page_counter {
- 
- 	/* legacy */
- 	unsigned long watermark;
--	unsigned long limited;
-+	unsigned long failcnt;
- };
- 
- #if BITS_PER_LONG == 32
--#define PAGE_COUNTER_MAX ULONG_MAX
-+#define PAGE_COUNTER_MAX LONG_MAX
- #else
--#define PAGE_COUNTER_MAX (ULONG_MAX / PAGE_SIZE)
-+#define PAGE_COUNTER_MAX (LONG_MAX / PAGE_SIZE)
- #endif
- 
- static inline void page_counter_init(struct page_counter *counter,
-@@ -79,13 +79,25 @@ static inline void page_counter_init(struct page_counter *counter,
- 	counter->parent = parent;
- }
- 
--int page_counter_cancel(struct page_counter *counter, unsigned long nr_pages);
--int page_counter_charge(struct page_counter *counter, unsigned long nr_pages,
--			struct page_counter **fail);
-+static inline unsigned long page_counter_read(struct page_counter *counter)
-+{
-+	return atomic_long_read(&counter->count);
-+}
-+
-+int page_counter_sub(struct page_counter *counter, unsigned long nr_pages);
-+void page_counter_charge(struct page_counter *counter, unsigned long nr_pages);
-+int page_counter_try_charge(struct page_counter *counter,
-+			    unsigned long nr_pages,
-+			    struct page_counter **fail);
- int page_counter_uncharge(struct page_counter *counter, unsigned long nr_pages);
- int page_counter_limit(struct page_counter *counter, unsigned long limit);
- int page_counter_memparse(const char *buf, unsigned long *nr_pages);
- 
-+static inline void page_counter_reset_watermark(struct page_counter *counter)
-+{
-+	counter->watermark = page_counter_read(counter);
-+}
-+
- int mem_cgroup_try_charge(struct page *page, struct mm_struct *mm,
- 			  gfp_t gfp_mask, struct mem_cgroup **memcgp);
- void mem_cgroup_commit_charge(struct page *page, struct mem_cgroup *memcg,
-diff --git a/include/net/sock.h b/include/net/sock.h
-index f41749982668..9aa435de3ef1 100644
---- a/include/net/sock.h
-+++ b/include/net/sock.h
-@@ -1217,9 +1217,9 @@ static inline void memcg_memory_allocated_add(struct cg_proto *prot,
- 					      unsigned long amt,
- 					      int *parent_status)
- {
--	page_counter_charge(&prot->memory_allocated, amt, NULL);
-+	page_counter_charge(&prot->memory_allocated, amt);
- 
--	if (atomic_long_read(&prot->memory_allocated.count) >
-+	if (page_counter_read(&prot->memory_allocated) >
- 	    prot->memory_allocated.limit)
- 		*parent_status = OVER_LIMIT;
- }
-@@ -1236,7 +1236,7 @@ sk_memory_allocated(const struct sock *sk)
- 	struct proto *prot = sk->sk_prot;
- 
- 	if (mem_cgroup_sockets_enabled && sk->sk_cgrp)
--		return atomic_long_read(&sk->sk_cgrp->memory_allocated.count);
-+		return page_counter_read(&sk->sk_cgrp->memory_allocated);
- 
- 	return atomic_long_read(prot->memory_allocated);
- }
-@@ -1250,7 +1250,7 @@ sk_memory_allocated_add(struct sock *sk, int amt, int *parent_status)
- 		memcg_memory_allocated_add(sk->sk_cgrp, amt, parent_status);
- 		/* update the root cgroup regardless */
- 		atomic_long_add_return(amt, prot->memory_allocated);
--		return atomic_long_read(&sk->sk_cgrp->memory_allocated.count);
-+		return page_counter_read(&sk->sk_cgrp->memory_allocated);
- 	}
- 
- 	return atomic_long_add_return(amt, prot->memory_allocated);
-diff --git a/mm/hugetlb_cgroup.c b/mm/hugetlb_cgroup.c
-index e619b6b62f1f..abd1e8dc7b46 100644
---- a/mm/hugetlb_cgroup.c
-+++ b/mm/hugetlb_cgroup.c
-@@ -61,7 +61,7 @@ static inline bool hugetlb_cgroup_have_usage(struct hugetlb_cgroup *h_cg)
- 	int idx;
- 
- 	for (idx = 0; idx < hugetlb_max_hstate; idx++) {
--		if (atomic_long_read(&h_cg->hugepage[idx].count))
-+		if (page_counter_read(&h_cg->hugepage[idx]))
- 			return true;
- 	}
- 	return false;
-@@ -127,11 +127,11 @@ static void hugetlb_cgroup_move_parent(int idx, struct hugetlb_cgroup *h_cg,
- 	if (!parent) {
- 		parent = root_h_cgroup;
- 		/* root has no limit */
--		page_counter_charge(&parent->hugepage[idx], nr_pages, NULL);
-+		page_counter_charge(&parent->hugepage[idx], nr_pages);
- 	}
- 	counter = &h_cg->hugepage[idx];
- 	/* Take the pages off the local counter */
--	page_counter_cancel(counter, nr_pages);
-+	page_counter_sub(counter, nr_pages);
- 
- 	set_hugetlb_cgroup(page, parent);
- out:
-@@ -186,7 +186,7 @@ again:
- 	}
- 	rcu_read_unlock();
- 
--	ret = page_counter_charge(&h_cg->hugepage[idx], nr_pages, &counter);
-+	ret = page_counter_try_charge(&h_cg->hugepage[idx], nr_pages, &counter);
- 	css_put(&h_cg->css);
- done:
- 	*ptr = h_cg;
-@@ -254,18 +254,20 @@ static u64 hugetlb_cgroup_read_u64(struct cgroup_subsys_state *css,
- 
- 	switch (MEMFILE_ATTR(cft->private)) {
- 	case RES_USAGE:
--		return (u64)atomic_long_read(&counter->count) * PAGE_SIZE;
-+		return (u64)page_counter_read(counter) * PAGE_SIZE;
- 	case RES_LIMIT:
- 		return (u64)counter->limit * PAGE_SIZE;
- 	case RES_MAX_USAGE:
- 		return (u64)counter->watermark * PAGE_SIZE;
- 	case RES_FAILCNT:
--		return counter->limited;
-+		return counter->failcnt;
- 	default:
- 		BUG();
- 	}
- }
- 
-+static DEFINE_MUTEX(hugetlb_limit_mutex);
-+
- static ssize_t hugetlb_cgroup_write(struct kernfs_open_file *of,
- 				    char *buf, size_t nbytes, loff_t off)
- {
-@@ -285,8 +287,10 @@ static ssize_t hugetlb_cgroup_write(struct kernfs_open_file *of,
- 
- 	switch (MEMFILE_ATTR(of_cft(of)->private)) {
- 	case RES_LIMIT:
--		nr_pages = ALIGN(nr_pages, huge_page_shift(&hstates[idx]));
-+		nr_pages = ALIGN(nr_pages, 1UL<<huge_page_order(&hstates[idx]));
-+		mutex_lock(&hugetlb_limit_mutex);
- 		ret = page_counter_limit(&h_cg->hugepage[idx], nr_pages);
-+		mutex_unlock(&hugetlb_limit_mutex);
- 		break;
- 	default:
- 		ret = -EINVAL;
-@@ -306,10 +310,10 @@ static ssize_t hugetlb_cgroup_reset(struct kernfs_open_file *of,
- 
- 	switch (MEMFILE_ATTR(of_cft(of)->private)) {
- 	case RES_MAX_USAGE:
--		counter->watermark = atomic_long_read(&counter->count);
-+		page_counter_reset_watermark(counter);
- 		break;
- 	case RES_FAILCNT:
--		counter->limited = 0;
-+		counter->failcnt = 0;
- 		break;
- 	default:
- 		ret = -EINVAL;
-diff --git a/mm/memcontrol.c b/mm/memcontrol.c
-index dfd3b15a57e8..9dec20b3c928 100644
---- a/mm/memcontrol.c
-+++ b/mm/memcontrol.c
-@@ -65,7 +65,7 @@
- 
- #include <trace/events/vmscan.h>
- 
--int page_counter_cancel(struct page_counter *counter, unsigned long nr_pages)
-+int page_counter_sub(struct page_counter *counter, unsigned long nr_pages)
- {
- 	long new;
- 
-@@ -74,28 +74,41 @@ int page_counter_cancel(struct page_counter *counter, unsigned long nr_pages)
- 	if (WARN_ON(unlikely(new < 0)))
- 		atomic_long_set(&counter->count, 0);
- 
--	return new > 1;
-+	return new > 0;
- }
- 
--int page_counter_charge(struct page_counter *counter, unsigned long nr_pages,
--			struct page_counter **fail)
-+void page_counter_charge(struct page_counter *counter, unsigned long nr_pages)
-+{
-+	struct page_counter *c;
-+
-+	for (c = counter; c; c = c->parent) {
-+		long new;
-+
-+		new = atomic_long_add_return(nr_pages, &c->count);
-+
-+		if (new > c->watermark)
-+			c->watermark = new;
-+	}
-+}
-+
-+int page_counter_try_charge(struct page_counter *counter,
-+			    unsigned long nr_pages,
-+			    struct page_counter **fail)
- {
- 	struct page_counter *c;
- 
- 	for (c = counter; c; c = c->parent) {
- 		for (;;) {
--			unsigned long count;
--			unsigned long new;
-+			long count;
-+			long new;
- 
- 			count = atomic_long_read(&c->count);
- 
- 			new = count + nr_pages;
- 			if (new > c->limit) {
--				c->limited++;
--				if (fail) {
--					*fail = c;
--					goto failed;
--				}
-+				c->failcnt++;
-+				*fail = c;
-+				goto failed;
- 			}
- 
- 			if (atomic_long_cmpxchg(&c->count, count, new) != count)
-@@ -111,7 +124,7 @@ int page_counter_charge(struct page_counter *counter, unsigned long nr_pages,
- 
- failed:
- 	for (c = counter; c != *fail; c = c->parent)
--		page_counter_cancel(c, nr_pages);
-+		page_counter_sub(c, nr_pages);
- 
- 	return -ENOMEM;
- }
-@@ -124,7 +137,7 @@ int page_counter_uncharge(struct page_counter *counter, unsigned long nr_pages)
- 	for (c = counter; c; c = c->parent) {
- 		int remainder;
- 
--		remainder = page_counter_cancel(c, nr_pages);
-+		remainder = page_counter_sub(c, nr_pages);
- 		if (c == counter && !remainder)
- 			ret = 0;
- 	}
-@@ -135,8 +148,8 @@ int page_counter_uncharge(struct page_counter *counter, unsigned long nr_pages)
- int page_counter_limit(struct page_counter *counter, unsigned long limit)
- {
- 	for (;;) {
--		unsigned long count;
- 		unsigned long old;
-+		long count;
- 
- 		count = atomic_long_read(&counter->count);
- 
-@@ -751,7 +764,7 @@ static void disarm_kmem_keys(struct mem_cgroup *memcg)
- 	 * This check can't live in kmem destruction function,
- 	 * since the charges will outlive the cgroup
- 	 */
--	WARN_ON(atomic_long_read(&memcg->kmem.count));
-+	WARN_ON(page_counter_read(&memcg->kmem));
- }
- #else
- static void disarm_kmem_keys(struct mem_cgroup *memcg)
-@@ -858,7 +871,7 @@ static void mem_cgroup_remove_exceeded(struct mem_cgroup_per_zone *mz,
- 
- static unsigned long soft_limit_excess(struct mem_cgroup *memcg)
- {
--	unsigned long nr_pages = atomic_long_read(&memcg->memory.count);
-+	unsigned long nr_pages = page_counter_read(&memcg->memory);
- 	unsigned long soft_limit = ACCESS_ONCE(memcg->soft_limit);
- 	unsigned long excess = 0;
- 
-@@ -1609,13 +1622,13 @@ static unsigned long mem_cgroup_margin(struct mem_cgroup *memcg)
- 	unsigned long count;
- 	unsigned long limit;
- 
--	count = atomic_long_read(&memcg->memory.count);
-+	count = page_counter_read(&memcg->memory);
- 	limit = ACCESS_ONCE(memcg->memory.limit);
- 	if (count < limit)
- 		margin = limit - count;
- 
- 	if (do_swap_account) {
--		count = atomic_long_read(&memcg->memsw.count);
-+		count = page_counter_read(&memcg->memsw);
- 		limit = ACCESS_ONCE(memcg->memsw.limit);
- 		if (count < limit)
- 			margin = min(margin, limit - count);
-@@ -1763,14 +1776,14 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)
- 	rcu_read_unlock();
- 
- 	pr_info("memory: usage %llukB, limit %llukB, failcnt %lu\n",
--		K((u64)atomic_long_read(&memcg->memory.count)),
--		K((u64)memcg->memory.limit), memcg->memory.limited);
-+		K((u64)page_counter_read(&memcg->memory)),
-+		K((u64)memcg->memory.limit), memcg->memory.failcnt);
- 	pr_info("memory+swap: usage %llukB, limit %llukB, failcnt %lu\n",
--		K((u64)atomic_long_read(&memcg->memsw.count)),
--		K((u64)memcg->memsw.limit), memcg->memsw.limited);
-+		K((u64)page_counter_read(&memcg->memsw)),
-+		K((u64)memcg->memsw.limit), memcg->memsw.failcnt);
- 	pr_info("kmem: usage %llukB, limit %llukB, failcnt %lu\n",
--		K((u64)atomic_long_read(&memcg->kmem.count)),
--		K((u64)memcg->kmem.limit), memcg->kmem.limited);
-+		K((u64)page_counter_read(&memcg->kmem)),
-+		K((u64)memcg->kmem.limit), memcg->kmem.failcnt);
- 
- 	for_each_mem_cgroup_tree(iter, memcg) {
- 		pr_info("Memory cgroup stats for ");
-@@ -2604,10 +2617,10 @@ retry:
- 	if (consume_stock(memcg, nr_pages))
- 		goto done;
- 
--	if (!page_counter_charge(&memcg->memory, batch, &counter)) {
-+	if (!page_counter_try_charge(&memcg->memory, batch, &counter)) {
- 		if (!do_swap_account)
- 			goto done_restock;
--		if (!page_counter_charge(&memcg->memsw, batch, &counter))
-+		if (!page_counter_try_charge(&memcg->memsw, batch, &counter))
- 			goto done_restock;
- 		page_counter_uncharge(&memcg->memory, batch);
- 		mem_over_limit = mem_cgroup_from_counter(counter, memsw);
-@@ -2877,7 +2890,7 @@ static int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp,
- 	struct page_counter *counter;
- 	int ret = 0;
- 
--	ret = page_counter_charge(&memcg->kmem, nr_pages, &counter);
-+	ret = page_counter_try_charge(&memcg->kmem, nr_pages, &counter);
- 	if (ret < 0)
- 		return ret;
- 
-@@ -2898,9 +2911,9 @@ static int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp,
- 		 * when the allocation triggers should have been already
- 		 * directed to the root cgroup in memcontrol.h
- 		 */
--		page_counter_charge(&memcg->memory, nr_pages, NULL);
-+		page_counter_charge(&memcg->memory, nr_pages);
- 		if (do_swap_account)
--			page_counter_charge(&memcg->memsw, nr_pages, NULL);
-+			page_counter_charge(&memcg->memsw, nr_pages);
- 		ret = 0;
- 	} else if (ret)
- 		page_counter_uncharge(&memcg->kmem, nr_pages);
-@@ -3558,9 +3571,9 @@ static int mem_cgroup_move_parent(struct page *page,
- 				pc, child, parent);
- 	if (!ret) {
- 		/* Take charge off the local counters */
--		page_counter_cancel(&child->memory, nr_pages);
-+		page_counter_sub(&child->memory, nr_pages);
- 		if (do_swap_account)
--			page_counter_cancel(&child->memsw, nr_pages);
-+			page_counter_sub(&child->memsw, nr_pages);
- 	}
- 
- 	if (nr_pages > 1)
-@@ -3665,7 +3678,7 @@ void mem_cgroup_print_bad_page(struct page *page)
- }
- #endif
- 
--static DEFINE_MUTEX(set_limit_mutex);
-+static DEFINE_MUTEX(memcg_limit_mutex);
- 
- static int mem_cgroup_resize_limit(struct mem_cgroup *memcg,
- 				   unsigned long limit)
-@@ -3684,7 +3697,7 @@ static int mem_cgroup_resize_limit(struct mem_cgroup *memcg,
- 	retry_count = MEM_CGROUP_RECLAIM_RETRIES *
- 		      mem_cgroup_count_children(memcg);
- 
--	oldusage = atomic_long_read(&memcg->memory.count);
-+	oldusage = page_counter_read(&memcg->memory);
- 
- 	do {
- 		if (signal_pending(current)) {
-@@ -3692,23 +3705,23 @@ static int mem_cgroup_resize_limit(struct mem_cgroup *memcg,
- 			break;
- 		}
- 
--		mutex_lock(&set_limit_mutex);
-+		mutex_lock(&memcg_limit_mutex);
- 		if (limit > memcg->memsw.limit) {
--			mutex_unlock(&set_limit_mutex);
-+			mutex_unlock(&memcg_limit_mutex);
- 			ret = -EINVAL;
- 			break;
- 		}
- 		if (limit > memcg->memory.limit)
- 			enlarge = true;
- 		ret = page_counter_limit(&memcg->memory, limit);
--		mutex_unlock(&set_limit_mutex);
-+		mutex_unlock(&memcg_limit_mutex);
- 
- 		if (!ret)
- 			break;
- 
- 		try_to_free_mem_cgroup_pages(memcg, 1, GFP_KERNEL, true);
- 
--		curusage = atomic_long_read(&memcg->memory.count);
-+		curusage = page_counter_read(&memcg->memory);
- 		/* Usage is reduced ? */
- 		if (curusage >= oldusage)
- 			retry_count--;
-@@ -3735,7 +3748,7 @@ static int mem_cgroup_resize_memsw_limit(struct mem_cgroup *memcg,
- 	retry_count = MEM_CGROUP_RECLAIM_RETRIES *
- 		      mem_cgroup_count_children(memcg);
- 
--	oldusage = atomic_long_read(&memcg->memsw.count);
-+	oldusage = page_counter_read(&memcg->memsw);
- 
- 	do {
- 		if (signal_pending(current)) {
-@@ -3743,23 +3756,23 @@ static int mem_cgroup_resize_memsw_limit(struct mem_cgroup *memcg,
- 			break;
- 		}
- 
--		mutex_lock(&set_limit_mutex);
-+		mutex_lock(&memcg_limit_mutex);
- 		if (limit < memcg->memory.limit) {
--			mutex_unlock(&set_limit_mutex);
-+			mutex_unlock(&memcg_limit_mutex);
- 			ret = -EINVAL;
- 			break;
- 		}
- 		if (limit > memcg->memsw.limit)
- 			enlarge = true;
- 		ret = page_counter_limit(&memcg->memsw, limit);
--		mutex_unlock(&set_limit_mutex);
-+		mutex_unlock(&memcg_limit_mutex);
- 
- 		if (!ret)
- 			break;
- 
- 		try_to_free_mem_cgroup_pages(memcg, 1, GFP_KERNEL, false);
- 
--		curusage = atomic_long_read(&memcg->memsw.count);
-+		curusage = page_counter_read(&memcg->memsw);
- 		/* Usage is reduced ? */
- 		if (curusage >= oldusage)
- 			retry_count--;
-@@ -3960,8 +3973,8 @@ static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg)
- 		 * right after the check. RES_USAGE should be safe as we always
- 		 * charge before adding to the LRU.
- 		 */
--	} while (atomic_long_read(&memcg->memory.count) -
--		 atomic_long_read(&memcg->kmem.count) > 0);
-+	} while (page_counter_read(&memcg->memory) -
-+		 page_counter_read(&memcg->kmem) > 0);
- }
- 
- /*
-@@ -4001,7 +4014,7 @@ static int mem_cgroup_force_empty(struct mem_cgroup *memcg)
- 	/* we call try-to-free pages for make this cgroup empty */
- 	lru_add_drain_all();
- 	/* try to free all pages in this cgroup */
--	while (nr_retries && atomic_long_read(&memcg->memory.count)) {
-+	while (nr_retries && page_counter_read(&memcg->memory)) {
- 		int progress;
- 
- 		if (signal_pending(current))
-@@ -4098,9 +4111,9 @@ static inline u64 mem_cgroup_usage(struct mem_cgroup *memcg, bool swap)
- 			val += tree_stat(memcg, MEM_CGROUP_STAT_SWAP);
- 	} else {
- 		if (!swap)
--			val = atomic_long_read(&memcg->memory.count);
-+			val = page_counter_read(&memcg->memory);
- 		else
--			val = atomic_long_read(&memcg->memsw.count);
-+			val = page_counter_read(&memcg->memsw);
- 	}
- 	return val << PAGE_SHIFT;
- }
-@@ -4139,13 +4152,13 @@ static u64 mem_cgroup_read_u64(struct cgroup_subsys_state *css,
- 			return mem_cgroup_usage(memcg, false);
- 		if (counter == &memcg->memsw)
- 			return mem_cgroup_usage(memcg, true);
--		return (u64)atomic_long_read(&counter->count) * PAGE_SIZE;
-+		return (u64)page_counter_read(counter) * PAGE_SIZE;
- 	case RES_LIMIT:
- 		return (u64)counter->limit * PAGE_SIZE;
- 	case RES_MAX_USAGE:
- 		return (u64)counter->watermark * PAGE_SIZE;
- 	case RES_FAILCNT:
--		return counter->limited;
-+		return counter->failcnt;
- 	case RES_SOFT_LIMIT:
- 		return (u64)memcg->soft_limit * PAGE_SIZE;
- 	default:
-@@ -4234,10 +4247,12 @@ static int memcg_update_kmem_limit(struct mem_cgroup *memcg,
- {
- 	int ret;
- 
-+	mutex_lock(&memcg_limit_mutex);
- 	if (!memcg_kmem_is_active(memcg))
- 		ret = memcg_activate_kmem(memcg, limit);
- 	else
- 		ret = page_counter_limit(&memcg->kmem, limit);
-+	mutex_unlock(&memcg_limit_mutex);
- 	return ret;
- }
- 
-@@ -4255,7 +4270,7 @@ static int memcg_propagate_kmem(struct mem_cgroup *memcg)
- 	 * after this point, because it has at least one child already.
- 	 */
- 	if (memcg_kmem_is_active(parent))
--		ret = __memcg_activate_kmem(memcg, ULONG_MAX);
-+		ret = __memcg_activate_kmem(memcg, PAGE_COUNTER_MAX);
- 	mutex_unlock(&activate_kmem_mutex);
- 	return ret;
- }
-@@ -4331,10 +4346,10 @@ static ssize_t mem_cgroup_reset(struct kernfs_open_file *of, char *buf,
- 
- 	switch (MEMFILE_ATTR(of_cft(of)->private)) {
- 	case RES_MAX_USAGE:
--		counter->watermark = atomic_long_read(&counter->count);
-+		page_counter_reset_watermark(counter);
- 		break;
- 	case RES_FAILCNT:
--		counter->limited = 0;
-+		counter->failcnt = 0;
- 		break;
- 	default:
- 		BUG();
-@@ -4934,7 +4949,7 @@ static void kmem_cgroup_css_offline(struct mem_cgroup *memcg)
- 
- 	memcg_kmem_mark_dead(memcg);
- 
--	if (atomic_long_read(&memcg->kmem.count))
-+	if (page_counter_read(&memcg->kmem))
- 		return;
- 
- 	if (memcg_kmem_test_and_clear_dead(memcg))
-@@ -5603,7 +5618,7 @@ static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
- 	 * call_rcu()
- 	 *   offline_css()
- 	 *     reparent_charges()
--	 *                           page_counter_charge()
-+	 *                           page_counter_try_charge()
- 	 *                           css_put()
- 	 *                             css_free()
- 	 *                           pc->mem_cgroup = dead memcg
-diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c
-index 9a448bdb19e9..272327134a1b 100644
---- a/net/ipv4/tcp_memcontrol.c
-+++ b/net/ipv4/tcp_memcontrol.c
-@@ -68,7 +68,7 @@ static int tcp_update_limit(struct mem_cgroup *memcg, unsigned long nr_pages)
- 		cg_proto->sysctl_mem[i] = min_t(long, nr_pages,
- 						sysctl_tcp_mem[i]);
- 
--	if (nr_pages == ULONG_MAX / PAGE_SIZE)
-+	if (nr_pages == PAGE_COUNTER_MAX)
- 		clear_bit(MEMCG_SOCK_ACTIVE, &cg_proto->flags);
- 	else {
- 		/*
-@@ -106,6 +106,8 @@ enum {
- 	RES_FAILCNT,
- };
- 
-+static DEFINE_MUTEX(tcp_limit_mutex);
-+
- static ssize_t tcp_cgroup_write(struct kernfs_open_file *of,
- 				char *buf, size_t nbytes, loff_t off)
- {
-@@ -121,7 +123,9 @@ static ssize_t tcp_cgroup_write(struct kernfs_open_file *of,
- 		ret = page_counter_memparse(buf, &nr_pages);
- 		if (ret)
- 			break;
-+		mutex_lock(&tcp_limit_mutex);
- 		ret = tcp_update_limit(memcg, nr_pages);
-+		mutex_unlock(&tcp_limit_mutex);
- 		break;
- 	default:
- 		ret = -EINVAL;
-@@ -145,14 +149,15 @@ static u64 tcp_cgroup_read(struct cgroup_subsys_state *css, struct cftype *cft)
- 		break;
- 	case RES_USAGE:
- 		if (!cg_proto)
--			return atomic_long_read(&tcp_memory_allocated);
--		val = atomic_long_read(&cg_proto->memory_allocated.count);
-+			val = atomic_long_read(&tcp_memory_allocated);
-+		else
-+			val = page_counter_read(&cg_proto->memory_allocated);
- 		val *= PAGE_SIZE;
- 		break;
- 	case RES_FAILCNT:
- 		if (!cg_proto)
- 			return 0;
--		val = cg_proto->memory_allocated.limited;
-+		val = cg_proto->memory_allocated.failcnt;
- 		break;
- 	case RES_MAX_USAGE:
- 		if (!cg_proto)
-@@ -179,11 +184,10 @@ static ssize_t tcp_cgroup_reset(struct kernfs_open_file *of,
- 
- 	switch (of_cft(of)->private) {
- 	case RES_MAX_USAGE:
--		cg_proto->memory_allocated.watermark =
--			atomic_long_read(&cg_proto->memory_allocated.count);
-+		page_counter_reset_watermark(&cg_proto->memory_allocated);
- 		break;
- 	case RES_FAILCNT:
--		cg_proto->memory_allocated.limited = 0;
-+		cg_proto->memory_allocated.failcnt = 0;
- 		break;
- 	}
- 
--- 
-2.1.0
-
-
---
-To unsubscribe, send a message with 'unsubscribe linux-mm' in
-the body to majordomo@kvack.org.  For more info on Linux MM,
-see: http://www.linux-mm.org/ .
-Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
diff --git a/a/content_digest b/N1/content_digest
index dd677e0..3528829 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -464,651 +464,6 @@
  "\n"
  "Here is the delta patch:\n"
  "\n"
- "---\n"
- "From 3601538347af756b9bfe05142ab21b5ae44f8cdd Mon Sep 17 00:00:00 2001\n"
- "From: Johannes Weiner <hannes@cmpxchg.org>\n"
- "Date: Mon, 22 Sep 2014 13:54:24 -0400\n"
- "Subject: [patch] mm: memcontrol: lockless page counters fix\n"
- "\n"
- "- renamed limited to failcnt again [vladimir]\n"
- "- base page counter range on on LONG_MAX [vladimir]\n"
- "- page_counter_read() [vladimir]\n"
- "- page_counter_sub() [vladimir]\n"
- "- rework the nofail charging [vladimir]\n"
- "- page_counter_reset_watermark() [vladimir]\n"
- "- fixed hugepage limit page alignment [vladimir]\n"
- "- fixed page_counter_sub() return value [vladimir]\n"
- "- fixed kmem's idea of unlimited [vladimir]\n"
- "- fixed tcp memcontrol's idea of unlimited [vladimir]\n"
- "- fixed tcp memcontrol's usage reporting [vladimir]\n"
- "- serialize page_counter_limit() callsites [vladimir]\n"
- "---\n"
- " include/linux/memcontrol.h |  24 ++++++---\n"
- " include/net/sock.h         |   8 +--\n"
- " mm/hugetlb_cgroup.c        |  22 ++++----\n"
- " mm/memcontrol.c            | 123 +++++++++++++++++++++++++--------------------\n"
- " net/ipv4/tcp_memcontrol.c  |  18 ++++---\n"
- " 5 files changed, 115 insertions(+), 80 deletions(-)\n"
- "\n"
- "diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h\n"
- "index bf8fb1a05597..a8b939376a5d 100644\n"
- "--- a/include/linux/memcontrol.h\n"
- "+++ b/include/linux/memcontrol.h\n"
- "@@ -62,13 +62,13 @@ struct page_counter {\n"
- " \n"
- " \t/* legacy */\n"
- " \tunsigned long watermark;\n"
- "-\tunsigned long limited;\n"
- "+\tunsigned long failcnt;\n"
- " };\n"
- " \n"
- " #if BITS_PER_LONG == 32\n"
- "-#define PAGE_COUNTER_MAX ULONG_MAX\n"
- "+#define PAGE_COUNTER_MAX LONG_MAX\n"
- " #else\n"
- "-#define PAGE_COUNTER_MAX (ULONG_MAX / PAGE_SIZE)\n"
- "+#define PAGE_COUNTER_MAX (LONG_MAX / PAGE_SIZE)\n"
- " #endif\n"
- " \n"
- " static inline void page_counter_init(struct page_counter *counter,\n"
- "@@ -79,13 +79,25 @@ static inline void page_counter_init(struct page_counter *counter,\n"
- " \tcounter->parent = parent;\n"
- " }\n"
- " \n"
- "-int page_counter_cancel(struct page_counter *counter, unsigned long nr_pages);\n"
- "-int page_counter_charge(struct page_counter *counter, unsigned long nr_pages,\n"
- "-\t\t\tstruct page_counter **fail);\n"
- "+static inline unsigned long page_counter_read(struct page_counter *counter)\n"
- "+{\n"
- "+\treturn atomic_long_read(&counter->count);\n"
- "+}\n"
- "+\n"
- "+int page_counter_sub(struct page_counter *counter, unsigned long nr_pages);\n"
- "+void page_counter_charge(struct page_counter *counter, unsigned long nr_pages);\n"
- "+int page_counter_try_charge(struct page_counter *counter,\n"
- "+\t\t\t    unsigned long nr_pages,\n"
- "+\t\t\t    struct page_counter **fail);\n"
- " int page_counter_uncharge(struct page_counter *counter, unsigned long nr_pages);\n"
- " int page_counter_limit(struct page_counter *counter, unsigned long limit);\n"
- " int page_counter_memparse(const char *buf, unsigned long *nr_pages);\n"
- " \n"
- "+static inline void page_counter_reset_watermark(struct page_counter *counter)\n"
- "+{\n"
- "+\tcounter->watermark = page_counter_read(counter);\n"
- "+}\n"
- "+\n"
- " int mem_cgroup_try_charge(struct page *page, struct mm_struct *mm,\n"
- " \t\t\t  gfp_t gfp_mask, struct mem_cgroup **memcgp);\n"
- " void mem_cgroup_commit_charge(struct page *page, struct mem_cgroup *memcg,\n"
- "diff --git a/include/net/sock.h b/include/net/sock.h\n"
- "index f41749982668..9aa435de3ef1 100644\n"
- "--- a/include/net/sock.h\n"
- "+++ b/include/net/sock.h\n"
- "@@ -1217,9 +1217,9 @@ static inline void memcg_memory_allocated_add(struct cg_proto *prot,\n"
- " \t\t\t\t\t      unsigned long amt,\n"
- " \t\t\t\t\t      int *parent_status)\n"
- " {\n"
- "-\tpage_counter_charge(&prot->memory_allocated, amt, NULL);\n"
- "+\tpage_counter_charge(&prot->memory_allocated, amt);\n"
- " \n"
- "-\tif (atomic_long_read(&prot->memory_allocated.count) >\n"
- "+\tif (page_counter_read(&prot->memory_allocated) >\n"
- " \t    prot->memory_allocated.limit)\n"
- " \t\t*parent_status = OVER_LIMIT;\n"
- " }\n"
- "@@ -1236,7 +1236,7 @@ sk_memory_allocated(const struct sock *sk)\n"
- " \tstruct proto *prot = sk->sk_prot;\n"
- " \n"
- " \tif (mem_cgroup_sockets_enabled && sk->sk_cgrp)\n"
- "-\t\treturn atomic_long_read(&sk->sk_cgrp->memory_allocated.count);\n"
- "+\t\treturn page_counter_read(&sk->sk_cgrp->memory_allocated);\n"
- " \n"
- " \treturn atomic_long_read(prot->memory_allocated);\n"
- " }\n"
- "@@ -1250,7 +1250,7 @@ sk_memory_allocated_add(struct sock *sk, int amt, int *parent_status)\n"
- " \t\tmemcg_memory_allocated_add(sk->sk_cgrp, amt, parent_status);\n"
- " \t\t/* update the root cgroup regardless */\n"
- " \t\tatomic_long_add_return(amt, prot->memory_allocated);\n"
- "-\t\treturn atomic_long_read(&sk->sk_cgrp->memory_allocated.count);\n"
- "+\t\treturn page_counter_read(&sk->sk_cgrp->memory_allocated);\n"
- " \t}\n"
- " \n"
- " \treturn atomic_long_add_return(amt, prot->memory_allocated);\n"
- "diff --git a/mm/hugetlb_cgroup.c b/mm/hugetlb_cgroup.c\n"
- "index e619b6b62f1f..abd1e8dc7b46 100644\n"
- "--- a/mm/hugetlb_cgroup.c\n"
- "+++ b/mm/hugetlb_cgroup.c\n"
- "@@ -61,7 +61,7 @@ static inline bool hugetlb_cgroup_have_usage(struct hugetlb_cgroup *h_cg)\n"
- " \tint idx;\n"
- " \n"
- " \tfor (idx = 0; idx < hugetlb_max_hstate; idx++) {\n"
- "-\t\tif (atomic_long_read(&h_cg->hugepage[idx].count))\n"
- "+\t\tif (page_counter_read(&h_cg->hugepage[idx]))\n"
- " \t\t\treturn true;\n"
- " \t}\n"
- " \treturn false;\n"
- "@@ -127,11 +127,11 @@ static void hugetlb_cgroup_move_parent(int idx, struct hugetlb_cgroup *h_cg,\n"
- " \tif (!parent) {\n"
- " \t\tparent = root_h_cgroup;\n"
- " \t\t/* root has no limit */\n"
- "-\t\tpage_counter_charge(&parent->hugepage[idx], nr_pages, NULL);\n"
- "+\t\tpage_counter_charge(&parent->hugepage[idx], nr_pages);\n"
- " \t}\n"
- " \tcounter = &h_cg->hugepage[idx];\n"
- " \t/* Take the pages off the local counter */\n"
- "-\tpage_counter_cancel(counter, nr_pages);\n"
- "+\tpage_counter_sub(counter, nr_pages);\n"
- " \n"
- " \tset_hugetlb_cgroup(page, parent);\n"
- " out:\n"
- "@@ -186,7 +186,7 @@ again:\n"
- " \t}\n"
- " \trcu_read_unlock();\n"
- " \n"
- "-\tret = page_counter_charge(&h_cg->hugepage[idx], nr_pages, &counter);\n"
- "+\tret = page_counter_try_charge(&h_cg->hugepage[idx], nr_pages, &counter);\n"
- " \tcss_put(&h_cg->css);\n"
- " done:\n"
- " \t*ptr = h_cg;\n"
- "@@ -254,18 +254,20 @@ static u64 hugetlb_cgroup_read_u64(struct cgroup_subsys_state *css,\n"
- " \n"
- " \tswitch (MEMFILE_ATTR(cft->private)) {\n"
- " \tcase RES_USAGE:\n"
- "-\t\treturn (u64)atomic_long_read(&counter->count) * PAGE_SIZE;\n"
- "+\t\treturn (u64)page_counter_read(counter) * PAGE_SIZE;\n"
- " \tcase RES_LIMIT:\n"
- " \t\treturn (u64)counter->limit * PAGE_SIZE;\n"
- " \tcase RES_MAX_USAGE:\n"
- " \t\treturn (u64)counter->watermark * PAGE_SIZE;\n"
- " \tcase RES_FAILCNT:\n"
- "-\t\treturn counter->limited;\n"
- "+\t\treturn counter->failcnt;\n"
- " \tdefault:\n"
- " \t\tBUG();\n"
- " \t}\n"
- " }\n"
- " \n"
- "+static DEFINE_MUTEX(hugetlb_limit_mutex);\n"
- "+\n"
- " static ssize_t hugetlb_cgroup_write(struct kernfs_open_file *of,\n"
- " \t\t\t\t    char *buf, size_t nbytes, loff_t off)\n"
- " {\n"
- "@@ -285,8 +287,10 @@ static ssize_t hugetlb_cgroup_write(struct kernfs_open_file *of,\n"
- " \n"
- " \tswitch (MEMFILE_ATTR(of_cft(of)->private)) {\n"
- " \tcase RES_LIMIT:\n"
- "-\t\tnr_pages = ALIGN(nr_pages, huge_page_shift(&hstates[idx]));\n"
- "+\t\tnr_pages = ALIGN(nr_pages, 1UL<<huge_page_order(&hstates[idx]));\n"
- "+\t\tmutex_lock(&hugetlb_limit_mutex);\n"
- " \t\tret = page_counter_limit(&h_cg->hugepage[idx], nr_pages);\n"
- "+\t\tmutex_unlock(&hugetlb_limit_mutex);\n"
- " \t\tbreak;\n"
- " \tdefault:\n"
- " \t\tret = -EINVAL;\n"
- "@@ -306,10 +310,10 @@ static ssize_t hugetlb_cgroup_reset(struct kernfs_open_file *of,\n"
- " \n"
- " \tswitch (MEMFILE_ATTR(of_cft(of)->private)) {\n"
- " \tcase RES_MAX_USAGE:\n"
- "-\t\tcounter->watermark = atomic_long_read(&counter->count);\n"
- "+\t\tpage_counter_reset_watermark(counter);\n"
- " \t\tbreak;\n"
- " \tcase RES_FAILCNT:\n"
- "-\t\tcounter->limited = 0;\n"
- "+\t\tcounter->failcnt = 0;\n"
- " \t\tbreak;\n"
- " \tdefault:\n"
- " \t\tret = -EINVAL;\n"
- "diff --git a/mm/memcontrol.c b/mm/memcontrol.c\n"
- "index dfd3b15a57e8..9dec20b3c928 100644\n"
- "--- a/mm/memcontrol.c\n"
- "+++ b/mm/memcontrol.c\n"
- "@@ -65,7 +65,7 @@\n"
- " \n"
- " #include <trace/events/vmscan.h>\n"
- " \n"
- "-int page_counter_cancel(struct page_counter *counter, unsigned long nr_pages)\n"
- "+int page_counter_sub(struct page_counter *counter, unsigned long nr_pages)\n"
- " {\n"
- " \tlong new;\n"
- " \n"
- "@@ -74,28 +74,41 @@ int page_counter_cancel(struct page_counter *counter, unsigned long nr_pages)\n"
- " \tif (WARN_ON(unlikely(new < 0)))\n"
- " \t\tatomic_long_set(&counter->count, 0);\n"
- " \n"
- "-\treturn new > 1;\n"
- "+\treturn new > 0;\n"
- " }\n"
- " \n"
- "-int page_counter_charge(struct page_counter *counter, unsigned long nr_pages,\n"
- "-\t\t\tstruct page_counter **fail)\n"
- "+void page_counter_charge(struct page_counter *counter, unsigned long nr_pages)\n"
- "+{\n"
- "+\tstruct page_counter *c;\n"
- "+\n"
- "+\tfor (c = counter; c; c = c->parent) {\n"
- "+\t\tlong new;\n"
- "+\n"
- "+\t\tnew = atomic_long_add_return(nr_pages, &c->count);\n"
- "+\n"
- "+\t\tif (new > c->watermark)\n"
- "+\t\t\tc->watermark = new;\n"
- "+\t}\n"
- "+}\n"
- "+\n"
- "+int page_counter_try_charge(struct page_counter *counter,\n"
- "+\t\t\t    unsigned long nr_pages,\n"
- "+\t\t\t    struct page_counter **fail)\n"
- " {\n"
- " \tstruct page_counter *c;\n"
- " \n"
- " \tfor (c = counter; c; c = c->parent) {\n"
- " \t\tfor (;;) {\n"
- "-\t\t\tunsigned long count;\n"
- "-\t\t\tunsigned long new;\n"
- "+\t\t\tlong count;\n"
- "+\t\t\tlong new;\n"
- " \n"
- " \t\t\tcount = atomic_long_read(&c->count);\n"
- " \n"
- " \t\t\tnew = count + nr_pages;\n"
- " \t\t\tif (new > c->limit) {\n"
- "-\t\t\t\tc->limited++;\n"
- "-\t\t\t\tif (fail) {\n"
- "-\t\t\t\t\t*fail = c;\n"
- "-\t\t\t\t\tgoto failed;\n"
- "-\t\t\t\t}\n"
- "+\t\t\t\tc->failcnt++;\n"
- "+\t\t\t\t*fail = c;\n"
- "+\t\t\t\tgoto failed;\n"
- " \t\t\t}\n"
- " \n"
- " \t\t\tif (atomic_long_cmpxchg(&c->count, count, new) != count)\n"
- "@@ -111,7 +124,7 @@ int page_counter_charge(struct page_counter *counter, unsigned long nr_pages,\n"
- " \n"
- " failed:\n"
- " \tfor (c = counter; c != *fail; c = c->parent)\n"
- "-\t\tpage_counter_cancel(c, nr_pages);\n"
- "+\t\tpage_counter_sub(c, nr_pages);\n"
- " \n"
- " \treturn -ENOMEM;\n"
- " }\n"
- "@@ -124,7 +137,7 @@ int page_counter_uncharge(struct page_counter *counter, unsigned long nr_pages)\n"
- " \tfor (c = counter; c; c = c->parent) {\n"
- " \t\tint remainder;\n"
- " \n"
- "-\t\tremainder = page_counter_cancel(c, nr_pages);\n"
- "+\t\tremainder = page_counter_sub(c, nr_pages);\n"
- " \t\tif (c == counter && !remainder)\n"
- " \t\t\tret = 0;\n"
- " \t}\n"
- "@@ -135,8 +148,8 @@ int page_counter_uncharge(struct page_counter *counter, unsigned long nr_pages)\n"
- " int page_counter_limit(struct page_counter *counter, unsigned long limit)\n"
- " {\n"
- " \tfor (;;) {\n"
- "-\t\tunsigned long count;\n"
- " \t\tunsigned long old;\n"
- "+\t\tlong count;\n"
- " \n"
- " \t\tcount = atomic_long_read(&counter->count);\n"
- " \n"
- "@@ -751,7 +764,7 @@ static void disarm_kmem_keys(struct mem_cgroup *memcg)\n"
- " \t * This check can't live in kmem destruction function,\n"
- " \t * since the charges will outlive the cgroup\n"
- " \t */\n"
- "-\tWARN_ON(atomic_long_read(&memcg->kmem.count));\n"
- "+\tWARN_ON(page_counter_read(&memcg->kmem));\n"
- " }\n"
- " #else\n"
- " static void disarm_kmem_keys(struct mem_cgroup *memcg)\n"
- "@@ -858,7 +871,7 @@ static void mem_cgroup_remove_exceeded(struct mem_cgroup_per_zone *mz,\n"
- " \n"
- " static unsigned long soft_limit_excess(struct mem_cgroup *memcg)\n"
- " {\n"
- "-\tunsigned long nr_pages = atomic_long_read(&memcg->memory.count);\n"
- "+\tunsigned long nr_pages = page_counter_read(&memcg->memory);\n"
- " \tunsigned long soft_limit = ACCESS_ONCE(memcg->soft_limit);\n"
- " \tunsigned long excess = 0;\n"
- " \n"
- "@@ -1609,13 +1622,13 @@ static unsigned long mem_cgroup_margin(struct mem_cgroup *memcg)\n"
- " \tunsigned long count;\n"
- " \tunsigned long limit;\n"
- " \n"
- "-\tcount = atomic_long_read(&memcg->memory.count);\n"
- "+\tcount = page_counter_read(&memcg->memory);\n"
- " \tlimit = ACCESS_ONCE(memcg->memory.limit);\n"
- " \tif (count < limit)\n"
- " \t\tmargin = limit - count;\n"
- " \n"
- " \tif (do_swap_account) {\n"
- "-\t\tcount = atomic_long_read(&memcg->memsw.count);\n"
- "+\t\tcount = page_counter_read(&memcg->memsw);\n"
- " \t\tlimit = ACCESS_ONCE(memcg->memsw.limit);\n"
- " \t\tif (count < limit)\n"
- " \t\t\tmargin = min(margin, limit - count);\n"
- "@@ -1763,14 +1776,14 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)\n"
- " \trcu_read_unlock();\n"
- " \n"
- " \tpr_info(\"memory: usage %llukB, limit %llukB, failcnt %lu\\n\",\n"
- "-\t\tK((u64)atomic_long_read(&memcg->memory.count)),\n"
- "-\t\tK((u64)memcg->memory.limit), memcg->memory.limited);\n"
- "+\t\tK((u64)page_counter_read(&memcg->memory)),\n"
- "+\t\tK((u64)memcg->memory.limit), memcg->memory.failcnt);\n"
- " \tpr_info(\"memory+swap: usage %llukB, limit %llukB, failcnt %lu\\n\",\n"
- "-\t\tK((u64)atomic_long_read(&memcg->memsw.count)),\n"
- "-\t\tK((u64)memcg->memsw.limit), memcg->memsw.limited);\n"
- "+\t\tK((u64)page_counter_read(&memcg->memsw)),\n"
- "+\t\tK((u64)memcg->memsw.limit), memcg->memsw.failcnt);\n"
- " \tpr_info(\"kmem: usage %llukB, limit %llukB, failcnt %lu\\n\",\n"
- "-\t\tK((u64)atomic_long_read(&memcg->kmem.count)),\n"
- "-\t\tK((u64)memcg->kmem.limit), memcg->kmem.limited);\n"
- "+\t\tK((u64)page_counter_read(&memcg->kmem)),\n"
- "+\t\tK((u64)memcg->kmem.limit), memcg->kmem.failcnt);\n"
- " \n"
- " \tfor_each_mem_cgroup_tree(iter, memcg) {\n"
- " \t\tpr_info(\"Memory cgroup stats for \");\n"
- "@@ -2604,10 +2617,10 @@ retry:\n"
- " \tif (consume_stock(memcg, nr_pages))\n"
- " \t\tgoto done;\n"
- " \n"
- "-\tif (!page_counter_charge(&memcg->memory, batch, &counter)) {\n"
- "+\tif (!page_counter_try_charge(&memcg->memory, batch, &counter)) {\n"
- " \t\tif (!do_swap_account)\n"
- " \t\t\tgoto done_restock;\n"
- "-\t\tif (!page_counter_charge(&memcg->memsw, batch, &counter))\n"
- "+\t\tif (!page_counter_try_charge(&memcg->memsw, batch, &counter))\n"
- " \t\t\tgoto done_restock;\n"
- " \t\tpage_counter_uncharge(&memcg->memory, batch);\n"
- " \t\tmem_over_limit = mem_cgroup_from_counter(counter, memsw);\n"
- "@@ -2877,7 +2890,7 @@ static int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp,\n"
- " \tstruct page_counter *counter;\n"
- " \tint ret = 0;\n"
- " \n"
- "-\tret = page_counter_charge(&memcg->kmem, nr_pages, &counter);\n"
- "+\tret = page_counter_try_charge(&memcg->kmem, nr_pages, &counter);\n"
- " \tif (ret < 0)\n"
- " \t\treturn ret;\n"
- " \n"
- "@@ -2898,9 +2911,9 @@ static int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp,\n"
- " \t\t * when the allocation triggers should have been already\n"
- " \t\t * directed to the root cgroup in memcontrol.h\n"
- " \t\t */\n"
- "-\t\tpage_counter_charge(&memcg->memory, nr_pages, NULL);\n"
- "+\t\tpage_counter_charge(&memcg->memory, nr_pages);\n"
- " \t\tif (do_swap_account)\n"
- "-\t\t\tpage_counter_charge(&memcg->memsw, nr_pages, NULL);\n"
- "+\t\t\tpage_counter_charge(&memcg->memsw, nr_pages);\n"
- " \t\tret = 0;\n"
- " \t} else if (ret)\n"
- " \t\tpage_counter_uncharge(&memcg->kmem, nr_pages);\n"
- "@@ -3558,9 +3571,9 @@ static int mem_cgroup_move_parent(struct page *page,\n"
- " \t\t\t\tpc, child, parent);\n"
- " \tif (!ret) {\n"
- " \t\t/* Take charge off the local counters */\n"
- "-\t\tpage_counter_cancel(&child->memory, nr_pages);\n"
- "+\t\tpage_counter_sub(&child->memory, nr_pages);\n"
- " \t\tif (do_swap_account)\n"
- "-\t\t\tpage_counter_cancel(&child->memsw, nr_pages);\n"
- "+\t\t\tpage_counter_sub(&child->memsw, nr_pages);\n"
- " \t}\n"
- " \n"
- " \tif (nr_pages > 1)\n"
- "@@ -3665,7 +3678,7 @@ void mem_cgroup_print_bad_page(struct page *page)\n"
- " }\n"
- " #endif\n"
- " \n"
- "-static DEFINE_MUTEX(set_limit_mutex);\n"
- "+static DEFINE_MUTEX(memcg_limit_mutex);\n"
- " \n"
- " static int mem_cgroup_resize_limit(struct mem_cgroup *memcg,\n"
- " \t\t\t\t   unsigned long limit)\n"
- "@@ -3684,7 +3697,7 @@ static int mem_cgroup_resize_limit(struct mem_cgroup *memcg,\n"
- " \tretry_count = MEM_CGROUP_RECLAIM_RETRIES *\n"
- " \t\t      mem_cgroup_count_children(memcg);\n"
- " \n"
- "-\toldusage = atomic_long_read(&memcg->memory.count);\n"
- "+\toldusage = page_counter_read(&memcg->memory);\n"
- " \n"
- " \tdo {\n"
- " \t\tif (signal_pending(current)) {\n"
- "@@ -3692,23 +3705,23 @@ static int mem_cgroup_resize_limit(struct mem_cgroup *memcg,\n"
- " \t\t\tbreak;\n"
- " \t\t}\n"
- " \n"
- "-\t\tmutex_lock(&set_limit_mutex);\n"
- "+\t\tmutex_lock(&memcg_limit_mutex);\n"
- " \t\tif (limit > memcg->memsw.limit) {\n"
- "-\t\t\tmutex_unlock(&set_limit_mutex);\n"
- "+\t\t\tmutex_unlock(&memcg_limit_mutex);\n"
- " \t\t\tret = -EINVAL;\n"
- " \t\t\tbreak;\n"
- " \t\t}\n"
- " \t\tif (limit > memcg->memory.limit)\n"
- " \t\t\tenlarge = true;\n"
- " \t\tret = page_counter_limit(&memcg->memory, limit);\n"
- "-\t\tmutex_unlock(&set_limit_mutex);\n"
- "+\t\tmutex_unlock(&memcg_limit_mutex);\n"
- " \n"
- " \t\tif (!ret)\n"
- " \t\t\tbreak;\n"
- " \n"
- " \t\ttry_to_free_mem_cgroup_pages(memcg, 1, GFP_KERNEL, true);\n"
- " \n"
- "-\t\tcurusage = atomic_long_read(&memcg->memory.count);\n"
- "+\t\tcurusage = page_counter_read(&memcg->memory);\n"
- " \t\t/* Usage is reduced ? */\n"
- " \t\tif (curusage >= oldusage)\n"
- " \t\t\tretry_count--;\n"
- "@@ -3735,7 +3748,7 @@ static int mem_cgroup_resize_memsw_limit(struct mem_cgroup *memcg,\n"
- " \tretry_count = MEM_CGROUP_RECLAIM_RETRIES *\n"
- " \t\t      mem_cgroup_count_children(memcg);\n"
- " \n"
- "-\toldusage = atomic_long_read(&memcg->memsw.count);\n"
- "+\toldusage = page_counter_read(&memcg->memsw);\n"
- " \n"
- " \tdo {\n"
- " \t\tif (signal_pending(current)) {\n"
- "@@ -3743,23 +3756,23 @@ static int mem_cgroup_resize_memsw_limit(struct mem_cgroup *memcg,\n"
- " \t\t\tbreak;\n"
- " \t\t}\n"
- " \n"
- "-\t\tmutex_lock(&set_limit_mutex);\n"
- "+\t\tmutex_lock(&memcg_limit_mutex);\n"
- " \t\tif (limit < memcg->memory.limit) {\n"
- "-\t\t\tmutex_unlock(&set_limit_mutex);\n"
- "+\t\t\tmutex_unlock(&memcg_limit_mutex);\n"
- " \t\t\tret = -EINVAL;\n"
- " \t\t\tbreak;\n"
- " \t\t}\n"
- " \t\tif (limit > memcg->memsw.limit)\n"
- " \t\t\tenlarge = true;\n"
- " \t\tret = page_counter_limit(&memcg->memsw, limit);\n"
- "-\t\tmutex_unlock(&set_limit_mutex);\n"
- "+\t\tmutex_unlock(&memcg_limit_mutex);\n"
- " \n"
- " \t\tif (!ret)\n"
- " \t\t\tbreak;\n"
- " \n"
- " \t\ttry_to_free_mem_cgroup_pages(memcg, 1, GFP_KERNEL, false);\n"
- " \n"
- "-\t\tcurusage = atomic_long_read(&memcg->memsw.count);\n"
- "+\t\tcurusage = page_counter_read(&memcg->memsw);\n"
- " \t\t/* Usage is reduced ? */\n"
- " \t\tif (curusage >= oldusage)\n"
- " \t\t\tretry_count--;\n"
- "@@ -3960,8 +3973,8 @@ static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg)\n"
- " \t\t * right after the check. RES_USAGE should be safe as we always\n"
- " \t\t * charge before adding to the LRU.\n"
- " \t\t */\n"
- "-\t} while (atomic_long_read(&memcg->memory.count) -\n"
- "-\t\t atomic_long_read(&memcg->kmem.count) > 0);\n"
- "+\t} while (page_counter_read(&memcg->memory) -\n"
- "+\t\t page_counter_read(&memcg->kmem) > 0);\n"
- " }\n"
- " \n"
- " /*\n"
- "@@ -4001,7 +4014,7 @@ static int mem_cgroup_force_empty(struct mem_cgroup *memcg)\n"
- " \t/* we call try-to-free pages for make this cgroup empty */\n"
- " \tlru_add_drain_all();\n"
- " \t/* try to free all pages in this cgroup */\n"
- "-\twhile (nr_retries && atomic_long_read(&memcg->memory.count)) {\n"
- "+\twhile (nr_retries && page_counter_read(&memcg->memory)) {\n"
- " \t\tint progress;\n"
- " \n"
- " \t\tif (signal_pending(current))\n"
- "@@ -4098,9 +4111,9 @@ static inline u64 mem_cgroup_usage(struct mem_cgroup *memcg, bool swap)\n"
- " \t\t\tval += tree_stat(memcg, MEM_CGROUP_STAT_SWAP);\n"
- " \t} else {\n"
- " \t\tif (!swap)\n"
- "-\t\t\tval = atomic_long_read(&memcg->memory.count);\n"
- "+\t\t\tval = page_counter_read(&memcg->memory);\n"
- " \t\telse\n"
- "-\t\t\tval = atomic_long_read(&memcg->memsw.count);\n"
- "+\t\t\tval = page_counter_read(&memcg->memsw);\n"
- " \t}\n"
- " \treturn val << PAGE_SHIFT;\n"
- " }\n"
- "@@ -4139,13 +4152,13 @@ static u64 mem_cgroup_read_u64(struct cgroup_subsys_state *css,\n"
- " \t\t\treturn mem_cgroup_usage(memcg, false);\n"
- " \t\tif (counter == &memcg->memsw)\n"
- " \t\t\treturn mem_cgroup_usage(memcg, true);\n"
- "-\t\treturn (u64)atomic_long_read(&counter->count) * PAGE_SIZE;\n"
- "+\t\treturn (u64)page_counter_read(counter) * PAGE_SIZE;\n"
- " \tcase RES_LIMIT:\n"
- " \t\treturn (u64)counter->limit * PAGE_SIZE;\n"
- " \tcase RES_MAX_USAGE:\n"
- " \t\treturn (u64)counter->watermark * PAGE_SIZE;\n"
- " \tcase RES_FAILCNT:\n"
- "-\t\treturn counter->limited;\n"
- "+\t\treturn counter->failcnt;\n"
- " \tcase RES_SOFT_LIMIT:\n"
- " \t\treturn (u64)memcg->soft_limit * PAGE_SIZE;\n"
- " \tdefault:\n"
- "@@ -4234,10 +4247,12 @@ static int memcg_update_kmem_limit(struct mem_cgroup *memcg,\n"
- " {\n"
- " \tint ret;\n"
- " \n"
- "+\tmutex_lock(&memcg_limit_mutex);\n"
- " \tif (!memcg_kmem_is_active(memcg))\n"
- " \t\tret = memcg_activate_kmem(memcg, limit);\n"
- " \telse\n"
- " \t\tret = page_counter_limit(&memcg->kmem, limit);\n"
- "+\tmutex_unlock(&memcg_limit_mutex);\n"
- " \treturn ret;\n"
- " }\n"
- " \n"
- "@@ -4255,7 +4270,7 @@ static int memcg_propagate_kmem(struct mem_cgroup *memcg)\n"
- " \t * after this point, because it has at least one child already.\n"
- " \t */\n"
- " \tif (memcg_kmem_is_active(parent))\n"
- "-\t\tret = __memcg_activate_kmem(memcg, ULONG_MAX);\n"
- "+\t\tret = __memcg_activate_kmem(memcg, PAGE_COUNTER_MAX);\n"
- " \tmutex_unlock(&activate_kmem_mutex);\n"
- " \treturn ret;\n"
- " }\n"
- "@@ -4331,10 +4346,10 @@ static ssize_t mem_cgroup_reset(struct kernfs_open_file *of, char *buf,\n"
- " \n"
- " \tswitch (MEMFILE_ATTR(of_cft(of)->private)) {\n"
- " \tcase RES_MAX_USAGE:\n"
- "-\t\tcounter->watermark = atomic_long_read(&counter->count);\n"
- "+\t\tpage_counter_reset_watermark(counter);\n"
- " \t\tbreak;\n"
- " \tcase RES_FAILCNT:\n"
- "-\t\tcounter->limited = 0;\n"
- "+\t\tcounter->failcnt = 0;\n"
- " \t\tbreak;\n"
- " \tdefault:\n"
- " \t\tBUG();\n"
- "@@ -4934,7 +4949,7 @@ static void kmem_cgroup_css_offline(struct mem_cgroup *memcg)\n"
- " \n"
- " \tmemcg_kmem_mark_dead(memcg);\n"
- " \n"
- "-\tif (atomic_long_read(&memcg->kmem.count))\n"
- "+\tif (page_counter_read(&memcg->kmem))\n"
- " \t\treturn;\n"
- " \n"
- " \tif (memcg_kmem_test_and_clear_dead(memcg))\n"
- "@@ -5603,7 +5618,7 @@ static void mem_cgroup_css_free(struct cgroup_subsys_state *css)\n"
- " \t * call_rcu()\n"
- " \t *   offline_css()\n"
- " \t *     reparent_charges()\n"
- "-\t *                           page_counter_charge()\n"
- "+\t *                           page_counter_try_charge()\n"
- " \t *                           css_put()\n"
- " \t *                             css_free()\n"
- " \t *                           pc->mem_cgroup = dead memcg\n"
- "diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c\n"
- "index 9a448bdb19e9..272327134a1b 100644\n"
- "--- a/net/ipv4/tcp_memcontrol.c\n"
- "+++ b/net/ipv4/tcp_memcontrol.c\n"
- "@@ -68,7 +68,7 @@ static int tcp_update_limit(struct mem_cgroup *memcg, unsigned long nr_pages)\n"
- " \t\tcg_proto->sysctl_mem[i] = min_t(long, nr_pages,\n"
- " \t\t\t\t\t\tsysctl_tcp_mem[i]);\n"
- " \n"
- "-\tif (nr_pages == ULONG_MAX / PAGE_SIZE)\n"
- "+\tif (nr_pages == PAGE_COUNTER_MAX)\n"
- " \t\tclear_bit(MEMCG_SOCK_ACTIVE, &cg_proto->flags);\n"
- " \telse {\n"
- " \t\t/*\n"
- "@@ -106,6 +106,8 @@ enum {\n"
- " \tRES_FAILCNT,\n"
- " };\n"
- " \n"
- "+static DEFINE_MUTEX(tcp_limit_mutex);\n"
- "+\n"
- " static ssize_t tcp_cgroup_write(struct kernfs_open_file *of,\n"
- " \t\t\t\tchar *buf, size_t nbytes, loff_t off)\n"
- " {\n"
- "@@ -121,7 +123,9 @@ static ssize_t tcp_cgroup_write(struct kernfs_open_file *of,\n"
- " \t\tret = page_counter_memparse(buf, &nr_pages);\n"
- " \t\tif (ret)\n"
- " \t\t\tbreak;\n"
- "+\t\tmutex_lock(&tcp_limit_mutex);\n"
- " \t\tret = tcp_update_limit(memcg, nr_pages);\n"
- "+\t\tmutex_unlock(&tcp_limit_mutex);\n"
- " \t\tbreak;\n"
- " \tdefault:\n"
- " \t\tret = -EINVAL;\n"
- "@@ -145,14 +149,15 @@ static u64 tcp_cgroup_read(struct cgroup_subsys_state *css, struct cftype *cft)\n"
- " \t\tbreak;\n"
- " \tcase RES_USAGE:\n"
- " \t\tif (!cg_proto)\n"
- "-\t\t\treturn atomic_long_read(&tcp_memory_allocated);\n"
- "-\t\tval = atomic_long_read(&cg_proto->memory_allocated.count);\n"
- "+\t\t\tval = atomic_long_read(&tcp_memory_allocated);\n"
- "+\t\telse\n"
- "+\t\t\tval = page_counter_read(&cg_proto->memory_allocated);\n"
- " \t\tval *= PAGE_SIZE;\n"
- " \t\tbreak;\n"
- " \tcase RES_FAILCNT:\n"
- " \t\tif (!cg_proto)\n"
- " \t\t\treturn 0;\n"
- "-\t\tval = cg_proto->memory_allocated.limited;\n"
- "+\t\tval = cg_proto->memory_allocated.failcnt;\n"
- " \t\tbreak;\n"
- " \tcase RES_MAX_USAGE:\n"
- " \t\tif (!cg_proto)\n"
- "@@ -179,11 +184,10 @@ static ssize_t tcp_cgroup_reset(struct kernfs_open_file *of,\n"
- " \n"
- " \tswitch (of_cft(of)->private) {\n"
- " \tcase RES_MAX_USAGE:\n"
- "-\t\tcg_proto->memory_allocated.watermark =\n"
- "-\t\t\tatomic_long_read(&cg_proto->memory_allocated.count);\n"
- "+\t\tpage_counter_reset_watermark(&cg_proto->memory_allocated);\n"
- " \t\tbreak;\n"
- " \tcase RES_FAILCNT:\n"
- "-\t\tcg_proto->memory_allocated.limited = 0;\n"
- "+\t\tcg_proto->memory_allocated.failcnt = 0;\n"
- " \t\tbreak;\n"
- " \t}\n"
- " \n"
- "-- \n"
- "2.1.0\n"
- "\n"
- "\n"
- "--\n"
- "To unsubscribe, send a message with 'unsubscribe linux-mm' in\n"
- "the body to majordomo@kvack.org.  For more info on Linux MM,\n"
- "see: http://www.linux-mm.org/ .\n"
- "Don't email: <a href=mailto:\"dont@kvack.org\"> email@kvack.org </a>"
+ ---
 
-89f67fcc0f7cd7d3c101e0f4628ef42b7213f688766a5c4803e345c654f5c7b2
+3dda00bc6d03373b5eab47b61048550d4de920f67e9cdada604e56e45e002421

diff --git a/a/1.txt b/N2/1.txt
index 54985a3..c090594 100644
--- a/a/1.txt
+++ b/N2/1.txt
@@ -451,7 +451,7 @@ Thanks for your thorough review, Vladimir!
 Here is the delta patch:
 
 ---
-From 3601538347af756b9bfe05142ab21b5ae44f8cdd Mon Sep 17 00:00:00 2001
+>From 3601538347af756b9bfe05142ab21b5ae44f8cdd Mon Sep 17 00:00:00 2001
 From: Johannes Weiner <hannes@cmpxchg.org>
 Date: Mon, 22 Sep 2014 13:54:24 -0400
 Subject: [patch] mm: memcontrol: lockless page counters fix
@@ -1089,10 +1089,3 @@ index 9a448bdb19e9..272327134a1b 100644
  
 -- 
 2.1.0
-
-
---
-To unsubscribe, send a message with 'unsubscribe linux-mm' in
-the body to majordomo@kvack.org.  For more info on Linux MM,
-see: http://www.linux-mm.org/ .
-Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
diff --git a/a/content_digest b/N2/content_digest
index dd677e0..2fb009b 100644
--- a/a/content_digest
+++ b/N2/content_digest
@@ -465,7 +465,7 @@
  "Here is the delta patch:\n"
  "\n"
  "---\n"
- "From 3601538347af756b9bfe05142ab21b5ae44f8cdd Mon Sep 17 00:00:00 2001\n"
+ ">From 3601538347af756b9bfe05142ab21b5ae44f8cdd Mon Sep 17 00:00:00 2001\n"
  "From: Johannes Weiner <hannes@cmpxchg.org>\n"
  "Date: Mon, 22 Sep 2014 13:54:24 -0400\n"
  "Subject: [patch] mm: memcontrol: lockless page counters fix\n"
@@ -1102,13 +1102,6 @@
  " \t}\n"
  " \n"
  "-- \n"
- "2.1.0\n"
- "\n"
- "\n"
- "--\n"
- "To unsubscribe, send a message with 'unsubscribe linux-mm' in\n"
- "the body to majordomo@kvack.org.  For more info on Linux MM,\n"
- "see: http://www.linux-mm.org/ .\n"
- "Don't email: <a href=mailto:\"dont@kvack.org\"> email@kvack.org </a>"
+ 2.1.0
 
-89f67fcc0f7cd7d3c101e0f4628ef42b7213f688766a5c4803e345c654f5c7b2
+a376983028772f94e302625bcef6b32d79a3ee4792d1e00ecd030831f1d7a8cd

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.