diff mbox series

[v3,06/18] mm/memcg: Add folio_memcg() and related functions

Message ID 20210630040034.1155892-7-willy@infradead.org (mailing list archive)
State New
Headers show
Series Folio conversion of memcg | expand

Commit Message

Matthew Wilcox June 30, 2021, 4 a.m. UTC
memcg information is only stored in the head page, so the memcg
subsystem needs to assure that all accesses are to the head page.
The first step is converting page_memcg() to folio_memcg().

Retain page_memcg() as a wrapper around folio_memcg() and PageMemcgKmem()
as a wrapper around folio_memcg_kmem() but convert __page_memcg() to
__folio_memcg() and __page_objcg() to __folio_objcg().

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 include/linux/memcontrol.h | 105 +++++++++++++++++++++----------------
 mm/memcontrol.c            |  21 ++++----
 2 files changed, 73 insertions(+), 53 deletions(-)

Comments

kernel test robot June 30, 2021, 6:53 a.m. UTC | #1
Hi "Matthew,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on next-20210629]
[cannot apply to hnaz-linux-mm/master tip/perf/core cgroup/for-next v5.13]
[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]

url:    https://github.com/0day-ci/linux/commits/Matthew-Wilcox-Oracle/Folio-conversion-of-memcg/20210630-121408
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 007b350a58754a93ca9fe50c498cc27780171153
config: x86_64-randconfig-a003-20210628 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 8d21d5472501460933e78aead04cf59579025ba4)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # https://github.com/0day-ci/linux/commit/615adf6169006fa1bc5e19d2105ff9a333bef423
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Matthew-Wilcox-Oracle/Folio-conversion-of-memcg/20210630-121408
        git checkout 615adf6169006fa1bc5e19d2105ff9a333bef423
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=x86_64 olddefconfig

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from arch/x86/kernel/asm-offsets.c:13:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:13:
   In file included from include/linux/cgroup.h:28:
   In file included from include/linux/cgroup-defs.h:22:
   In file included from include/linux/bpf-cgroup.h:5:
   In file included from include/linux/bpf.h:20:
   In file included from include/linux/kallsyms.h:12:
   include/linux/mm.h:1382:42: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline int folio_nid(const struct folio *folio)
                                            ^
   include/linux/mm.h:1384:27: error: incomplete definition of type 'struct folio'
           return page_to_nid(&folio->page);
                               ~~~~~^
   include/linux/mm.h:1382:42: note: forward declaration of 'struct folio'
   static inline int folio_nid(const struct folio *folio)
                                            ^
   In file included from arch/x86/kernel/asm-offsets.c:13:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   include/linux/memcontrol.h:375:44: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline bool folio_memcg_kmem(struct folio *folio);
                                              ^
   include/linux/memcontrol.h:399:55: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline struct mem_cgroup *__folio_memcg(struct folio *folio)
                                                         ^
>> include/linux/memcontrol.h:401:34: error: incomplete definition of type 'struct folio'
           unsigned long memcg_data = folio->memcg_data;
                                      ~~~~~^
   include/linux/memcontrol.h:399:55: note: forward declaration of 'struct folio'
   static inline struct mem_cgroup *__folio_memcg(struct folio *folio)
                                                         ^
>> include/linux/memcontrol.h:403:2: error: implicit declaration of function 'VM_BUG_ON_FOLIO' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio_slab(folio), folio);
           ^
