Skip to contentSkip to conversation

memcg: workingset: remove folio_memcg_rcu usage

PATCH Applied Shakeel Butt 3 participants 5 messages Oct 26, 2024 – Oct 27, 2024

Subsystems (5)
lore
Share & tools
lore

Shakeel Butt

author maintainer
#0 lore raw

PATCH v2 1/1 memcg: workingset: remove folio_memcg_rcu usage

The function workingset_activation() is called from folio_mark_accessed() with the guarantee that the given folio can not be freed under us in workingset_activation(). In addition, the association of the folio and its memcg can not be broken here because charge migration is no more. There is no need to use folio_memcg_rcu. Simply use folio_memcg_charged() because that is what this function cares about.

---
Andrew, please put this patch after charge migration deprecation series.

Changes since v1:
- Fix for mem_cgroup_disabled(). (Yu Zhao)

 include/linux/memcontrol.h | 35 -----------------------------------
 mm/workingset.c            | 14 ++------------
 2 files changed, 2 insertions(+), 47 deletions(-)
include/linux/memcontrol.h +0 -35
index 932534291ca2..89a1e9f10e1b 100644
@@ -443,35 +443,6 @@ static inline bool folio_memcg_charged(struct folio *folio)
 	return __folio_memcg(folio) != NULL;
 }
 
-/**
- * folio_memcg_rcu - Locklessly get the memory cgroup associated with a folio.
- * @folio: Pointer to the folio.
- *
- * This function assumes that the folio is known to have a
- * proper memory cgroup pointer. It's not safe to call this function
- * against some type of folios, e.g. slab folios or ex-slab folios.
- *
- * Return: A pointer to the memory cgroup associated with the folio,
- * or NULL.
- */
-static inline struct mem_cgroup *folio_memcg_rcu(struct folio *folio)
-{
-	unsigned long memcg_data = READ_ONCE(folio->memcg_data);
-
-	VM_BUG_ON_FOLIO(folio_test_slab(folio), folio);
-
-	if (memcg_data & MEMCG_DATA_KMEM) {
-		struct obj_cgroup *objcg;
-
-		objcg = (void *)(memcg_data & ~OBJEXTS_FLAGS_MASK);
-		return obj_cgroup_memcg(objcg);
-	}
-
-	WARN_ON_ONCE(!rcu_read_lock_held());
-
-	return (struct mem_cgroup *)(memcg_data & ~OBJEXTS_FLAGS_MASK);
-}
-
 /*
  * folio_memcg_check - Get the memory cgroup associated with a folio.
  * @folio: Pointer to the folio.
@@ -1084,12 +1055,6 @@ static inline struct mem_cgroup *folio_memcg(struct folio *folio)
 	return NULL;
 }
 
-static inline struct mem_cgroup *folio_memcg_rcu(struct folio *folio)
-{
-	WARN_ON_ONCE(!rcu_read_lock_held());
-	return NULL;
-}
-
 static inline struct mem_cgroup *folio_memcg_check(struct folio *folio)
 {
 	return NULL;
mm/workingset.c +2 -12
index 4b58ef535a17..a4705e196545 100644
@@ -591,22 +591,12 @@ void workingset_refault(struct folio *folio, void *shadow)
  */
 void workingset_activation(struct folio *folio)
 {
-	struct mem_cgroup *memcg;
-
-	rcu_read_lock();
 	/*
 	 * Filter non-memcg pages here, e.g. unmap can call
 	 * mark_page_accessed() on VDSO pages.
-	 *
-	 * XXX: See workingset_refault() - this should return
-	 * root_mem_cgroup even for !CONFIG_MEMCG.
 	 */
-	memcg = folio_memcg_rcu(folio);
-	if (!mem_cgroup_disabled() && !memcg)
-		goto out;
-	workingset_age_nonresident(folio_lruvec(folio), folio_nr_pages(folio));
-out:
-	rcu_read_unlock();
+	if (mem_cgroup_disabled() || folio_memcg_charged(folio))
+		workingset_age_nonresident(folio_lruvec(folio), folio_nr_pages(folio));
 }
 
 /*
Signature · 1 line
2.43.5
#1 lore raw
kernel test robot noticed the following build errors:

Hi Shakeel,

kernel test robot noticed the following build errors:

[auto build test ERROR on akpm-mm/mm-everything]
[also build test ERROR on linus/master v6.12-rc4 next-20241025] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Shakeel-Butt/memcg-workingset-remove-folio_memcg_rcu-usage/20241027-003815
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20241026163707.2479526-1-shakeel.butt%40linux.dev
patch subject: [PATCH v2] memcg: workingset: remove folio_memcg_rcu usage
config: sh-secureedge5410_defconfig (https://download.01.org/0day-ci/archive/20241027/[email protected]/config)
compiler: sh4-linux-gcc (GCC) 13.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241027/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All errors (new ones prefixed by >>):

mm/workingset.c: In function 'workingset_activation':

>> mm/workingset.c:598:38: error: implicit declaration of function 'folio_memcg_charged'; did you mean 'folio_memcg_check'? [-Werror=implicit-function-declaration]
     598 |         if (mem_cgroup_disabled() || folio_memcg_charged(folio))
         |                                      ^~~~~~~~~~~~~~~~~~~
         |                                      folio_memcg_check

cc1: some warnings being treated as errors

vim +598 mm/workingset.c

587
588 /**
589 * workingset_activation - note a page activation
590 * @folio: Folio that is being activated.
591 */
592 void workingset_activation(struct folio *folio)
593 {
594 /*
595 * Filter non-memcg pages here, e.g. unmap can call
596 * mark_page_accessed() on VDSO pages.
597 */

 > 598		if (mem_cgroup_disabled() || folio_memcg_charged(folio))

599 workingset_age_nonresident(folio_lruvec(folio), folio_nr_pages(folio));
600 }
601

