linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
To: akpm@linux-foundation.org, guro@fb.com, hannes@cmpxchg.org,
	linux-mm@kvack.org, mhocko@kernel.org,
	mm-commits@vger.kernel.org, shakeelb@google.com,
	torvalds@linux-foundation.org
Subject: [patch 05/40] mm: kmem: prepare remote memcg charging infra for interrupt contexts
Date: Sat, 17 Oct 2020 16:13:50 -0700	[thread overview]
Message-ID: <20201017231350.KU3k56hf5%akpm@linux-foundation.org> (raw)
In-Reply-To: <20201017161314.88890b87fae7446ccc13c902@linux-foundation.org>

From: Roman Gushchin <guro@fb.com>
Subject: mm: kmem: prepare remote memcg charging infra for interrupt contexts

Remote memcg charging API uses current->active_memcg to store the
currently active memory cgroup, which overwrites the memory cgroup of the
current process.  It works well for normal contexts, but doesn't work for
interrupt contexts: indeed, if an interrupt occurs during the execution of
a section with an active memcg set, all allocations inside the interrupt
will be charged to the active memcg set (given that we'll enable
accounting for allocations from an interrupt context).  But because the
interrupt might have no relation to the active memcg set outside, it's
obviously wrong from the accounting prospective.

To resolve this problem, let's add a global percpu int_active_memcg
variable, which will be used to store an active memory cgroup which will
be used from interrupt contexts.  set_active_memcg() will transparently
use current->active_memcg or int_active_memcg depending on the context.

To make the read part simple and transparent for the caller, let's
introduce two new functions:
  - struct mem_cgroup *active_memcg(void),
  - struct mem_cgroup *get_active_memcg(void).

They are returning the active memcg if it's set, hiding all implementation
details: where to get it depending on the current context.

Link: http://lkml.kernel.org/r/20200827225843.1270629-4-guro@fb.com
Signed-off-by: Roman Gushchin <guro@fb.com>
Reviewed-by: Shakeel Butt <shakeelb@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 include/linux/sched/mm.h |   13 ++++++++--
 mm/memcontrol.c          |   48 ++++++++++++++++++++++++++-----------
 2 files changed, 45 insertions(+), 16 deletions(-)

--- a/include/linux/sched/mm.h~mm-kmem-prepare-remote-memcg-charging-infra-for-interrupt-contexts
+++ a/include/linux/sched/mm.h
@@ -279,6 +279,7 @@ static inline void memalloc_nocma_restor
 #endif
 
 #ifdef CONFIG_MEMCG
+DECLARE_PER_CPU(struct mem_cgroup *, int_active_memcg);
 /**
  * set_active_memcg - Starts the remote memcg charging scope.
  * @memcg: memcg to charge.
@@ -293,8 +294,16 @@ static inline void memalloc_nocma_restor
 static inline struct mem_cgroup *
 set_active_memcg(struct mem_cgroup *memcg)
 {
-	struct mem_cgroup *old = current->active_memcg;
-	current->active_memcg = memcg;
+	struct mem_cgroup *old;
+
+	if (in_interrupt()) {
+		old = this_cpu_read(int_active_memcg);
+		this_cpu_write(int_active_memcg, memcg);
+	} else {
+		old = current->active_memcg;
+		current->active_memcg = memcg;
+	}
+
 	return old;
 }
 #else
--- a/mm/memcontrol.c~mm-kmem-prepare-remote-memcg-charging-infra-for-interrupt-contexts
+++ a/mm/memcontrol.c
@@ -73,6 +73,9 @@ EXPORT_SYMBOL(memory_cgrp_subsys);
 
 struct mem_cgroup *root_mem_cgroup __read_mostly;
 
+/* Active memory cgroup to use from an interrupt context */
+DEFINE_PER_CPU(struct mem_cgroup *, int_active_memcg);
+
 /* Socket memory accounting disabled? */
 static bool cgroup_memory_nosocket;
 
@@ -1061,26 +1064,43 @@ struct mem_cgroup *get_mem_cgroup_from_p
 }
 EXPORT_SYMBOL(get_mem_cgroup_from_page);
 
