Re: [PATCH] vmstat: don't auto expand the sysfs files

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 11 Dec 2023, Pasha Tatashin wrote:

> Whenever a new fields are added one of the following: node_stat_item
> numa_stat_item zone_stat_item, the /sys/devices/system/node/nodeX/vmstat
> files are auto expanded.
> 
> This is a problem, as sysfs files should be only one value per file.

Does this patch address the one-value-per-file issue?  (I think that ship 
has sailed for vmstat.)

/sys/devices/system/node/nodeX/vmstat has been documented as a stable ABI 
in Linux for 13 years.

That said, the contents of the file has not been documented so I assume 
it's "whatever stats make sense for the current implementation of the 
Linux VM".

> Also, once a field is exported via vmstat it is hard to remove it as
> there could be user applications that rely on this field. This is why
> we still cary "nr_unstable 0" in /proc/vmstat that is not used.
> 

Implementations change over time, so this would be expected.

I'm assuming, but perhaps incorrectly, that userspace won't crash if 
nr_unstable just don't appear anymore.  That whoever is using it would 
just assume that it's zero if it doesn't appear.

So I think we need to answer the question of: are the *contents* of files 
like vmstat that are heavily dependent on implementation level details 
really part of a stable ABI that people can expect will carry on forever?  

> Also, since vmstat is auto-expanded the fields are not documented, so
> users do not know whether they are counted in bytes/kilobytes/pages,
> and the exact meaning of these fields.
> 

I think that's actually intended since there can also be ones that are 
event counters.  I don't think any fields in vmstat are intended to be 
long-term sacred stable ABIs.

