[Devel] [PATCH RHEL7 COMMIT] net/packet: cleanup packet_sk_charge

Konstantin Khorenko khorenko at virtuozzo.com
Mon Jun 29 04:00:45 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.21
------>
commit 30a812f9edd80554dd11977529a789afd5f9bc18
Author: Vladimir Davydov <vdavydov at parallels.com>
Date:   Mon Jun 29 15:00:45 2015 +0400

    net/packet: cleanup packet_sk_charge
    
     - 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 e09ec92..eb7ae43 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 17552cf..cb153ac 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 a2e4fad..af79d53 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,



More information about the Devel mailing list