-/**
- * If current->active_memcg is non-NULL, do not fallback to current->mm->memcg.
- */
-static __always_inline struct mem_cgroup *get_mem_cgroup_from_current(void)
+static __always_inline struct mem_cgroup *active_memcg(void)
 {
-	if (memcg_kmem_bypass())
-		return NULL;
+	if (in_interrupt())
+		return this_cpu_read(int_active_memcg);
+	else
+		return current->active_memcg;
+}
 
-	if (unlikely(current->active_memcg)) {
-		struct mem_cgroup *memcg;
+static __always_inline struct mem_cgroup *get_active_memcg(void)
+{
+	struct mem_cgroup *memcg;
 
-		rcu_read_lock();
+	rcu_read_lock();
+	memcg = active_memcg();
+	if (memcg) {
 		/* current->active_memcg must hold a ref. */
-		if (WARN_ON_ONCE(!css_tryget(&current->active_memcg->css)))
+		if (WARN_ON_ONCE(!css_tryget(&memcg->css)))
 			memcg = root_mem_cgroup;
 		else
 			memcg = current->active_memcg;
-		rcu_read_unlock();
-		return memcg;
 	}
+	rcu_read_unlock();
+
+	return memcg;
+}
+
+/**
+ * If active memcg is set, do not fallback to current->mm->memcg.
+ */
+static __always_inline struct mem_cgroup *get_mem_cgroup_from_current(void)
+{
+	if (memcg_kmem_bypass())
+		return NULL;
+
+	if (unlikely(active_memcg()))
+		return get_active_memcg();
+
 	return get_mem_cgroup_from_mm(current->mm);
 }
 
@@ -2940,8 +2960,8 @@ __always_inline struct obj_cgroup *get_o
 		return NULL;
 
 	rcu_read_lock();
-	if (unlikely(current->active_memcg))
-		memcg = rcu_dereference(current->active_memcg);
+	if (unlikely(active_memcg()))
+		memcg = active_memcg();
 	else
 		memcg = mem_cgroup_from_task(current);
 
_


  parent reply	other threads:[~2020-10-17 23:13 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-17 23:13 incoming Andrew Morton
2020-10-17 23:13 ` [patch 01/40] ia64: fix build error with !COREDUMP Andrew Morton
2020-10-17 23:13 ` [patch 02/40] mm, memcg: rework remote charging API to support nesting Andrew Morton
2020-10-17 23:13 ` [patch 03/40] mm: kmem: move memcg_kmem_bypass() calls to get_mem/obj_cgroup_from_current() Andrew Morton
2020-10-17 23:13 ` [patch 04/40] mm: kmem: remove redundant checks from get_obj_cgroup_from_current() Andrew Morton
2020-10-17 23:13 ` Andrew Morton [this message]
2020-10-17 23:13 ` [patch 06/40] mm: kmem: enable kernel memcg accounting from interrupt contexts Andrew Morton
2020-10-17 23:13 ` [patch 07/40] mm/memory-failure: remove a wrapper for alloc_migration_target() Andrew Morton
2020-10-17 23:14 ` [patch 08/40] mm/memory_hotplug: " Andrew Morton
2020-10-17 23:14 ` [patch 09/40] mm/migrate: avoid possible unnecessary process right check in kernel_move_pages() Andrew Morton
2020-10-17 23:14 ` [patch 10/40] mm/mmap: add inline vma_next() for readability of mmap code Andrew Morton
2020-10-17 23:14 ` [patch 11/40] mm/mmap: add inline munmap_vma_range() for code readability Andrew Morton
2020-10-17 23:14 ` [patch 12/40] mm/gup_benchmark: take the mmap lock around GUP Andrew Morton
2020-10-17 23:14 ` [patch 13/40] binfmt_elf: take the mmap lock around find_extend_vma() Andrew Morton
2020-10-17 23:14 ` [patch 14/40] mm/gup: assert that the mmap lock is held in __get_user_pages() Andrew Morton
2020-10-18  1:28   ` Jann Horn
2020-10-17 23:14 ` [patch 15/40] mm/gup_benchmark: rename to mm/gup_test Andrew Morton
2020-10-17 23:14 ` [patch 16/40] selftests/vm: use a common gup_test.h Andrew Morton
2020-10-18 16:18   ` Linus Torvalds
2020-10-18 16:22     ` Linus Torvalds
2020-10-18 18:50     ` John Hubbard
2020-10-18 19:03       ` Matthew Wilcox
2020-10-18 19:12         ` John Hubbard
2020-10-18 19:33           ` Linus Torvalds
2020-10-18 19:48             ` John Hubbard
2020-10-20  4:13               ` John Hubbard
2020-10-20 16:45                 ` Linus Torvalds
2020-10-20 18:45                   ` John Hubbard
2020-10-17 23:14 ` [patch 17/40] selftests/vm: rename run_vmtests --> run_vmtests.sh Andrew Morton
2020-10-17 23:14 ` [patch 18/40] selftests/vm: minor cleanup: Makefile and gup_test.c Andrew Morton
2020-10-17 23:14 ` [patch 19/40] selftests/vm: only some gup_test items are really benchmarks Andrew Morton
2020-10-17 23:14 ` [patch 20/40] selftests/vm: gup_test: introduce the dump_pages() sub-test Andrew Morton
2020-10-17 23:14 ` [patch 21/40] selftests/vm: run_vmtests.sh: update and clean up gup_test invocation Andrew Morton
2020-10-17 23:14 ` [patch 22/40] selftests/vm: hmm-tests: remove the libhugetlbfs dependency Andrew Morton
2020-10-17 23:14 ` [patch 23/40] selftests/vm: 10x speedup for hmm-tests Andrew Morton
2020-10-17 23:14 ` [patch 24/40] mm/madvise: pass mm to do_madvise Andrew Morton
2020-10-17 23:14 ` [patch 25/40] pid: move pidfd_get_pid() to pid.c Andrew Morton
2020-10-17 23:14 ` [patch 26/40] mm/madvise: introduce process_madvise() syscall: an external memory hinting API Andrew Morton
2020-10-17 23:15 ` [patch 27/40] mm: update the documentation for vfree Andrew Morton
2020-10-17 23:15 ` [patch 28/40] mm: add a VM_MAP_PUT_PAGES flag for vmap Andrew Morton
2020-10-17 23:15 ` [patch 29/40] mm: add a vmap_pfn function Andrew Morton
2020-10-17 23:15 ` [patch 30/40] mm: allow a NULL fn callback in apply_to_page_range Andrew Morton
2020-10-17 23:15 ` [patch 31/40] zsmalloc: switch from alloc_vm_area to get_vm_area Andrew Morton
2020-10-17 23:15 ` [patch 32/40] drm/i915: use vmap in shmem_pin_map Andrew Morton
2020-10-17 23:15 ` [patch 33/40] drm/i915: stop using kmap in i915_gem_object_map Andrew Morton
2020-10-17 23:15 ` [patch 34/40] drm/i915: use vmap " Andrew Morton
2020-10-17 23:15 ` [patch 35/40] xen/xenbus: use apply_to_page_range directly in xenbus_map_ring_pv Andrew Morton
2020-10-17 23:15 ` [patch 36/40] x86/xen: open code alloc_vm_area in arch_gnttab_valloc Andrew Morton
2020-10-17 23:15 ` [patch 37/40] mm: remove alloc_vm_area Andrew Morton
2020-10-17 23:15 ` [patch 38/40] mm: cleanup the gfp_mask handling in __vmalloc_area_node Andrew Morton
2020-10-17 23:15 ` [patch 39/40] mm: remove the filename in the top of file comment in vmalloc.c Andrew Morton
2020-10-17 23:15 ` [patch 40/40] mm: remove duplicate include statement in mmu.c Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201017231350.KU3k56hf5%akpm@linux-foundation.org \
    --to=akpm@linux-foundation.org \
    --cc=guro@fb.com \
    --cc=hannes@cmpxchg.org \
    --cc=linux-mm@kvack.org \
    --cc=mhocko@kernel.org \
    --cc=mm-commits@vger.kernel.org \
    --cc=shakeelb@google.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).