> Modify the code that the new fields do not auto-expand the vmstat in
> sysfs. The new fields can still be exported via their own files in
> sysfs, and be properly documents.
> 
> vmstat values are named using vmstat_text[] array, which contains names
> for zone_stat, numa_stat, node_stat, lru_list, writeback_stat,
> vm_event.
> 
> Change vmstat_text[] to be an array of structs that contain two values:
> name, and flags.  The new flags field contains information whether to
> show stat value in vmstat files in sysfs (VMSTAT_SHOW_SYSFS), and in
> procfs (VMSTAT_SHOW_PROCFS). The comment above VMSTAT_SHOW_SYSFS
> documents that this flag should not be used for new stat values when
> they are added.
> 
> Signed-off-by: Pasha Tatashin <pasha.tatashin@xxxxxxxxxx>
> ---
>  drivers/base/node.c    |  34 ++--
>  include/linux/vmstat.h |  48 ++++--
>  mm/vmstat.c            | 377 +++++++++++++++++++++--------------------
>  3 files changed, 244 insertions(+), 215 deletions(-)
> 
> Examples of the projects that are currently under review and that add new
> fields to the one of the vmstat items:
> 
> [1] mm: report per-page metadata information
> https://lore.kernel.org/all/20231205223118.3575485-1-souravpanda@xxxxxxxxxx
> 
> [2] IOMMU memory observability
> https://lore.kernel.org/all/20231130201504.2322355-1-pasha.tatashin@xxxxxxxxxx
> 
> Greg KH has been requesting for these files not to grow:
> https://lore.kernel.org/all/2023120731-deception-handmade-8d49@gregkh
> 
> diff --git a/drivers/base/node.c b/drivers/base/node.c
> index 493d533f8375..f139d7ab58f5 100644
> --- a/drivers/base/node.c
> +++ b/drivers/base/node.c
> @@ -520,26 +520,34 @@ static ssize_t node_read_vmstat(struct device *dev,
>  	int i;
>  	int len = 0;
>  
> -	for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
> -		len += sysfs_emit_at(buf, len, "%s %lu\n",
> -				     zone_stat_name(i),
> -				     sum_zone_node_page_state(nid, i));
> +	for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) {
> +		if (vmstat_text[ZONE_STAT_NAME_IDX(i)].flags & VMSTAT_SHOW_SYSFS) {
> +			len += sysfs_emit_at(buf, len, "%s %lu\n",
> +					     zone_stat_name(i),
> +					     sum_zone_node_page_state(nid, i));
> +		}
> +	}
>  
>  #ifdef CONFIG_NUMA
>  	fold_vm_numa_events();
> -	for (i = 0; i < NR_VM_NUMA_EVENT_ITEMS; i++)
> -		len += sysfs_emit_at(buf, len, "%s %lu\n",
> -				     numa_stat_name(i),
> -				     sum_zone_numa_event_state(nid, i));
> +	for (i = 0; i < NR_VM_NUMA_EVENT_ITEMS; i++) {
> +		if (vmstat_text[NUMA_STAT_NAME_IDX(i)].flags & VMSTAT_SHOW_SYSFS) {
> +			len += sysfs_emit_at(buf, len, "%s %lu\n",
> +					     numa_stat_name(i),
> +					     sum_zone_numa_event_state(nid, i));
> +		}
> +	}
>  
>  #endif
>  	for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) {
> -		unsigned long pages = node_page_state_pages(pgdat, i);
> +		if (vmstat_text[NODE_STAT_NAME_IDX(i)].flags & VMSTAT_SHOW_SYSFS) {
> +			unsigned long pages = node_page_state_pages(pgdat, i);
>  
> -		if (vmstat_item_print_in_thp(i))
> -			pages /= HPAGE_PMD_NR;
> -		len += sysfs_emit_at(buf, len, "%s %lu\n", node_stat_name(i),
> -				     pages);
> +			if (vmstat_item_print_in_thp(i))
> +				pages /= HPAGE_PMD_NR;
> +			len += sysfs_emit_at(buf, len, "%s %lu\n", node_stat_name(i),
> +					     pages);
> +		}
>  	}
>  
>  	return len;
> diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
> index fed855bae6d8..2dd46daf69aa 100644
> --- a/include/linux/vmstat.h
> +++ b/include/linux/vmstat.h
> @@ -495,26 +495,44 @@ static inline void __mod_zone_freepage_state(struct zone *zone, int nr_pages,
>  		__mod_zone_page_state(zone, NR_FREE_CMA_PAGES, nr_pages);
>  }
>  
> -extern const char * const vmstat_text[];
>  
> +/*
> + * Show this stat in /sys/devices/system/node/nodeX/vmstat
> + * IMPORTANT: Don't use this flag for new stats, as the right way to output only
> + * one stat per file in sysfs. Instead, add new individual sysfs files for new
> + * stats, and document them in Documentation/ABI/TYPE/sysfs-new_field_name.
> + */
> +#define VMSTAT_SHOW_SYSFS	BIT(0)
> +
> +/* Show this stat in /proc/vmstat */
> +#define VMSTAT_SHOW_PROCFS	BIT(1)
> +
> +struct vmstat_text {
> +	const char *name;
> +	char flags;
> +};
> +
> +extern const struct vmstat_text vmstat_text[];
> +
> +#define ZONE_STAT_NAME_IDX(item)	((int)(item))
>  static inline const char *zone_stat_name(enum zone_stat_item item)
>  {
> -	return vmstat_text[item];
> +	return vmstat_text[ZONE_STAT_NAME_IDX(item)].name;
>  }
>  
>  #ifdef CONFIG_NUMA
> +#define NUMA_STAT_NAME_IDX(item)	(NR_VM_ZONE_STAT_ITEMS + (int)(item))
>  static inline const char *numa_stat_name(enum numa_stat_item item)
>  {
> -	return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
> -			   item];
> +	return vmstat_text[NUMA_STAT_NAME_IDX(item)].name;
>  }
>  #endif /* CONFIG_NUMA */
>  
> +#define NODE_STAT_NAME_IDX(item)	(NR_VM_NUMA_EVENT_ITEMS +	\
> +	NR_VM_ZONE_STAT_ITEMS + (int)(item))
>  static inline const char *node_stat_name(enum node_stat_item item)
>  {
> -	return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
> -			   NR_VM_NUMA_EVENT_ITEMS +
> -			   item];
> +	return vmstat_text[NODE_STAT_NAME_IDX(item)].name;
>  }
>  
>  static inline const char *lru_list_name(enum lru_list lru)
> @@ -522,22 +540,20 @@ static inline const char *lru_list_name(enum lru_list lru)
>  	return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
>  }
>  
> +#define WRITEBACK_STAT_NAME_IDX(item)	(NR_VM_NODE_STAT_ITEMS +	\
> +	NR_VM_NUMA_EVENT_ITEMS + NR_VM_ZONE_STAT_ITEMS + (int)(item))
>  static inline const char *writeback_stat_name(enum writeback_stat_item item)
>  {
> -	return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
> -			   NR_VM_NUMA_EVENT_ITEMS +
> -			   NR_VM_NODE_STAT_ITEMS +
> -			   item];
> +	return vmstat_text[WRITEBACK_STAT_NAME_IDX(item)].name;
>  }
>  
>  #if defined(CONFIG_VM_EVENT_COUNTERS) || defined(CONFIG_MEMCG)
> +#define VM_EVENT_NAME_IDX(item)	(NR_VM_WRITEBACK_STAT_ITEMS +		\
> +	NR_VM_NODE_STAT_ITEMS + NR_VM_NUMA_EVENT_ITEMS +		\
> +	NR_VM_ZONE_STAT_ITEMS + (int)(item))
>  static inline const char *vm_event_name(enum vm_event_item item)
>  {
> -	return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
> -			   NR_VM_NUMA_EVENT_ITEMS +
> -			   NR_VM_NODE_STAT_ITEMS +
> -			   NR_VM_WRITEBACK_STAT_ITEMS +
> -			   item];
> +	return vmstat_text[VM_EVENT_NAME_IDX(item)].name;
>  }
>  #endif /* CONFIG_VM_EVENT_COUNTERS || CONFIG_MEMCG */
>  
> diff --git a/mm/vmstat.c b/mm/vmstat.c
> index 359460deb377..691d8c90b4ac 100644
> --- a/mm/vmstat.c
> +++ b/mm/vmstat.c
> @@ -1142,278 +1142,281 @@ int fragmentation_index(struct zone *zone, unsigned int order)
>  #if defined(CONFIG_PROC_FS) || defined(CONFIG_SYSFS) || \
>      defined(CONFIG_NUMA) || defined(CONFIG_MEMCG)
>  #ifdef CONFIG_ZONE_DMA
> -#define TEXT_FOR_DMA(xx) xx "_dma",
> +#define TEXT_FOR_DMA(xx) {xx "_dma",	VMSTAT_SHOW_PROCFS},
>  #else
>  #define TEXT_FOR_DMA(xx)
>  #endif
>  
>  #ifdef CONFIG_ZONE_DMA32
> -#define TEXT_FOR_DMA32(xx) xx "_dma32",
> +#define TEXT_FOR_DMA32(xx) {xx "_dma32",	VMSTAT_SHOW_PROCFS},
>  #else
>  #define TEXT_FOR_DMA32(xx)
>  #endif
>  
>  #ifdef CONFIG_HIGHMEM
> -#define TEXT_FOR_HIGHMEM(xx) xx "_high",
> +#define TEXT_FOR_HIGHMEM(xx) {xx "_high",	VMSTAT_SHOW_PROCFS},
>  #else
>  #define TEXT_FOR_HIGHMEM(xx)
>  #endif
>  
>  #ifdef CONFIG_ZONE_DEVICE
> -#define TEXT_FOR_DEVICE(xx) xx "_device",
> +#define TEXT_FOR_DEVICE(xx) {xx "_device",	VMSTAT_SHOW_PROCFS},
>  #else
>  #define TEXT_FOR_DEVICE(xx)
>  #endif
>  
> -#define TEXTS_FOR_ZONES(xx) TEXT_FOR_DMA(xx) TEXT_FOR_DMA32(xx) xx "_normal", \
> -					TEXT_FOR_HIGHMEM(xx) xx "_movable", \
> -					TEXT_FOR_DEVICE(xx)
> +#define TEXT_FOR_NORMAL(xx) {xx "_normal", VMSTAT_SHOW_PROCFS},
> +#define TEXT_FOR_MOVABLE(xx) {xx "_movable", VMSTAT_SHOW_PROCFS},
>  
> -const char * const vmstat_text[] = {
> +#define TEXTS_FOR_ZONES(xx) TEXT_FOR_DMA(xx) TEXT_FOR_DMA32(xx)		\
> +	TEXT_FOR_NORMAL(xx) TEXT_FOR_HIGHMEM(xx) TEXT_FOR_MOVABLE(xx)	\
> +	TEXT_FOR_DEVICE(xx)
> +
> +const struct vmstat_text vmstat_text[] = {
>  	/* enum zone_stat_item counters */
> -	"nr_free_pages",
> -	"nr_zone_inactive_anon",
> -	"nr_zone_active_anon",
> -	"nr_zone_inactive_file",
> -	"nr_zone_active_file",
> -	"nr_zone_unevictable",
> -	"nr_zone_write_pending",
> -	"nr_mlock",
> -	"nr_bounce",
> +	{"nr_free_pages",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_zone_inactive_anon",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_zone_active_anon",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_zone_inactive_file",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_zone_active_file",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_zone_unevictable",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_zone_write_pending",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_mlock",			VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_bounce",			VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
>  #if IS_ENABLED(CONFIG_ZSMALLOC)
> -	"nr_zspages",
> +	{"nr_zspages",			VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
>  #endif
> -	"nr_free_cma",
> +	{"nr_free_cma",			VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
>  #ifdef CONFIG_UNACCEPTED_MEMORY
> -	"nr_unaccepted",
> +	{"nr_unaccepted",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
>  #endif
>  
>  	/* enum numa_stat_item counters */
>  #ifdef CONFIG_NUMA
> -	"numa_hit",
> -	"numa_miss",
> -	"numa_foreign",
> -	"numa_interleave",
> -	"numa_local",
> -	"numa_other",
> +	{"numa_hit",			VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"numa_miss",			VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"numa_foreign",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"numa_interleave",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"numa_local",			VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"numa_other",			VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
>  #endif
> -
>  	/* enum node_stat_item counters */
> -	"nr_inactive_anon",
> -	"nr_active_anon",
> -	"nr_inactive_file",
> -	"nr_active_file",
> -	"nr_unevictable",
> -	"nr_slab_reclaimable",
> -	"nr_slab_unreclaimable",
> -	"nr_isolated_anon",
> -	"nr_isolated_file",
> -	"workingset_nodes",
> -	"workingset_refault_anon",
> -	"workingset_refault_file",
> -	"workingset_activate_anon",
> -	"workingset_activate_file",
> -	"workingset_restore_anon",
> -	"workingset_restore_file",
> -	"workingset_nodereclaim",
> -	"nr_anon_pages",
> -	"nr_mapped",
> -	"nr_file_pages",
> -	"nr_dirty",
> -	"nr_writeback",
> -	"nr_writeback_temp",
> -	"nr_shmem",
> -	"nr_shmem_hugepages",
> -	"nr_shmem_pmdmapped",
> -	"nr_file_hugepages",
> -	"nr_file_pmdmapped",
> -	"nr_anon_transparent_hugepages",
> -	"nr_vmscan_write",
> -	"nr_vmscan_immediate_reclaim",
> -	"nr_dirtied",
> -	"nr_written",
> -	"nr_throttled_written",
> -	"nr_kernel_misc_reclaimable",
> -	"nr_foll_pin_acquired",
> -	"nr_foll_pin_released",
> -	"nr_kernel_stack",
> +	{"nr_inactive_anon",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_active_anon",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_inactive_file",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_active_file",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_unevictable",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_slab_reclaimable",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_slab_unreclaimable",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_isolated_anon",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_isolated_file",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"workingset_nodes",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"workingset_refault_anon",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"workingset_refault_file",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"workingset_activate_anon",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"workingset_activate_file",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"workingset_restore_anon",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"workingset_restore_file",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"workingset_nodereclaim",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_anon_pages",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_mapped",			VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_file_pages",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_dirty",			VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_writeback",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_writeback_temp",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_shmem",			VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_shmem_hugepages",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_shmem_pmdmapped",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_file_hugepages",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_file_pmdmapped",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_anon_transparent_hugepages", VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_vmscan_write",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_vmscan_immediate_reclaim",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_dirtied",			VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_written",			VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_throttled_written",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_kernel_misc_reclaimable",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_foll_pin_acquired",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_foll_pin_released",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_kernel_stack",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
>  #if IS_ENABLED(CONFIG_SHADOW_CALL_STACK)
> -	"nr_shadow_call_stack",
> +	{"nr_shadow_call_stack",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
>  #endif
> -	"nr_page_table_pages",
> -	"nr_sec_page_table_pages",
> +	{"nr_page_table_pages",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"nr_sec_page_table_pages",	VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
>  #ifdef CONFIG_SWAP
> -	"nr_swapcached",
> +	{"nr_swapcached",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
>  #endif
>  #ifdef CONFIG_NUMA_BALANCING
> -	"pgpromote_success",
> -	"pgpromote_candidate",
> +	{"pgpromote_success",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
> +	{"pgpromote_candidate",		VMSTAT_SHOW_PROCFS | VMSTAT_SHOW_SYSFS},
>  #endif
>  
>  	/* enum writeback_stat_item counters */
> -	"nr_dirty_threshold",
> -	"nr_dirty_background_threshold",
> +	{"nr_dirty_threshold",		VMSTAT_SHOW_PROCFS},
> +	{"nr_dirty_background_threshold", VMSTAT_SHOW_PROCFS},
>  
>  #if defined(CONFIG_VM_EVENT_COUNTERS) || defined(CONFIG_MEMCG)
>  	/* enum vm_event_item counters */
> -	"pgpgin",
> -	"pgpgout",
> -	"pswpin",
> -	"pswpout",
> +	{"pgpgin",			VMSTAT_SHOW_PROCFS},
> +	{"pgpgout",			VMSTAT_SHOW_PROCFS},
> +	{"pswpin",			VMSTAT_SHOW_PROCFS},
> +	{"pswpout",			VMSTAT_SHOW_PROCFS},
>  
>  	TEXTS_FOR_ZONES("pgalloc")
>  	TEXTS_FOR_ZONES("allocstall")
>  	TEXTS_FOR_ZONES("pgskip")
>  
> -	"pgfree",
> -	"pgactivate",
> -	"pgdeactivate",
> -	"pglazyfree",
> -
> -	"pgfault",
> -	"pgmajfault",
> -	"pglazyfreed",
> -
> -	"pgrefill",
> -	"pgreuse",
> -	"pgsteal_kswapd",
> -	"pgsteal_direct",
> -	"pgsteal_khugepaged",
> -	"pgdemote_kswapd",
> -	"pgdemote_direct",
> -	"pgdemote_khugepaged",
> -	"pgscan_kswapd",
> -	"pgscan_direct",
> -	"pgscan_khugepaged",
> -	"pgscan_direct_throttle",
> -	"pgscan_anon",
> -	"pgscan_file",
> -	"pgsteal_anon",
> -	"pgsteal_file",
> +	{"pgfree",			VMSTAT_SHOW_PROCFS},
> +	{"pgactivate",			VMSTAT_SHOW_PROCFS},
> +	{"pgdeactivate",		VMSTAT_SHOW_PROCFS},
> +	{"pglazyfree",			VMSTAT_SHOW_PROCFS},
> +
> +	{"pgfault",			VMSTAT_SHOW_PROCFS},
> +	{"pgmajfault",			VMSTAT_SHOW_PROCFS},
> +	{"pglazyfreed",			VMSTAT_SHOW_PROCFS},
> +
> +	{"pgrefill",			VMSTAT_SHOW_PROCFS},
> +	{"pgreuse",			VMSTAT_SHOW_PROCFS},
> +	{"pgsteal_kswapd",		VMSTAT_SHOW_PROCFS},
> +	{"pgsteal_direct",		VMSTAT_SHOW_PROCFS},
> +	{"pgsteal_khugepaged",		VMSTAT_SHOW_PROCFS},
> +	{"pgdemote_kswapd",		VMSTAT_SHOW_PROCFS},
> +	{"pgdemote_direct",		VMSTAT_SHOW_PROCFS},
> +	{"pgdemote_khugepaged",		VMSTAT_SHOW_PROCFS},
> +	{"pgscan_kswapd",		VMSTAT_SHOW_PROCFS},
> +	{"pgscan_direct",		VMSTAT_SHOW_PROCFS},
> +	{"pgscan_khugepaged",		VMSTAT_SHOW_PROCFS},
> +	{"pgscan_direct_throttle",	VMSTAT_SHOW_PROCFS},
> +	{"pgscan_anon",			VMSTAT_SHOW_PROCFS},
> +	{"pgscan_file",			VMSTAT_SHOW_PROCFS},
> +	{"pgsteal_anon",		VMSTAT_SHOW_PROCFS},
> +	{"pgsteal_file",		VMSTAT_SHOW_PROCFS},
>  
>  #ifdef CONFIG_NUMA
> -	"zone_reclaim_failed",
> +	{"zone_reclaim_failed",		VMSTAT_SHOW_PROCFS},
>  #endif
> -	"pginodesteal",
> -	"slabs_scanned",
> -	"kswapd_inodesteal",
> -	"kswapd_low_wmark_hit_quickly",
> -	"kswapd_high_wmark_hit_quickly",
> -	"pageoutrun",
> +	{"pginodesteal",		VMSTAT_SHOW_PROCFS},
> +	{"slabs_scanned",		VMSTAT_SHOW_PROCFS},
> +	{"kswapd_inodesteal",		VMSTAT_SHOW_PROCFS},
> +	{"kswapd_low_wmark_hit_quickly", VMSTAT_SHOW_PROCFS},
> +	{"kswapd_high_wmark_hit_quickly", VMSTAT_SHOW_PROCFS},
> +	{"pageoutrun",			VMSTAT_SHOW_PROCFS},
>  
> -	"pgrotated",
> +	{"pgrotated",			VMSTAT_SHOW_PROCFS},
>  
> -	"drop_pagecache",
> -	"drop_slab",
> -	"oom_kill",
> +	{"drop_pagecache",		VMSTAT_SHOW_PROCFS},
> +	{"drop_slab",			VMSTAT_SHOW_PROCFS},
> +	{"oom_kill",			VMSTAT_SHOW_PROCFS},
>  
>  #ifdef CONFIG_NUMA_BALANCING
> -	"numa_pte_updates",
> -	"numa_huge_pte_updates",
> -	"numa_hint_faults",
> -	"numa_hint_faults_local",
> -	"numa_pages_migrated",
> +	{"numa_pte_updates",		VMSTAT_SHOW_PROCFS},
> +	{"numa_huge_pte_updates",	VMSTAT_SHOW_PROCFS},
> +	{"numa_hint_faults",		VMSTAT_SHOW_PROCFS},
> +	{"numa_hint_faults_local",	VMSTAT_SHOW_PROCFS},
> +	{"numa_pages_migrated",		VMSTAT_SHOW_PROCFS},
>  #endif
>  #ifdef CONFIG_MIGRATION
> -	"pgmigrate_success",
> -	"pgmigrate_fail",
> -	"thp_migration_success",
> -	"thp_migration_fail",
> -	"thp_migration_split",
> +	{"pgmigrate_success",		VMSTAT_SHOW_PROCFS},
> +	{"pgmigrate_fail",		VMSTAT_SHOW_PROCFS},
> +	{"thp_migration_success",	VMSTAT_SHOW_PROCFS},
> +	{"thp_migration_fail",		VMSTAT_SHOW_PROCFS},
> +	{"thp_migration_split",		VMSTAT_SHOW_PROCFS},
>  #endif
>  #ifdef CONFIG_COMPACTION
> -	"compact_migrate_scanned",
> -	"compact_free_scanned",
> -	"compact_isolated",
> -	"compact_stall",
> -	"compact_fail",
> -	"compact_success",
> -	"compact_daemon_wake",
> -	"compact_daemon_migrate_scanned",
> -	"compact_daemon_free_scanned",
> +	{"compact_migrate_scanned",	VMSTAT_SHOW_PROCFS},
> +	{"compact_free_scanned",	VMSTAT_SHOW_PROCFS},
> +	{"compact_isolated",		VMSTAT_SHOW_PROCFS},
> +	{"compact_stall",		VMSTAT_SHOW_PROCFS},
> +	{"compact_fail",		VMSTAT_SHOW_PROCFS},
> +	{"compact_success",		VMSTAT_SHOW_PROCFS},
> +	{"compact_daemon_wake",		VMSTAT_SHOW_PROCFS},
> +	{"compact_daemon_migrate_scanned", VMSTAT_SHOW_PROCFS},
> +	{"compact_daemon_free_scanned",	VMSTAT_SHOW_PROCFS},
>  #endif
>  
>  #ifdef CONFIG_HUGETLB_PAGE
> -	"htlb_buddy_alloc_success",
> -	"htlb_buddy_alloc_fail",
> +	{"htlb_buddy_alloc_success",	VMSTAT_SHOW_PROCFS},
> +	{"htlb_buddy_alloc_fail",	VMSTAT_SHOW_PROCFS},
>  #endif
>  #ifdef CONFIG_CMA
> -	"cma_alloc_success",
> -	"cma_alloc_fail",
> +	{"cma_alloc_success",		VMSTAT_SHOW_PROCFS},
> +	{"cma_alloc_fail",		VMSTAT_SHOW_PROCFS},
>  #endif
> -	"unevictable_pgs_culled",
> -	"unevictable_pgs_scanned",
> -	"unevictable_pgs_rescued",
> -	"unevictable_pgs_mlocked",
> -	"unevictable_pgs_munlocked",
> -	"unevictable_pgs_cleared",
> -	"unevictable_pgs_stranded",
> +	{"unevictable_pgs_culled",	VMSTAT_SHOW_PROCFS},
> +	{"unevictable_pgs_scanned",	VMSTAT_SHOW_PROCFS},
> +	{"unevictable_pgs_rescued",	VMSTAT_SHOW_PROCFS},
> +	{"unevictable_pgs_mlocked",	VMSTAT_SHOW_PROCFS},
> +	{"unevictable_pgs_munlocked",	VMSTAT_SHOW_PROCFS},
> +	{"unevictable_pgs_cleared",	VMSTAT_SHOW_PROCFS},
> +	{"unevictable_pgs_stranded",	VMSTAT_SHOW_PROCFS},
>  
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
> -	"thp_fault_alloc",
> -	"thp_fault_fallback",
> -	"thp_fault_fallback_charge",
> -	"thp_collapse_alloc",
> -	"thp_collapse_alloc_failed",
> -	"thp_file_alloc",
> -	"thp_file_fallback",
> -	"thp_file_fallback_charge",
> -	"thp_file_mapped",
> -	"thp_split_page",
> -	"thp_split_page_failed",
> -	"thp_deferred_split_page",
> -	"thp_split_pmd",
> -	"thp_scan_exceed_none_pte",
> -	"thp_scan_exceed_swap_pte",
> -	"thp_scan_exceed_share_pte",
> +	{"thp_fault_alloc",		VMSTAT_SHOW_PROCFS},
> +	{"thp_fault_fallback",		VMSTAT_SHOW_PROCFS},
> +	{"thp_fault_fallback_charge",	VMSTAT_SHOW_PROCFS},
> +	{"thp_collapse_alloc",		VMSTAT_SHOW_PROCFS},
> +	{"thp_collapse_alloc_failed",	VMSTAT_SHOW_PROCFS},
> +	{"thp_file_alloc",		VMSTAT_SHOW_PROCFS},
> +	{"thp_file_fallback",		VMSTAT_SHOW_PROCFS},
> +	{"thp_file_fallback_charge",	VMSTAT_SHOW_PROCFS},
> +	{"thp_file_mapped",		VMSTAT_SHOW_PROCFS},
> +	{"thp_split_page",		VMSTAT_SHOW_PROCFS},
> +	{"thp_split_page_failed",	VMSTAT_SHOW_PROCFS},
> +	{"thp_deferred_split_page",	VMSTAT_SHOW_PROCFS},
> +	{"thp_split_pmd",		VMSTAT_SHOW_PROCFS},
> +	{"thp_scan_exceed_none_pte",	VMSTAT_SHOW_PROCFS},
> +	{"thp_scan_exceed_swap_pte",	VMSTAT_SHOW_PROCFS},
> +	{"thp_scan_exceed_share_pte",	VMSTAT_SHOW_PROCFS},
>  #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
> -	"thp_split_pud",
> +	{"thp_split_pud",		VMSTAT_SHOW_PROCFS},
>  #endif
> -	"thp_zero_page_alloc",
> -	"thp_zero_page_alloc_failed",
> -	"thp_swpout",
> -	"thp_swpout_fallback",
> +	{"thp_zero_page_alloc",		VMSTAT_SHOW_PROCFS},
> +	{"thp_zero_page_alloc_failed",	VMSTAT_SHOW_PROCFS},
> +	{"thp_swpout",			VMSTAT_SHOW_PROCFS},
> +	{"thp_swpout_fallback",		VMSTAT_SHOW_PROCFS},
>  #endif
>  #ifdef CONFIG_MEMORY_BALLOON
> -	"balloon_inflate",
> -	"balloon_deflate",
> +	{"balloon_inflate",		VMSTAT_SHOW_PROCFS},
> +	{"balloon_deflate",		VMSTAT_SHOW_PROCFS},
>  #ifdef CONFIG_BALLOON_COMPACTION
> -	"balloon_migrate",
> +	{"balloon_migrate",		VMSTAT_SHOW_PROCFS},
>  #endif
>  #endif /* CONFIG_MEMORY_BALLOON */
>  #ifdef CONFIG_DEBUG_TLBFLUSH
> -	"nr_tlb_remote_flush",
> -	"nr_tlb_remote_flush_received",
> -	"nr_tlb_local_flush_all",
> -	"nr_tlb_local_flush_one",
> +	{"nr_tlb_remote_flush",		VMSTAT_SHOW_PROCFS},
> +	{"nr_tlb_remote_flush_received", VMSTAT_SHOW_PROCFS},
> +	{"nr_tlb_local_flush_all",	VMSTAT_SHOW_PROCFS},
> +	{"nr_tlb_local_flush_one",	VMSTAT_SHOW_PROCFS},
>  #endif /* CONFIG_DEBUG_TLBFLUSH */
>  
>  #ifdef CONFIG_SWAP
> -	"swap_ra",
> -	"swap_ra_hit",
> +	{"swap_ra",			VMSTAT_SHOW_PROCFS},
> +	{"swap_ra_hit",			VMSTAT_SHOW_PROCFS},
>  #ifdef CONFIG_KSM
> -	"ksm_swpin_copy",
> +	{"ksm_swpin_copy",		VMSTAT_SHOW_PROCFS},
>  #endif
>  #endif
>  #ifdef CONFIG_KSM
> -	"cow_ksm",
> +	{"cow_ksm",			VMSTAT_SHOW_PROCFS},
>  #endif
>  #ifdef CONFIG_ZSWAP
> -	"zswpin",
> -	"zswpout",
> +	{"zswpin",			VMSTAT_SHOW_PROCFS},
> +	{"zswpout",			VMSTAT_SHOW_PROCFS},
>  #endif
>  #ifdef CONFIG_X86
> -	"direct_map_level2_splits",
> -	"direct_map_level3_splits",
> +	{"direct_map_level2_splits",	VMSTAT_SHOW_PROCFS},
> +	{"direct_map_level3_splits",	VMSTAT_SHOW_PROCFS},
>  #endif
>  #ifdef CONFIG_PER_VMA_LOCK_STATS
> -	"vma_lock_success",
> -	"vma_lock_abort",
> -	"vma_lock_retry",
> -	"vma_lock_miss",
> +	{"vma_lock_success",		VMSTAT_SHOW_PROCFS},
> +	{"vma_lock_abort",		VMSTAT_SHOW_PROCFS},
> +	{"vma_lock_retry",		VMSTAT_SHOW_PROCFS},
> +	{"vma_lock_miss",		VMSTAT_SHOW_PROCFS},
>  #endif
>  #endif /* CONFIG_VM_EVENT_COUNTERS || CONFIG_MEMCG */
>  };
> +
>  #endif /* CONFIG_PROC_FS || CONFIG_SYSFS || CONFIG_NUMA || CONFIG_MEMCG */
>  
>  #if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_COMPACTION)) || \
> @@ -1845,9 +1848,11 @@ static int vmstat_show(struct seq_file *m, void *arg)
>  	unsigned long *l = arg;
>  	unsigned long off = l - (unsigned long *)m->private;
>  
> -	seq_puts(m, vmstat_text[off]);
> -	seq_put_decimal_ull(m, " ", *l);
> -	seq_putc(m, '\n');
> +	if (vmstat_text[off].flags & VMSTAT_SHOW_PROCFS) {
> +		seq_puts(m, vmstat_text[off].name);
> +		seq_put_decimal_ull(m, " ", *l);
> +		seq_putc(m, '\n');
> +	}
>  
>  	if (off == NR_VMSTAT_ITEMS - 1) {
>  		/*
> -- 
> 2.43.0.472.g3155946c3a-goog
> 
> 
> 




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux