mm: memcg: add THP swap out info for anonymous reclaim
Subsystems (7)
PATCH v3 1/1 mm: memcg: add THP swap out info for anonymous reclaim
From: Xin Hao <[email protected]>
At present, we support per-memcg reclaim strategy, however we do not know the number of transparent huge pages being reclaimed, as we know the transparent huge pages need to be splited before reclaim them, and they will bring some performance bottleneck effect. for example, when two memcg (A & B) are doing reclaim for anonymous pages at same time, and 'A' memcg is reclaiming a large number of transparent huge pages, we can better analyze that the performance bottleneck will be caused by 'A' memcg. therefore, in order to better analyze such problems, there add THP swap out info for per-memcg.
---
v2 -> v3
- Do little fix as Johannes Weiner suggestion.
- add 'thp_swpout' and 'thp_swpout_fallback' to Documentation/admin-guide/cgroup-v2.rst
v1 -> v2
- Do some fix as Johannes Weiner suggestion.
v2:
https://lore.kernel.org/linux-mm/20230912021727.61601-1-vernhao-1Nz4purKYjRBDgjK7y7TUQ@public.gmane.org/
v1:
https://lore.kernel.org/linux-mm/[email protected]/T/
Documentation/admin-guide/cgroup-v2.rst | 9 +++++++++ mm/memcontrol.c | 2 ++ mm/page_io.c | 8 ++++---- mm/vmscan.c | 1 + 4 files changed, 16 insertions(+), 4 deletions(-)
Documentation/admin-guide/cgroup-v2.rst +9 -0
@@ -1532,6 +1532,15 @@ PAGE_SIZE multiple when read back. collapsing an existing range of pages. This counter is not present when CONFIG_TRANSPARENT_HUGEPAGE is not set. + thp_swpout (npn) + Number of transparent hugepages which are swapout in one piece + without splitting. + + thp_swpout_fallback (npn) + Number of transparent hugepages which were split before swapout. + Usually because failed to allocate some continuous swap space + for the huge page. + memory.numa_stat A read-only nested-keyed file which exists on non-root cgroups.
mm/memcontrol.c +2 -0
@@ -704,6 +704,8 @@ static const unsigned int memcg_vm_event_stat[] = {#ifdef CONFIG_TRANSPARENT_HUGEPAGE THP_FAULT_ALLOC ,THP_COLLAPSE_ALLOC , +THP_SWPOUT , + THP_SWPOUT_FALLBACK, #endif };
mm/page_io.c +4 -4
@@ -208,8 +208,10 @@ int swap_writepage(struct page *page, struct writeback_control *wbc)static inline void count_swpout_vm_event (struct folio *folio) {#ifdef CONFIG_TRANSPARENT_HUGEPAGE -if (unlikely (folio_test_pmd_mappable (folio))) +if (unlikely (folio_test_pmd_mappable (folio))) { +count_memcg_folio_events (folio,THP_SWPOUT ,1 );count_vm_event (THP_SWPOUT ); + }#endif count_vm_events (PSWPOUT ,folio_nr_pages (folio)); }
@@ -278,9 +280,6 @@ static void sio_write_complete(struct kiocb *iocb, long ret)set_page_dirty (page);ClearPageReclaim (page); } - }else { -for (p =0 ; p < sio->pages; p++) -count_swpout_vm_event (page_folio (sio->bvec[p].bv_page)); }for (p =0 ; p < sio->pages; p++)
@@ -296,6 +295,7 @@ static void swap_writepage_fs(struct page *page, struct writeback_control *wbc)struct file *swap_file = sis->swap_file;loff_t pos =page_file_offset (page); +count_swpout_vm_event (page_folio (sio->bvec[p].bv_page));set_page_writeback (page);unlock_page (page);if (wbc->swap_plug)
mm/vmscan.c +1 -0
@@ -1227,6 +1227,7 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, folio_list)) goto activate_locked;#ifdef CONFIG_TRANSPARENT_HUGEPAGE +count_memcg_folio_events (folio,THP_SWPOUT_FALLBACK ,1 );count_vm_event (THP_SWPOUT_FALLBACK );#endif if (!add_to_swap (folio))
Signature · 1 line
2.42.0
Quoted 12 lines · Vern Hao
From: Xin Hao <[email protected]>
At present, we support per-memcg reclaim strategy, however we do not know the number of transparent huge pages being reclaimed, as we know the transparent huge pages need to be splited before reclaim them, and they will bring some performance bottleneck effect. for example, when two memcg (A & B) are doing reclaim for anonymous pages at same time, and 'A' memcg is reclaiming a large number of transparent huge pages, we can better analyze that the performance bottleneck will be caused by 'A' memcg. therefore, in order to better analyze such problems, there add THP swap out info for per-memcg.
Quoted 2 lines
Suggested-by Johannes Weiner <[email protected]>Signed-off-by Xin Hao <[email protected]>
kernel test robot
build botkernel test robot noticed the following build errors:
Hi Vern,
kernel test robot noticed the following build errors:
[auto build test ERROR on akpm-mm/mm-everything]
url: https://github.com/intel-lab-lkp/linux/commits/Vern-Hao/mm-memcg-add-THP-swap-out-info-for-anonymous-reclaim/20230914-005121 base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything patch link: https://lore.kernel.org/r/20230913164938.16918-1-vernhao%40tencent.com patch subject: [PATCH v3] mm: memcg: add THP swap out info for anonymous reclaim config: um-allnoconfig (https://download.01.org/0day-ci/archive/20230914/202309140314.DrcFvlZS-lkp-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org/config) compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230914/202309140314.DrcFvlZS-lkp-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org/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/202309140314.DrcFvlZS-lkp-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org/
All errors (new ones prefixed by >>):
In file included from mm/page_io.c:15:
In file included from include/linux/kernel_stat.h:9:
In file included from include/linux/interrupt.h:11:
In file included from include/linux/hardirq.h:11:
In file included from arch/um/include/asm/hardirq.h:5:
In file included from include/asm-generic/hardirq.h:17:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/um/include/asm/io.h:24:
include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
547 | val = __raw_readb(PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
560 | val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
| ~~~~~~~~~~ ^
include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
| ^
In file included from mm/page_io.c:15:
In file included from include/linux/kernel_stat.h:9:
In file included from include/linux/interrupt.h:11:
In file included from include/linux/hardirq.h:11:
In file included from arch/um/include/asm/hardirq.h:5:
In file included from include/asm-generic/hardirq.h:17:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/um/include/asm/io.h:24:
include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
573 | val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
| ~~~~~~~~~~ ^
include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
35 | #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
| ^
In file included from mm/page_io.c:15:
In file included from include/linux/kernel_stat.h:9:
In file included from include/linux/interrupt.h:11:
In file included from include/linux/hardirq.h:11:
In file included from arch/um/include/asm/hardirq.h:5:
In file included from include/asm-generic/hardirq.h:17:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/um/include/asm/io.h:24:
include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
584 | __raw_writeb(value, PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
594 | __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
604 | __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:692:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
692 | readsb(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:700:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
700 | readsw(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:708:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
708 | readsl(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:717:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
717 | writesb(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:726:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
726 | writesw(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:735:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
735 | writesl(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
>> mm/page_io.c:298:45: error: use of undeclared identifier 'p'
298 | count_swpout_vm_event(page_folio(sio->bvec[p].bv_page));
| ^12 warnings and 1 error generated.
vim +/p +298 mm/page_io.c
290
291 static void swap_writepage_fs(struct page *page, struct writeback_control *wbc)
292 {
293 struct swap_iocb *sio = NULL;
294 struct swap_info_struct *sis = page_swap_info(page);
295 struct file *swap_file = sis->swap_file;
296 loff_t pos = page_file_offset(page);
297
> 298 count_swpout_vm_event(page_folio(sio->bvec[p].bv_page));
299 set_page_writeback(page);
300 unlock_page(page);
301 if (wbc->swap_plug)
302 sio = *wbc->swap_plug;
303 if (sio) {
304 if (sio->iocb.ki_filp != swap_file ||
305 sio->iocb.ki_pos + sio->len != pos) {
306 swap_write_unplug(sio);
307 sio = NULL;
308 }
309 }
310 if (!sio) {
311 sio = mempool_alloc(sio_pool, GFP_NOIO);
312 init_sync_kiocb(&sio->iocb, swap_file);
313 sio->iocb.ki_complete = sio_write_complete;
314 sio->iocb.ki_pos = pos;
315 sio->pages = 0;
316 sio->len = 0;
317 }
318 bvec_set_page(&sio->bvec[sio->pages], page, thp_size(page), 0);
319 sio->len += thp_size(page);
320 sio->pages += 1;
321 if (sio->pages == ARRAY_SIZE(sio->bvec) || !wbc->swap_plug) {
322 swap_write_unplug(sio);
323 sio = NULL;
324 }
325 if (wbc->swap_plug)
326 *wbc->swap_plug = sio;
327 }
328
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Johannes Weiner
maintainermm/page_io.c static void swap_writepage_fs(struct page *page, struct writeback_control *wbc) · line 298
Quoted 5 lines · Vern Hao
mm/page_io.c +1
-0@@ -296,6 +295,7 @@ static void swap_writepage_fs(struct page *page, struct writeback_control *wbc)struct file *swap_file = sis->swap_file;loff_t pos =page_file_offset (page); +count_swpout_vm_event (page_folio (sio->bvec[p].bv_page));
Argh, this should be
count_swpout_vm_event(page_folio(page));