[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