>> include/linux/memcontrol.h:403:18: error: implicit declaration of function 'folio_slab' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio_slab(folio), folio);
                           ^
   include/linux/memcontrol.h:420:55: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline struct obj_cgroup *__folio_objcg(struct folio *folio)
                                                         ^
   include/linux/memcontrol.h:422:34: error: incomplete definition of type 'struct folio'
           unsigned long memcg_data = folio->memcg_data;
                                      ~~~~~^
   include/linux/memcontrol.h:420:55: note: forward declaration of 'struct folio'
   static inline struct obj_cgroup *__folio_objcg(struct folio *folio)
                                                         ^
   include/linux/memcontrol.h:424:2: error: implicit declaration of function 'VM_BUG_ON_FOLIO' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio_slab(folio), folio);
           ^
   include/linux/memcontrol.h:424:18: error: implicit declaration of function 'folio_slab' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio_slab(folio), folio);
                           ^
   include/linux/memcontrol.h:451:53: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline struct mem_cgroup *folio_memcg(struct folio *folio)
                                                       ^
   include/linux/memcontrol.h:453:23: error: incompatible pointer types passing 'struct folio *' to parameter of type 'struct folio *' [-Werror,-Wincompatible-pointer-types]
           if (folio_memcg_kmem(folio))
                                ^~~~~
   include/linux/memcontrol.h:375:51: note: passing argument to parameter 'folio' here
   static inline bool folio_memcg_kmem(struct folio *folio);
                                                     ^
   include/linux/memcontrol.h:454:41: error: incompatible pointer types passing 'struct folio *' to parameter of type 'struct folio *' [-Werror,-Wincompatible-pointer-types]
                   return obj_cgroup_memcg(__folio_objcg(folio));
                                                         ^~~~~
   include/linux/memcontrol.h:420:62: note: passing argument to parameter 'folio' here
   static inline struct obj_cgroup *__folio_objcg(struct folio *folio)
                                                                ^
   include/linux/memcontrol.h:456:24: error: incompatible pointer types passing 'struct folio *' to parameter of type 'struct folio *' [-Werror,-Wincompatible-pointer-types]
                   return __folio_memcg(folio);
                                        ^~~~~
   include/linux/memcontrol.h:399:62: note: passing argument to parameter 'folio' here
   static inline struct mem_cgroup *__folio_memcg(struct folio *folio)
                                                                ^
   include/linux/memcontrol.h:461:21: error: implicit declaration of function 'page_folio' [-Werror,-Wimplicit-function-declaration]
           return folio_memcg(page_folio(page));
                              ^
   include/linux/memcontrol.h:461:21: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'struct folio *' [-Wint-conversion]
           return folio_memcg(page_folio(page));
                              ^~~~~~~~~~~~~~~~
   include/linux/memcontrol.h:451:60: note: passing argument to parameter 'folio' here
   static inline struct mem_cgroup *folio_memcg(struct folio *folio)
                                                              ^
   include/linux/memcontrol.h:541:44: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline bool folio_memcg_kmem(struct folio *folio)
                                              ^
   include/linux/memcontrol.h:541:20: error: conflicting types for 'folio_memcg_kmem'
   static inline bool folio_memcg_kmem(struct folio *folio)
                      ^
   include/linux/memcontrol.h:375:20: note: previous declaration is here
   static inline bool folio_memcg_kmem(struct folio *folio);
                      ^
   include/linux/memcontrol.h:543:35: error: incomplete definition of type 'struct folio'
           VM_BUG_ON_PGFLAGS(PageTail(&folio->page), &folio->page);
                                       ~~~~~^
   include/linux/mmdebug.h:76:60: note: expanded from macro 'VM_BUG_ON_PGFLAGS'
   #define VM_BUG_ON_PGFLAGS(cond, page) BUILD_BUG_ON_INVALID(cond)
                                                              ^~~~
   include/linux/build_bug.h:30:63: note: expanded from macro 'BUILD_BUG_ON_INVALID'
   #define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
                                                                 ^
   include/linux/memcontrol.h:541:44: note: forward declaration of 'struct folio'
   static inline bool folio_memcg_kmem(struct folio *folio)
                                              ^
   include/linux/memcontrol.h:544:2: error: implicit declaration of function 'VM_BUG_ON_FOLIO' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio->memcg_data & MEMCG_DATA_OBJCGS, folio);
           ^
   include/linux/memcontrol.h:544:23: error: incomplete definition of type 'struct folio'
           VM_BUG_ON_FOLIO(folio->memcg_data & MEMCG_DATA_OBJCGS, folio);
                           ~~~~~^
   include/linux/memcontrol.h:541:44: note: forward declaration of 'struct folio'
   static inline bool folio_memcg_kmem(struct folio *folio)
                                              ^
   include/linux/memcontrol.h:545:14: error: incomplete definition of type 'struct folio'
           return folio->memcg_data & MEMCG_DATA_KMEM;
                  ~~~~~^
   include/linux/memcontrol.h:541:44: note: forward declaration of 'struct folio'
   static inline bool folio_memcg_kmem(struct folio *folio)
                                              ^
   include/linux/memcontrol.h:607:26: error: implicit declaration of function 'page_folio' [-Werror,-Wimplicit-function-declaration]
           return folio_memcg_kmem(page_folio(page));
                                   ^
   include/linux/memcontrol.h:607:26: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'struct folio *' [-Wint-conversion]
           return folio_memcg_kmem(page_folio(page));
                                   ^~~~~~~~~~~~~~~~
   include/linux/memcontrol.h:375:51: note: passing argument to parameter 'folio' here
   static inline bool folio_memcg_kmem(struct folio *folio);
                                                     ^
   8 warnings and 17 errors generated.
--
   In file included from arch/x86/kernel/asm-offsets.c:13:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:13:
   In file included from include/linux/cgroup.h:28:
   In file included from include/linux/cgroup-defs.h:22:
   In file included from include/linux/bpf-cgroup.h:5:
   In file included from include/linux/bpf.h:20:
   In file included from include/linux/kallsyms.h:12:
   include/linux/mm.h:1382:42: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline int folio_nid(const struct folio *folio)
                                            ^
   include/linux/mm.h:1384:27: error: incomplete definition of type 'struct folio'
           return page_to_nid(&folio->page);
                               ~~~~~^
   include/linux/mm.h:1382:42: note: forward declaration of 'struct folio'
   static inline int folio_nid(const struct folio *folio)
                                            ^
   In file included from arch/x86/kernel/asm-offsets.c:13:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   include/linux/memcontrol.h:375:44: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline bool folio_memcg_kmem(struct folio *folio);
                                              ^
   include/linux/memcontrol.h:399:55: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline struct mem_cgroup *__folio_memcg(struct folio *folio)
                                                         ^
>> include/linux/memcontrol.h:401:34: error: incomplete definition of type 'struct folio'
           unsigned long memcg_data = folio->memcg_data;
                                      ~~~~~^
   include/linux/memcontrol.h:399:55: note: forward declaration of 'struct folio'
   static inline struct mem_cgroup *__folio_memcg(struct folio *folio)
                                                         ^
>> include/linux/memcontrol.h:403:2: error: implicit declaration of function 'VM_BUG_ON_FOLIO' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio_slab(folio), folio);
           ^
>> include/linux/memcontrol.h:403:18: error: implicit declaration of function 'folio_slab' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio_slab(folio), folio);
                           ^
   include/linux/memcontrol.h:420:55: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline struct obj_cgroup *__folio_objcg(struct folio *folio)
                                                         ^
   include/linux/memcontrol.h:422:34: error: incomplete definition of type 'struct folio'
           unsigned long memcg_data = folio->memcg_data;
                                      ~~~~~^
   include/linux/memcontrol.h:420:55: note: forward declaration of 'struct folio'
   static inline struct obj_cgroup *__folio_objcg(struct folio *folio)
                                                         ^
   include/linux/memcontrol.h:424:2: error: implicit declaration of function 'VM_BUG_ON_FOLIO' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio_slab(folio), folio);
           ^
   include/linux/memcontrol.h:424:18: error: implicit declaration of function 'folio_slab' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio_slab(folio), folio);
                           ^
   include/linux/memcontrol.h:451:53: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline struct mem_cgroup *folio_memcg(struct folio *folio)
                                                       ^
   include/linux/memcontrol.h:453:23: error: incompatible pointer types passing 'struct folio *' to parameter of type 'struct folio *' [-Werror,-Wincompatible-pointer-types]
           if (folio_memcg_kmem(folio))
                                ^~~~~
   include/linux/memcontrol.h:375:51: note: passing argument to parameter 'folio' here
   static inline bool folio_memcg_kmem(struct folio *folio);
                                                     ^
   include/linux/memcontrol.h:454:41: error: incompatible pointer types passing 'struct folio *' to parameter of type 'struct folio *' [-Werror,-Wincompatible-pointer-types]
                   return obj_cgroup_memcg(__folio_objcg(folio));
                                                         ^~~~~
   include/linux/memcontrol.h:420:62: note: passing argument to parameter 'folio' here
   static inline struct obj_cgroup *__folio_objcg(struct folio *folio)
                                                                ^
   include/linux/memcontrol.h:456:24: error: incompatible pointer types passing 'struct folio *' to parameter of type 'struct folio *' [-Werror,-Wincompatible-pointer-types]
                   return __folio_memcg(folio);
                                        ^~~~~
   include/linux/memcontrol.h:399:62: note: passing argument to parameter 'folio' here
   static inline struct mem_cgroup *__folio_memcg(struct folio *folio)
                                                                ^
   include/linux/memcontrol.h:461:21: error: implicit declaration of function 'page_folio' [-Werror,-Wimplicit-function-declaration]
           return folio_memcg(page_folio(page));
                              ^
   include/linux/memcontrol.h:461:21: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'struct folio *' [-Wint-conversion]
           return folio_memcg(page_folio(page));
                              ^~~~~~~~~~~~~~~~
   include/linux/memcontrol.h:451:60: note: passing argument to parameter 'folio' here
   static inline struct mem_cgroup *folio_memcg(struct folio *folio)
                                                              ^
   include/linux/memcontrol.h:541:44: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline bool folio_memcg_kmem(struct folio *folio)
                                              ^
   include/linux/memcontrol.h:541:20: error: conflicting types for 'folio_memcg_kmem'
   static inline bool folio_memcg_kmem(struct folio *folio)
                      ^
   include/linux/memcontrol.h:375:20: note: previous declaration is here
   static inline bool folio_memcg_kmem(struct folio *folio);
                      ^
   include/linux/memcontrol.h:543:35: error: incomplete definition of type 'struct folio'
           VM_BUG_ON_PGFLAGS(PageTail(&folio->page), &folio->page);
                                       ~~~~~^
   include/linux/mmdebug.h:76:60: note: expanded from macro 'VM_BUG_ON_PGFLAGS'
   #define VM_BUG_ON_PGFLAGS(cond, page) BUILD_BUG_ON_INVALID(cond)
                                                              ^~~~
   include/linux/build_bug.h:30:63: note: expanded from macro 'BUILD_BUG_ON_INVALID'
   #define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
                                                                 ^
   include/linux/memcontrol.h:541:44: note: forward declaration of 'struct folio'
   static inline bool folio_memcg_kmem(struct folio *folio)
                                              ^
   include/linux/memcontrol.h:544:2: error: implicit declaration of function 'VM_BUG_ON_FOLIO' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio->memcg_data & MEMCG_DATA_OBJCGS, folio);
           ^
   include/linux/memcontrol.h:544:23: error: incomplete definition of type 'struct folio'
           VM_BUG_ON_FOLIO(folio->memcg_data & MEMCG_DATA_OBJCGS, folio);
                           ~~~~~^
   include/linux/memcontrol.h:541:44: note: forward declaration of 'struct folio'
   static inline bool folio_memcg_kmem(struct folio *folio)
                                              ^
   include/linux/memcontrol.h:545:14: error: incomplete definition of type 'struct folio'
           return folio->memcg_data & MEMCG_DATA_KMEM;
                  ~~~~~^
   include/linux/memcontrol.h:541:44: note: forward declaration of 'struct folio'
   static inline bool folio_memcg_kmem(struct folio *folio)
                                              ^
   include/linux/memcontrol.h:607:26: error: implicit declaration of function 'page_folio' [-Werror,-Wimplicit-function-declaration]
           return folio_memcg_kmem(page_folio(page));
                                   ^
   include/linux/memcontrol.h:607:26: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'struct folio *' [-Wint-conversion]
           return folio_memcg_kmem(page_folio(page));
                                   ^~~~~~~~~~~~~~~~
   include/linux/memcontrol.h:375:51: note: passing argument to parameter 'folio' here
   static inline bool folio_memcg_kmem(struct folio *folio);
                                                     ^
   8 warnings and 17 errors generated.
   make[2]: *** [scripts/Makefile.build:117: arch/x86/kernel/asm-offsets.s] Error 1
   make[2]: Target '__build' not remade because of errors.
   make[1]: *** [Makefile:1235: prepare0] Error 2
   make[1]: Target 'modules_prepare' not remade because of errors.
   make: *** [Makefile:215: __sub-make] Error 2
   make: Target 'modules_prepare' not remade because of errors.
