Thread (5 messages) 5 messages, 2 authors, 2018-04-06

Re: [PATCH v3 1/2] mm: memcg: remote memcg charging for kmem allocations

From: Shakeel Butt <hidden>
Date: 2018-03-13 17:55:18
Also in: linux-fsdevel, linux-mm, lkml

On Tue, Mar 13, 2018 at 6:49 AM, Michal Hocko [off-list ref] wrote:
On Wed 21-02-18 14:37:56, Shakeel Butt wrote:
[...]
quoted
+#ifdef CONFIG_MEMCG
+static inline struct mem_cgroup *memalloc_memcg_save(struct mem_cgroup *memcg)
+{
+     struct mem_cgroup *old_memcg = current->target_memcg;
+     current->target_memcg = memcg;
+     return old_memcg;
+}
So you are relying that the caller will handle the reference counting
properly? I do not think this is a good idea.
For the fsnotify use-case, this assumption makes sense as fsnotify has
an abstraction of fsnotify_group which is created by the
person/process interested in the events and thus can be used to hold
the reference to the person/process's memcg. Another use-case I have
in mind is the filesystem mount. Basically attaching a mount with a
memcg and thus all user pages and kmem allocations (inodes, dentries)
for that mount will be charged to the attached memcg. In this use-case
the super_block is the perfect structure to hold the reference to the
memcg.

If in future we find a use-case where this assumption does not make
sense we can evolve the API and since this is kernel internal API, it
should not be hard to evolve.
Also do we need some kind
of debugging facility to detect unbalanced save/restore scopes?
I am not sure, I didn't find other similar patterns (like PF_MEMALLOC)
having debugging facility. Maybe we can add such debugging facility
when we find more users other than kmalloc & kmem_cache_alloc. Vmalloc
may be one but I could not think of a use-case for vmalloc for remote
charging, so, no need to add more code at this time.
[...]
quoted
@@ -2260,7 +2269,10 @@ struct kmem_cache *memcg_kmem_get_cache(struct kmem_cache *cachep)
      if (current->memcg_kmem_skip_account)
              return cachep;

-     memcg = get_mem_cgroup_from_mm(current->mm);
+     if (current->target_memcg)
+             memcg = get_mem_cgroup(current->target_memcg);
+     if (!memcg)
+             memcg = get_mem_cgroup_from_mm(current->mm);
      kmemcg_id = READ_ONCE(memcg->kmemcg_id);
      if (kmemcg_id < 0)
              goto out;
You are also adding one branch for _each_ charge path even though the
usecase is rather limited.
I understand the concern but the charging path, IMO, is much complex
than just one or couple of additional branches. I can run a simple
microbenchmark to see if there is anything noticeable here.
I will have to think about this approach more. It is clearly less code
than your previous attempt but I cannot say I would be really impressed.
Thanks for your time.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help