linux/fs/proc
Johannes Weiner 91cdcd8d62 mm: zswap: optimize zswap pool size tracking
Profiling the munmap() of a zswapped memory region shows 60% of the total
cycles currently going into updating the zswap_pool_total_size.

There are three consumers of this counter:
- store, to enforce the globally configured pool limit
- meminfo & debugfs, to report the size to the user
- shrink, to determine the batch size for each cycle

Instead of aggregating everytime an entry enters or exits the zswap
pool, aggregate the value from the zpools on-demand:

- Stores aggregate the counter anyway upon success. Aggregating to
  check the limit instead is the same amount of work.

- Meminfo & debugfs might benefit somewhat from a pre-aggregated
  counter, but aren't exactly hotpaths.

- Shrinking can aggregate once for every cycle instead of doing it for
  every freed entry. As the shrinker might work on tens or hundreds of
  objects per scan cycle, this is a large reduction in aggregations.

The paths that benefit dramatically are swapin, swapoff, and unmaps. 
There could be millions of pages being processed until somebody asks for
the pool size again.  This eliminates the pool size updates from those
paths entirely.

Top profile entries for a 24G range munmap(), before:

    38.54%  zswap-unmap  [kernel.kallsyms]  [k] zs_zpool_total_size
    12.51%  zswap-unmap  [kernel.kallsyms]  [k] zpool_get_total_size
     9.10%  zswap-unmap  [kernel.kallsyms]  [k] zswap_update_total_size
     2.95%  zswap-unmap  [kernel.kallsyms]  [k] obj_cgroup_uncharge_zswap
     2.88%  zswap-unmap  [kernel.kallsyms]  [k] __slab_free
     2.86%  zswap-unmap  [kernel.kallsyms]  [k] xas_store

and after:

     7.70%  zswap-unmap  [kernel.kallsyms]  [k] __slab_free
     7.16%  zswap-unmap  [kernel.kallsyms]  [k] obj_cgroup_uncharge_zswap
     6.74%  zswap-unmap  [kernel.kallsyms]  [k] xas_store

It was also briefly considered to move to a single atomic in zswap
that is updated by the backends, since zswap only cares about the sum
of all pools anyway. However, zram directly needs per-pool information
out of zsmalloc. To keep the backend from having to update two atomics
every time, I opted for the lazy aggregation instead for now.

Link: https://lkml.kernel.org/r/20240312153901.3441-1-hannes@cmpxchg.org
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Yosry Ahmed <yosryahmed@google.com>
Reviewed-by: Chengming Zhou <chengming.zhou@linux.dev>
Reviewed-by: Nhat Pham <nphamcs@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2024-04-25 20:55:47 -07:00
..
array.c fs/proc: do_task_stat: use sig->stats_lock to gather the threads/children stats 2024-02-07 21:20:33 -08:00
base.c procfs: move dropping pde and pid from ->evict_inode() to ->free_inode() 2024-02-25 02:10:32 -05:00
bootconfig.c fs/proc: Skip bootloader comment if no embedded kernel parameters 2024-04-09 23:36:18 +09:00
cmdline.c proc: mark /proc/cmdline as permanent 2023-02-02 22:50:02 -08:00
consoles.c proc: consoles: use console_list_lock for list iteration 2022-12-02 11:25:02 +01:00
cpuinfo.c x86/aperfmperf: Replace aperfmperf_get_khz() 2022-04-27 20:22:19 +02:00
devices.c proc: mark more files as permanent 2022-10-03 14:21:45 -07:00
fd.c file: convert to SLAB_TYPESAFE_BY_RCU 2023-10-19 11:02:48 +02:00
fd.h fs: port ->permission() to pass mnt_idmap 2023-01-19 09:24:28 +01:00
generic.c fs: pass the request_mask to generic_fillattr 2023-08-09 08:56:36 +02:00
inode.c vfs-6.9.misc 2024-03-11 09:38:17 -07:00
internal.h proc: Use lsmids instead of lsm names for attrs 2023-11-12 22:54:42 -05:00
interrupts.c
Kconfig crash: split vmcoreinfo exporting code out from crash_core.c 2024-02-23 17:48:22 -08:00
kcore.c crash: split vmcoreinfo exporting code out from crash_core.c 2024-02-23 17:48:22 -08:00
kmsg.c printk changes for 6.1 2022-10-10 11:24:19 -07:00
loadavg.c proc: mark more files as permanent 2022-10-03 14:21:45 -07:00
Makefile kbuild: make -Woverride-init warnings more consistent 2024-03-31 11:32:26 +09:00
meminfo.c mm: zswap: optimize zswap pool size tracking 2024-04-25 20:55:47 -07:00
namespaces.c
nommu.c fs: create helper file_user_path() for user displayed mapped file path 2023-10-19 11:03:15 +02:00
page.c mm: support page_mapcount() on page_has_type() pages 2024-04-24 19:34:26 -07:00
proc_net.c v6.6-fs.proc.uapi 2023-08-28 11:43:19 -07:00
proc_sysctl.c misc cleanups (the part that hadn't been picked by individual fs trees) 2024-01-11 20:23:50 -08:00
proc_tty.c proc: delete unused <linux/uaccess.h> includes 2022-07-17 17:31:39 -07:00
root.c procfs: make freeing proc_fs_info rcu-delayed 2024-02-25 02:10:32 -05:00
self.c proc: convert to new timestamp accessors 2023-10-18 14:08:26 +02:00
softirqs.c proc: mark more files as permanent 2022-10-03 14:21:45 -07:00
stat.c proc/stat: remove arch_idle_time() 2023-04-18 16:39:33 -07:00
task_mmu.c fs/proc/task_mmu.c: add_to_pagemap: remove useless parameter addr 2024-02-21 16:00:04 -08:00
task_nommu.c vfs-6.7.misc 2023-10-30 09:14:19 -10:00
thread_self.c proc: convert to new timestamp accessors 2023-10-18 14:08:26 +02:00
uptime.c proc: mark more files as permanent 2022-10-03 14:21:45 -07:00
util.c
version.c proc: mark more files as permanent 2022-10-03 14:21:45 -07:00
vmcore.c proc/vmcore: fix signedness bug in read_from_oldmem() 2023-07-27 13:07:05 -07:00