--
   In file included from arch/x86/kernel/asm-offsets.c:13:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:13:
   In file included from include/linux/cgroup.h:28:
   In file included from include/linux/cgroup-defs.h:22:
   In file included from include/linux/bpf-cgroup.h:5:
   In file included from include/linux/bpf.h:20:
   In file included from include/linux/kallsyms.h:12:
   include/linux/mm.h:1382:42: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline int folio_nid(const struct folio *folio)
                                            ^
   include/linux/mm.h:1384:27: error: incomplete definition of type 'struct folio'
           return page_to_nid(&folio->page);
                               ~~~~~^
   include/linux/mm.h:1382:42: note: forward declaration of 'struct folio'
   static inline int folio_nid(const struct folio *folio)
                                            ^
   In file included from arch/x86/kernel/asm-offsets.c:13:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   include/linux/memcontrol.h:375:44: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline bool folio_memcg_kmem(struct folio *folio);
                                              ^
   include/linux/memcontrol.h:399:55: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline struct mem_cgroup *__folio_memcg(struct folio *folio)
                                                         ^
>> include/linux/memcontrol.h:401:34: error: incomplete definition of type 'struct folio'
           unsigned long memcg_data = folio->memcg_data;
                                      ~~~~~^
   include/linux/memcontrol.h:399:55: note: forward declaration of 'struct folio'
   static inline struct mem_cgroup *__folio_memcg(struct folio *folio)
                                                         ^
>> include/linux/memcontrol.h:403:2: error: implicit declaration of function 'VM_BUG_ON_FOLIO' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio_slab(folio), folio);
           ^
