[Devel] [PATCH rh7 4/4] net/packet: cleanup packet_sk_charge

Vladimir Davydov vdavydov at parallels.com
Thu Jun 25 09:08:25 PDT 2015


 - Do not check mem_cgroup_sockets_enabled - it has nothing to do with
   tcp/udp buffers accounting, which enable this static key. A check if
   memcg_kmem_is_active is enough anyway.

 - Do not forget to put memcg if try_get_mem_cgroup_from_mm returned a
   kmem inactive memcg.

 - Use ACCESS_ONCE for reading sysctl_rmem_max, because it can change on
   the fly and we rely on it being constant.

 - Use memcg_charge_kmem instead of memcg_charge_kmem_nofail for
   charging sock packet buf, because we can dive into reclaim here.

Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 include/linux/memcontrol.h |  1 +
 mm/memcontrol.c            |  2 +-
 net/packet/af_packet.c     | 44 +++++++++++++++++++++++++++-----------------
 3 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index e09ec923a5d1..eb7ae43a57f9 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -481,6 +481,7 @@ void __memcg_kmem_put_cache(struct kmem_cache *cachep);
 
 struct mem_cgroup *__mem_cgroup_from_kmem(void *ptr);
 
+int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp, u64 size);
 void memcg_charge_kmem_nofail(struct mem_cgroup *memcg, u64 size);
 void memcg_uncharge_kmem(struct mem_cgroup *memcg, u64 size);
 
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 17552cfbf4a1..cb153ac4567b 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3158,7 +3158,7 @@ static int mem_cgroup_slabinfo_read(struct cgroup *cont, struct cftype *cft,
 }
 #endif
 
-static int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp, u64 size)
+int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp, u64 size)
 {
 	struct res_counter *fail_res;
 	struct mem_cgroup *_memcg;
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index a2e4fadf36f6..af79d53acc52 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2429,28 +2429,38 @@ struct packet_sk_charge {
 static struct cg_proto *packet_sk_charge(void)
 {
 	struct packet_sk_charge *psc;
-
-	if (!mem_cgroup_sockets_enabled)
-		return NULL;
+	int err = -ENOMEM;
 
 	psc = kmalloc(sizeof(*psc), GFP_KERNEL);
 	if (!psc)
-		return ERR_PTR(-ENOMEM);
+		goto out;
 
+	err = 0;
 	psc->memcg = try_get_mem_cgroup_from_mm(current->mm);
-	if (psc->memcg && memcg_kmem_is_active(psc->memcg)) {
-		/*
-		 * Forcedly charge the maximum amount of data this socket
-		 * may have. It's typically not huge and packet sockets are
-		 * rare guests in containers, so we don't disturb the memory
-		 * consumption much.
-		 */
-		psc->amt = sysctl_rmem_max;
-		memcg_charge_kmem_nofail(psc->memcg, psc->amt);
-	} else {
-		kfree(psc);
-		psc = NULL;
-	}
+	if (!psc->memcg)
+		goto out_free_psc;
+	if (!memcg_kmem_is_active(psc->memcg))
+		goto out_put_cg;
+
+	/*
+	 * Forcedly charge the maximum amount of data this socket may have.
+	 * It's typically not huge and packet sockets are rare guests in
+	 * containers, so we don't disturb the memory consumption much.
+	 */
+	psc->amt = ACCESS_ONCE(sysctl_rmem_max);
+
+	err = memcg_charge_kmem(psc->memcg, GFP_KERNEL, psc->amt);
+	if (!err)
+		goto out;
+
+out_put_cg:
+	css_put(mem_cgroup_css(psc->memcg));
+out_free_psc:
+	kfree(psc);
+	psc = NULL;
+out:
+	if (err)
+		return ERR_PTR(err);
 
 	/*
 	 * The sk->sk_cgrp is not used for packet sockets,
-- 
2.1.4




More information about the Devel mailing list