Signature · 2 lines
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
#2 lore raw
In reply to Shakeel Butt
kernel test robot noticed the following build errors:

Hi Shakeel,

kernel test robot noticed the following build errors:

[auto build test ERROR on akpm-mm/mm-everything]
[also build test ERROR on linus/master v6.12-rc4 next-20241025] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Shakeel-Butt/memcg-workingset-remove-folio_memcg_rcu-usage/20241027-003815
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20241026163707.2479526-1-shakeel.butt%40linux.dev
patch subject: [PATCH v2] memcg: workingset: remove folio_memcg_rcu usage
config: x86_64-allnoconfig (https://download.01.org/0day-ci/archive/20241027/[email protected]/config)
compiler: clang version 19.1.2 (https://github.com/llvm/llvm-project 7ba7d8e2f7b6445b60679da826210cdde29eaf8b)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241027/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All errors (new ones prefixed by >>):

In file included from mm/workingset.c:8:
In file included from include/linux/memcontrol.h:21:
In file included from include/linux/mm.h:2213:
include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]

     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   In file included from mm/workingset.c:9:
   include/linux/mm_inline.h:47:41: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
      47 |         __mod_lruvec_state(lruvec, NR_LRU_BASE + lru, nr_pages);
         |                                    ~~~~~~~~~~~ ^ ~~~
   include/linux/mm_inline.h:49:22: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
      49 |                                 NR_ZONE_LRU_BASE + lru, nr_pages);
         |                                 ~~~~~~~~~~~~~~~~ ^ ~~~
>> mm/workingset.c:598:31: error: call to undeclared function 'folio_memcg_charged'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     598 |         if (mem_cgroup_disabled() || folio_memcg_charged(folio))
         |                                      ^

mm/workingset.c:598:31: note: did you mean 'folio_memcg_check'? include/linux/memcontrol.h:1058:34: note: 'folio_memcg_check' declared here
1058 | static inline struct mem_cgroup *folio_memcg_check(struct folio *folio)
| ^
3 warnings and 1 error generated.

vim +/folio_memcg_charged +598 mm/workingset.c

587
588 /**
589 * workingset_activation - note a page activation
590 * @folio: Folio that is being activated.
591 */
592 void workingset_activation(struct folio *folio)
593 {
594 /*
595 * Filter non-memcg pages here, e.g. unmap can call
596 * mark_page_accessed() on VDSO pages.
597 */

 > 598		if (mem_cgroup_disabled() || folio_memcg_charged(folio))

599 workingset_age_nonresident(folio_lruvec(folio), folio_nr_pages(folio));
600 }
601

Signature · 2 lines
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
author maintainer
#3 lore raw
In reply to Shakeel Butt
Quoted 8 lines · Shakeel Butt

The function workingset_activation() is called from folio_mark_accessed() with the guarantee that the given folio can not be freed under us in workingset_activation(). In addition, the association of the folio and its memcg can not be broken here because charge migration is no more. There is no need to use folio_memcg_rcu. Simply use folio_memcg_charged() because that is what this function cares about.

Quoted 8 lines

---
Andrew, please put this patch after charge migration deprecation series.

Changes since v1:
- Fix for mem_cgroup_disabled(). (Yu Zhao)

It seems like folio_memcg_charged() is not defined for CONFIG_MEMCG=n config option. The following stub should fix the build for such config.

include/linux/memcontrol.h +5 -0
index 89a1e9f10e1b..5502aa8e138e 100644
@@ -1055,6 +1055,11 @@ static inline struct mem_cgroup *folio_memcg(struct folio *folio)
 	return NULL;
 }
 
+static inline bool folio_memcg_charged(struct folio *folio)
+{
+	return false;
+}
+
 static inline struct mem_cgroup *folio_memcg_check(struct folio *folio)
 {
 	return NULL;
Tested-by
#4 lore raw

On Sat, 26 Oct 2024 23:55:14 -0700 Shakeel Butt <[email protected]> wrote:

[...]
It seems like folio_memcg_charged() is not defined for CONFIG_MEMCG=n

Quoted 9 lines

config option. The following stub should fix the build for such config.

include/linux/memcontrol.h +0 -0
index 89a1e9f10e1b..5502aa8e138e 100644
@@ -1055,6 +1055,11 @@ static inline struct mem_cgroup *folio_memcg(struct folio *folio)
 	return NULL;

include/linux/memcontrol.h static inline struct mem_cgroup *folio_memcg(struct folio *folio) · line 1065

Quoted 10 lines
include/linux/memcontrol.h +5 -0
 }
 
+static inline bool folio_memcg_charged(struct folio *folio)
+{
+	return false;
+}
+
 static inline struct mem_cgroup *folio_memcg_check(struct folio *folio)
 {
 	return NULL;

Thanks,
SJ