>> include/linux/memcontrol.h:403:18: error: implicit declaration of function 'folio_slab' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio_slab(folio), folio);
                           ^
   include/linux/memcontrol.h:420:55: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline struct obj_cgroup *__folio_objcg(struct folio *folio)
                                                         ^
   include/linux/memcontrol.h:422:34: error: incomplete definition of type 'struct folio'
           unsigned long memcg_data = folio->memcg_data;
                                      ~~~~~^
   include/linux/memcontrol.h:420:55: note: forward declaration of 'struct folio'
   static inline struct obj_cgroup *__folio_objcg(struct folio *folio)
                                                         ^
   include/linux/memcontrol.h:424:2: error: implicit declaration of function 'VM_BUG_ON_FOLIO' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio_slab(folio), folio);
           ^
   include/linux/memcontrol.h:424:18: error: implicit declaration of function 'folio_slab' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio_slab(folio), folio);
                           ^
   include/linux/memcontrol.h:451:53: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline struct mem_cgroup *folio_memcg(struct folio *folio)
                                                       ^
   include/linux/memcontrol.h:453:23: error: incompatible pointer types passing 'struct folio *' to parameter of type 'struct folio *' [-Werror,-Wincompatible-pointer-types]
           if (folio_memcg_kmem(folio))
                                ^~~~~
   include/linux/memcontrol.h:375:51: note: passing argument to parameter 'folio' here
   static inline bool folio_memcg_kmem(struct folio *folio);
                                                     ^
   include/linux/memcontrol.h:454:41: error: incompatible pointer types passing 'struct folio *' to parameter of type 'struct folio *' [-Werror,-Wincompatible-pointer-types]
                   return obj_cgroup_memcg(__folio_objcg(folio));
                                                         ^~~~~
   include/linux/memcontrol.h:420:62: note: passing argument to parameter 'folio' here
   static inline struct obj_cgroup *__folio_objcg(struct folio *folio)
                                                                ^
   include/linux/memcontrol.h:456:24: error: incompatible pointer types passing 'struct folio *' to parameter of type 'struct folio *' [-Werror,-Wincompatible-pointer-types]
                   return __folio_memcg(folio);
                                        ^~~~~
   include/linux/memcontrol.h:399:62: note: passing argument to parameter 'folio' here
   static inline struct mem_cgroup *__folio_memcg(struct folio *folio)
                                                                ^
   include/linux/memcontrol.h:461:21: error: implicit declaration of function 'page_folio' [-Werror,-Wimplicit-function-declaration]
           return folio_memcg(page_folio(page));
                              ^
   include/linux/memcontrol.h:461:21: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'struct folio *' [-Wint-conversion]
           return folio_memcg(page_folio(page));
                              ^~~~~~~~~~~~~~~~
   include/linux/memcontrol.h:451:60: note: passing argument to parameter 'folio' here
   static inline struct mem_cgroup *folio_memcg(struct folio *folio)
                                                              ^
   include/linux/memcontrol.h:541:44: warning: declaration of 'struct folio' will not be visible outside of this function [-Wvisibility]
   static inline bool folio_memcg_kmem(struct folio *folio)
                                              ^
   include/linux/memcontrol.h:541:20: error: conflicting types for 'folio_memcg_kmem'
   static inline bool folio_memcg_kmem(struct folio *folio)
                      ^
   include/linux/memcontrol.h:375:20: note: previous declaration is here
   static inline bool folio_memcg_kmem(struct folio *folio);
                      ^
   include/linux/memcontrol.h:543:35: error: incomplete definition of type 'struct folio'
           VM_BUG_ON_PGFLAGS(PageTail(&folio->page), &folio->page);
                                       ~~~~~^
   include/linux/mmdebug.h:76:60: note: expanded from macro 'VM_BUG_ON_PGFLAGS'
   #define VM_BUG_ON_PGFLAGS(cond, page) BUILD_BUG_ON_INVALID(cond)
                                                              ^~~~
   include/linux/build_bug.h:30:63: note: expanded from macro 'BUILD_BUG_ON_INVALID'
   #define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
                                                                 ^
   include/linux/memcontrol.h:541:44: note: forward declaration of 'struct folio'
   static inline bool folio_memcg_kmem(struct folio *folio)
                                              ^
   include/linux/memcontrol.h:544:2: error: implicit declaration of function 'VM_BUG_ON_FOLIO' [-Werror,-Wimplicit-function-declaration]
           VM_BUG_ON_FOLIO(folio->memcg_data & MEMCG_DATA_OBJCGS, folio);
           ^
   include/linux/memcontrol.h:544:23: error: incomplete definition of type 'struct folio'
           VM_BUG_ON_FOLIO(folio->memcg_data & MEMCG_DATA_OBJCGS, folio);
                           ~~~~~^
   include/linux/memcontrol.h:541:44: note: forward declaration of 'struct folio'
   static inline bool folio_memcg_kmem(struct folio *folio)
                                              ^
   include/linux/memcontrol.h:545:14: error: incomplete definition of type 'struct folio'
           return folio->memcg_data & MEMCG_DATA_KMEM;
                  ~~~~~^
   include/linux/memcontrol.h:541:44: note: forward declaration of 'struct folio'
   static inline bool folio_memcg_kmem(struct folio *folio)
                                              ^
   include/linux/memcontrol.h:607:26: error: implicit declaration of function 'page_folio' [-Werror,-Wimplicit-function-declaration]
           return folio_memcg_kmem(page_folio(page));
                                   ^
   include/linux/memcontrol.h:607:26: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'struct folio *' [-Wint-conversion]
           return folio_memcg_kmem(page_folio(page));
                                   ^~~~~~~~~~~~~~~~
   include/linux/memcontrol.h:375:51: note: passing argument to parameter 'folio' here
   static inline bool folio_memcg_kmem(struct folio *folio);
                                                     ^
   8 warnings and 17 errors generated.
   make[2]: *** [scripts/Makefile.build:117: arch/x86/kernel/asm-offsets.s] Error 1
   make[2]: Target '__build' not remade because of errors.
   make[1]: *** [Makefile:1235: prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [Makefile:215: __sub-make] Error 2
   make: Target 'prepare' not remade because of errors.


vim +401 include/linux/memcontrol.h

   373	
   374	static inline bool PageMemcgKmem(struct page *page);
 > 375	static inline bool folio_memcg_kmem(struct folio *folio);
   376	
   377	/*
   378	 * After the initialization objcg->memcg is always pointing at
   379	 * a valid memcg, but can be atomically swapped to the parent memcg.
   380	 *
   381	 * The caller must ensure that the returned memcg won't be released:
   382	 * e.g. acquire the rcu_read_lock or css_set_lock.
   383	 */
   384	static inline struct mem_cgroup *obj_cgroup_memcg(struct obj_cgroup *objcg)
   385	{
   386		return READ_ONCE(objcg->memcg);
   387	}
   388	
   389	/*
   390	 * __folio_memcg - Get the memory cgroup associated with a non-kmem folio
   391	 * @folio: Pointer to the folio.
   392	 *
   393	 * Returns a pointer to the memory cgroup associated with the folio,
   394	 * or NULL. This function assumes that the folio is known to have a
   395	 * proper memory cgroup pointer. It's not safe to call this function
   396	 * against some type of folios, e.g. slab folios or ex-slab folios or
   397	 * kmem folios.
   398	 */
 > 399	static inline struct mem_cgroup *__folio_memcg(struct folio *folio)
   400	{
 > 401		unsigned long memcg_data = folio->memcg_data;
   402	
 > 403		VM_BUG_ON_FOLIO(folio_slab(folio), folio);
   404		VM_BUG_ON_FOLIO(memcg_data & MEMCG_DATA_OBJCGS, folio);
   405		VM_BUG_ON_FOLIO(memcg_data & MEMCG_DATA_KMEM, folio);
   406	
   407		return (struct mem_cgroup *)(memcg_data & ~MEMCG_DATA_FLAGS_MASK);
   408	}
   409	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Christoph Hellwig July 1, 2021, 7:12 a.m. UTC | #2
On Wed, Jun 30, 2021 at 05:00:22AM +0100, Matthew Wilcox (Oracle) wrote:
> memcg information is only stored in the head page, so the memcg
> subsystem needs to assure that all accesses are to the head page.
> The first step is converting page_memcg() to folio_memcg().
> 
> Retain page_memcg() as a wrapper around folio_memcg() and PageMemcgKmem()
> as a wrapper around folio_memcg_kmem() but convert __page_memcg() to
> __folio_memcg() and __page_objcg() to __folio_objcg().
> 
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
>  include/linux/memcontrol.h | 105 +++++++++++++++++++++----------------
>  mm/memcontrol.c            |  21 ++++----
>  2 files changed, 73 insertions(+), 53 deletions(-)
> 
> diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
> index 6d66037be646..92689fb2dab4 100644
> --- a/include/linux/memcontrol.h
> +++ b/include/linux/memcontrol.h
> @@ -372,6 +372,7 @@ enum page_memcg_data_flags {
>  #define MEMCG_DATA_FLAGS_MASK (__NR_MEMCG_DATA_FLAGS - 1)
>  
>  static inline bool PageMemcgKmem(struct page *page);
> +static inline bool folio_memcg_kmem(struct folio *folio);
>  
>  /*
>   * After the initialization objcg->memcg is always pointing at
> @@ -386,73 +387,78 @@ static inline struct mem_cgroup *obj_cgroup_memcg(struct obj_cgroup *objcg)
>  }
>  
>  /*
> - * __page_memcg - get the memory cgroup associated with a non-kmem page
> - * @page: a pointer to the page struct
> + * __folio_memcg - Get the memory cgroup associated with a non-kmem folio
> + * @folio: Pointer to the folio.
>   *
> - * Returns a pointer to the memory cgroup associated with the page,
> - * or NULL. This function assumes that the page is known to have a
> + * Returns a pointer to the memory cgroup associated with the folio,
> + * or NULL. 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 pages, e.g. slab pages or ex-slab pages or
> - * kmem pages.
> + * against some type of folios, e.g. slab folios or ex-slab folios or
> + * kmem folios.
>   */
> -static inline struct mem_cgroup *__page_memcg(struct page *page)
> +static inline struct mem_cgroup *__folio_memcg(struct folio *folio)
>  {
> -	unsigned long memcg_data = page->memcg_data;
> +	unsigned long memcg_data = folio->memcg_data;
>  
> -	VM_BUG_ON_PAGE(PageSlab(page), page);
> -	VM_BUG_ON_PAGE(memcg_data & MEMCG_DATA_OBJCGS, page);
> -	VM_BUG_ON_PAGE(memcg_data & MEMCG_DATA_KMEM, page);
> +	VM_BUG_ON_FOLIO(folio_slab(folio), folio);
> +	VM_BUG_ON_FOLIO(memcg_data & MEMCG_DATA_OBJCGS, folio);
> +	VM_BUG_ON_FOLIO(memcg_data & MEMCG_DATA_KMEM, folio);
>  
>  	return (struct mem_cgroup *)(memcg_data & ~MEMCG_DATA_FLAGS_MASK);
>  }
>  
>  /*
> - * __page_objcg - get the object cgroup associated with a kmem page
> - * @page: a pointer to the page struct
> + * __folio_objcg - get the object cgroup associated with a kmem folio.
> + * @folio: Pointer to the folio.
>   *
> - * Returns a pointer to the object cgroup associated with the page,
> - * or NULL. This function assumes that the page is known to have a
> + * Returns a pointer to the object cgroup associated with the folio,
> + * or NULL. This function assumes that the folio is known to have a
>   * proper object cgroup pointer. It's not safe to call this function
> - * against some type of pages, e.g. slab pages or ex-slab pages or
> - * LRU pages.
> + * against some type of folios, e.g. slab folios or ex-slab folios or
> + * LRU folios.
>   */
> -static inline struct obj_cgroup *__page_objcg(struct page *page)
> +static inline struct obj_cgroup *__folio_objcg(struct folio *folio)
>  {
> -	unsigned long memcg_data = page->memcg_data;
> +	unsigned long memcg_data = folio->memcg_data;
>  
> -	VM_BUG_ON_PAGE(PageSlab(page), page);
> -	VM_BUG_ON_PAGE(memcg_data & MEMCG_DATA_OBJCGS, page);
> -	VM_BUG_ON_PAGE(!(memcg_data & MEMCG_DATA_KMEM), page);
> +	VM_BUG_ON_FOLIO(folio_slab(folio), folio);
> +	VM_BUG_ON_FOLIO(memcg_data & MEMCG_DATA_OBJCGS, folio);
> +	VM_BUG_ON_FOLIO(!(memcg_data & MEMCG_DATA_KMEM), folio);
>  
>  	return (struct obj_cgroup *)(memcg_data & ~MEMCG_DATA_FLAGS_MASK);
>  }
>  
>  /*
> - * page_memcg - get the memory cgroup associated with a page
> - * @page: a pointer to the page struct
> + * folio_memcg - Get the memory cgroup associated with a folio.
> + * @folio: Pointer to the folio.
>   *
> - * Returns a pointer to the memory cgroup associated with the page,
> - * or NULL. This function assumes that the page is known to have a
> + * Returns a pointer to the memory cgroup associated with the folio,
> + * or NULL. 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 pages, e.g. slab pages or ex-slab pages.
> + * against some type of folios, e.g. slab folios or ex-slab folios.
>   *
> - * For a non-kmem page any of the following ensures page and memcg binding
> + * For a non-kmem folio any of the following ensures folio and memcg binding
>   * stability:
>   *
> - * - the page lock
> + * - the folio lock
>   * - LRU isolation
>   * - lock_page_memcg()
>   * - exclusive reference
>   *
> - * For a kmem page a caller should hold an rcu read lock to protect memcg
> - * associated with a kmem page from being released.
> + * For a kmem folio a caller should hold an rcu read lock to protect memcg
> + * associated with a kmem folio from being released.
>   */
> -static inline struct mem_cgroup *page_memcg(struct page *page)
> +static inline struct mem_cgroup *folio_memcg(struct folio *folio)
>  {
> -	if (PageMemcgKmem(page))
> -		return obj_cgroup_memcg(__page_objcg(page));
> +	if (folio_memcg_kmem(folio))
> +		return obj_cgroup_memcg(__folio_objcg(folio));
>  	else
> +		return __folio_memcg(folio);

Nit: it might be worth to drop the pointless else while you're at it.
therwise looks good:


Reviewed-by: Christoph Hellwig <hch@lst.de>
diff mbox series

Patch

diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 6d66037be646..92689fb2dab4 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -372,6 +372,7 @@  enum page_memcg_data_flags {
 #define MEMCG_DATA_FLAGS_MASK (__NR_MEMCG_DATA_FLAGS - 1)
 
 static inline bool PageMemcgKmem(struct page *page);
+static inline bool folio_memcg_kmem(struct folio *folio);
 
 /*
  * After the initialization objcg->memcg is always pointing at
@@ -386,73 +387,78 @@  static inline struct mem_cgroup *obj_cgroup_memcg(struct obj_cgroup *objcg)
 }
 
 /*
- * __page_memcg - get the memory cgroup associated with a non-kmem page
- * @page: a pointer to the page struct
+ * __folio_memcg - Get the memory cgroup associated with a non-kmem folio
+ * @folio: Pointer to the folio.
  *
- * Returns a pointer to the memory cgroup associated with the page,
- * or NULL. This function assumes that the page is known to have a
+ * Returns a pointer to the memory cgroup associated with the folio,
+ * or NULL. 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 pages, e.g. slab pages or ex-slab pages or
- * kmem pages.
+ * against some type of folios, e.g. slab folios or ex-slab folios or
+ * kmem folios.
  */
-static inline struct mem_cgroup *__page_memcg(struct page *page)
+static inline struct mem_cgroup *__folio_memcg(struct folio *folio)
 {
-	unsigned long memcg_data = page->memcg_data;
+	unsigned long memcg_data = folio->memcg_data;
 
-	VM_BUG_ON_PAGE(PageSlab(page), page);
-	VM_BUG_ON_PAGE(memcg_data & MEMCG_DATA_OBJCGS, page);
-	VM_BUG_ON_PAGE(memcg_data & MEMCG_DATA_KMEM, page);
+	VM_BUG_ON_FOLIO(folio_slab(folio), folio);
+	VM_BUG_ON_FOLIO(memcg_data & MEMCG_DATA_OBJCGS, folio);
+	VM_BUG_ON_FOLIO(memcg_data & MEMCG_DATA_KMEM, folio);
 
 	return (struct mem_cgroup *)(memcg_data & ~MEMCG_DATA_FLAGS_MASK);
 }
 
 /*
- * __page_objcg - get the object cgroup associated with a kmem page
- * @page: a pointer to the page struct
+ * __folio_objcg - get the object cgroup associated with a kmem folio.
+ * @folio: Pointer to the folio.
  *
- * Returns a pointer to the object cgroup associated with the page,
- * or NULL. This function assumes that the page is known to have a
+ * Returns a pointer to the object cgroup associated with the folio,
+ * or NULL. This function assumes that the folio is known to have a
  * proper object cgroup pointer. It's not safe to call this function
- * against some type of pages, e.g. slab pages or ex-slab pages or
- * LRU pages.
+ * against some type of folios, e.g. slab folios or ex-slab folios or
+ * LRU folios.
  */
-static inline struct obj_cgroup *__page_objcg(struct page *page)
+static inline struct obj_cgroup *__folio_objcg(struct folio *folio)
 {
-	unsigned long memcg_data = page->memcg_data;
+	unsigned long memcg_data = folio->memcg_data;
 
-	VM_BUG_ON_PAGE(PageSlab(page), page);
-	VM_BUG_ON_PAGE(memcg_data & MEMCG_DATA_OBJCGS, page);
-	VM_BUG_ON_PAGE(!(memcg_data & MEMCG_DATA_KMEM), page);
+	VM_BUG_ON_FOLIO(folio_slab(folio), folio);
+	VM_BUG_ON_FOLIO(memcg_data & MEMCG_DATA_OBJCGS, folio);
+	VM_BUG_ON_FOLIO(!(memcg_data & MEMCG_DATA_KMEM), folio);
 
 	return (struct obj_cgroup *)(memcg_data & ~MEMCG_DATA_FLAGS_MASK);
 }
 
 /*
- * page_memcg - get the memory cgroup associated with a page
- * @page: a pointer to the page struct
+ * folio_memcg - Get the memory cgroup associated with a folio.
+ * @folio: Pointer to the folio.
  *
- * Returns a pointer to the memory cgroup associated with the page,
- * or NULL. This function assumes that the page is known to have a
+ * Returns a pointer to the memory cgroup associated with the folio,
+ * or NULL. 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 pages, e.g. slab pages or ex-slab pages.
+ * against some type of folios, e.g. slab folios or ex-slab folios.
  *
- * For a non-kmem page any of the following ensures page and memcg binding
+ * For a non-kmem folio any of the following ensures folio and memcg binding
  * stability:
  *
- * - the page lock
+ * - the folio lock
  * - LRU isolation
  * - lock_page_memcg()
  * - exclusive reference
  *
- * For a kmem page a caller should hold an rcu read lock to protect memcg
- * associated with a kmem page from being released.
+ * For a kmem folio a caller should hold an rcu read lock to protect memcg
+ * associated with a kmem folio from being released.
  */
-static inline struct mem_cgroup *page_memcg(struct page *page)
+static inline struct mem_cgroup *folio_memcg(struct folio *folio)
 {
-	if (PageMemcgKmem(page))
-		return obj_cgroup_memcg(__page_objcg(page));
+	if (folio_memcg_kmem(folio))
+		return obj_cgroup_memcg(__folio_objcg(folio));
 	else
-		return __page_memcg(page);
+		return __folio_memcg(folio);
+}
+
+static inline struct mem_cgroup *page_memcg(struct page *page)
+{
+	return folio_memcg(page_folio(page));
 }
 
 /*
@@ -525,17 +531,18 @@  static inline struct mem_cgroup *page_memcg_check(struct page *page)
 
 #ifdef CONFIG_MEMCG_KMEM
 /*
- * PageMemcgKmem - check if the page has MemcgKmem flag set
- * @page: a pointer to the page struct
+ * folio_memcg_kmem - Check if the folio has the memcg_kmem flag set.
+ * @folio: Pointer to the folio.
  *
- * Checks if the page has MemcgKmem flag set. The caller must ensure that
- * the page has an associated memory cgroup. It's not safe to call this function
- * against some types of pages, e.g. slab pages.
+ * Checks if the folio has MemcgKmem flag set. The caller must ensure
+ * that the folio has an associated memory cgroup. It's not safe to call
+ * this function against some types of folios, e.g. slab folios.
  */
-static inline bool PageMemcgKmem(struct page *page)
+static inline bool folio_memcg_kmem(struct folio *folio)
 {
-	VM_BUG_ON_PAGE(page->memcg_data & MEMCG_DATA_OBJCGS, page);
-	return page->memcg_data & MEMCG_DATA_KMEM;
+	VM_BUG_ON_PGFLAGS(PageTail(&folio->page), &folio->page);
+	VM_BUG_ON_FOLIO(folio->memcg_data & MEMCG_DATA_OBJCGS, folio);
+	return folio->memcg_data & MEMCG_DATA_KMEM;
 }
 
 /*
@@ -579,7 +586,7 @@  static inline struct obj_cgroup **page_objcgs_check(struct page *page)
 }
 
 #else
-static inline bool PageMemcgKmem(struct page *page)
+static inline bool folio_memcg_kmem(struct folio *folio)
 {
 	return false;
 }
@@ -595,6 +602,11 @@  static inline struct obj_cgroup **page_objcgs_check(struct page *page)
 }
 #endif
 
+static inline bool PageMemcgKmem(struct page *page)
+{
+	return folio_memcg_kmem(page_folio(page));
+}
+
 static __always_inline bool memcg_stat_item_in_bytes(int idx)
 {
 	if (idx == MEMCG_PERCPU_B)
@@ -1122,6 +1134,11 @@  static inline struct mem_cgroup *page_memcg_check(struct page *page)
 	return NULL;
 }
 
+static inline bool folio_memcg_kmem(struct folio *folio)
+{
+	return false;
+}
+
 static inline bool PageMemcgKmem(struct page *page)
 {
 	return false;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 5d143d46a8a4..f369bbaf584b 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3045,15 +3045,16 @@  int __memcg_kmem_charge_page(struct page *page, gfp_t gfp, int order)
  */
 void __memcg_kmem_uncharge_page(struct page *page, int order)
 {
+	struct folio *folio = page_folio(page);
 	struct obj_cgroup *objcg;
 	unsigned int nr_pages = 1 << order;
 
-	if (!PageMemcgKmem(page))
+	if (!folio_memcg_kmem(folio))
 		return;
 
-	objcg = __page_objcg(page);
+	objcg = __folio_objcg(folio);
 	obj_cgroup_uncharge_pages(objcg, nr_pages);
-	page->memcg_data = 0;
+	folio->memcg_data = 0;
 	obj_cgroup_put(objcg);
 }
 
@@ -3285,17 +3286,18 @@  void obj_cgroup_uncharge(struct obj_cgroup *objcg, size_t size)
  */
 void split_page_memcg(struct page *head, unsigned int nr)
 {
-	struct mem_cgroup *memcg = page_memcg(head);
+	struct folio *folio = page_folio(head);
+	struct mem_cgroup *memcg = folio_memcg(folio);
 	int i;
 
 	if (mem_cgroup_disabled() || !memcg)
 		return;
 
 	for (i = 1; i < nr; i++)
-		head[i].memcg_data = head->memcg_data;
+		folio_page(folio, i)->memcg_data = folio->memcg_data;
 
-	if (PageMemcgKmem(head))
-		obj_cgroup_get_many(__page_objcg(head), nr - 1);
+	if (folio_memcg_kmem(folio))
+		obj_cgroup_get_many(__folio_objcg(folio), nr - 1);
 	else
 		css_get_many(&memcg->css, nr - 1);
 }
@@ -6830,6 +6832,7 @@  static void uncharge_batch(const struct uncharge_gather *ug)
 
 static void uncharge_page(struct page *page, struct uncharge_gather *ug)
 {
+	struct folio *folio = page_folio(page);
 	unsigned long nr_pages;
 	struct mem_cgroup *memcg;
 	struct obj_cgroup *objcg;
@@ -6843,14 +6846,14 @@  static void uncharge_page(struct page *page, struct uncharge_gather *ug)
 	 * exclusive access to the page.
 	 */
 	if (use_objcg) {
-		objcg = __page_objcg(page);
+		objcg = __folio_objcg(folio);
 		/*
 		 * This get matches the put at the end of the function and
 		 * kmem pages do not hold memcg references anymore.
 		 */
 		memcg = get_mem_cgroup_from_objcg(objcg);
 	} else {
-		memcg = __page_memcg(page);
+		memcg = __folio_memcg(folio);
 	}
 
 	if (!memcg)