[Crash-utility] [PATCH] Fix "kmem -i" option on Linux 5.9-rc1 and later kernels

lijiang lijiang at redhat.com
Thu Sep 10 02:07:25 UTC 2020


在 2020年08月18日 07:40, HAGIO KAZUHITO(萩尾 一仁) 写道:
> On kernels that contain commit 1008fe6dc36d ("block: remove the all_bdevs
> list"), without the patch, the "kmem -i" option fails halfway with the
> error message 'kmem: cannot resolve: "all_bdevs"'.
> 
> Signed-off-by: Kazuhito Hagio <k-hagio-ab at nec.com>
> ---
> # sorry, resending this because I sent with inappropriate setting..
> 
>  defs.h    |  2 ++
>  memory.c  | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  symbols.c |  4 ++++
>  3 files changed, 64 insertions(+)
> 
> diff --git a/defs.h b/defs.h
> index 17e98763362b..dfc09bc86618 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -2089,6 +2089,8 @@ struct offset_table {                    /* stash of commonly-used offsets */
>  	long size_class_size;
>  	long gendisk_private_data;
>  	long zram_table_entry;
> +	long super_block_s_inodes;
> +	long inode_i_sb_list;
>  };
>  
>  struct size_table {         /* stash of commonly-used sizes */
> diff --git a/memory.c b/memory.c
> index 2bea1288251a..c951827162cb 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -252,6 +252,7 @@ static ulonglong get_vm_flags(char *);
>  static void PG_reserved_flag_init(void);
>  static void PG_slab_flag_init(void);
>  static ulong nr_blockdev_pages(void);
> +static ulong nr_blockdev_pages_v2(void);
>  void sparse_mem_init(void);
>  void dump_mem_sections(int);
>  void dump_memory_blocks(int);
> @@ -501,6 +502,9 @@ vm_init(void)
>  	if (INVALID_MEMBER(address_space_nrpages))
>  		MEMBER_OFFSET_INIT(address_space_nrpages, "address_space", "__nrpages");
>  
> +	MEMBER_OFFSET_INIT(super_block_s_inodes, "super_block", "s_inodes");
> +	MEMBER_OFFSET_INIT(inode_i_sb_list, "inode", "i_sb_list");
> +
>  	MEMBER_OFFSET_INIT(gendisk_major, "gendisk", "major");
>  	MEMBER_OFFSET_INIT(gendisk_fops, "gendisk", "fops");
>  	MEMBER_OFFSET_INIT(gendisk_disk_name, "gendisk", "disk_name");
> @@ -8608,6 +8612,9 @@ nr_blockdev_pages(void)
>  	ulong nrpages;
>  	char *block_device_buf, *inode_buf, *address_space_buf;
>  
> +	if (!kernel_symbol_exists("all_bdevs"))
> +		return nr_blockdev_pages_v2();
> +
>          ld = &list_data;
>          BZERO(ld, sizeof(struct list_data));
>  	get_symbol_data("all_bdevs", sizeof(void *), &ld->start);
> @@ -8652,6 +8659,57 @@ nr_blockdev_pages(void)
>  } 
>  
>  /*
> + *  Emulate 5.9 nr_blockdev_pages() function.
> + */
> +static ulong
> +nr_blockdev_pages_v2(void)
> +{
> +	struct list_data list_data, *ld;
> +	ulong bd_sb, address_space;
> +	ulong nrpages;
> +	int i, inode_count;
> +	char *inode_buf, *address_space_buf;
> +
> +	ld = &list_data;
> +	BZERO(ld, sizeof(struct list_data));
> +
> +	get_symbol_data("blockdev_superblock", sizeof(void *), &bd_sb);
> +	readmem(bd_sb + OFFSET(super_block_s_inodes), KVADDR, &ld->start,
> +		sizeof(ulong), "blockdev_superblock.s_inodes", FAULT_ON_ERROR);
> +
> +	if (empty_list(ld->start))
> +		return 0;
> +	ld->flags |= LIST_ALLOCATE;
> +	ld->end = bd_sb + OFFSET(super_block_s_inodes);
> +	ld->list_head_offset = OFFSET(inode_i_sb_list);
> +
> +	inode_buf = GETBUF(SIZE(inode));
> +	address_space_buf = GETBUF(SIZE(address_space));
> +
> +	inode_count = do_list(ld);
> +
> +	/*
> +	 *  go through the s_inodes list, emulating:
> +	 *
> +	 *      ret += inode->i_mapping->nrpages;
> +	 */
> +	for (i = nrpages = 0; i < inode_count; i++) {
> +		readmem(ld->list_ptr[i], KVADDR, inode_buf, SIZE(inode), "inode buffer",
> +			FAULT_ON_ERROR);
> +		address_space = ULONG(inode_buf + OFFSET(inode_i_mapping));
> +		readmem(address_space, KVADDR, address_space_buf, SIZE(address_space),
> +			"address_space buffer", FAULT_ON_ERROR);
> +		nrpages += ULONG(address_space_buf + OFFSET(address_space_nrpages));
> +	}
> +
> +	FREEBUF(ld->list_ptr);
> +	FREEBUF(inode_buf);
> +	FREEBUF(address_space_buf);
> +
> +	return nrpages;
> +}
> +
> +/*
>   *  dump_vmlist() displays information from the vmlist.
>   */
>  
> diff --git a/symbols.c b/symbols.c
> index 2fecaee093a2..123ed00913e1 100644
> --- a/symbols.c
> +++ b/symbols.c
> @@ -9452,6 +9452,8 @@ dump_offset_table(char *spec, ulong makestruct)
>  		OFFSET(inode_i_fop)); 
>  	fprintf(fp, "               inode_i_mapping: %ld\n",
>  		OFFSET(inode_i_mapping));
> +	fprintf(fp, "               inode_i_sb_list: %ld\n",
> +		OFFSET(inode_i_sb_list));
>  
>          fprintf(fp, "             vfsmount_mnt_next: %ld\n", 
>  		OFFSET(vfsmount_mnt_next));
> @@ -9488,6 +9490,8 @@ dump_offset_table(char *spec, ulong makestruct)
>  		OFFSET(super_block_s_type));
>          fprintf(fp, "           super_block_s_files: %ld\n", 
>  		OFFSET(super_block_s_files));
> +	fprintf(fp, "          super_block_s_inodes: %ld\n",
> +		OFFSET(super_block_s_inodes));
>  
>  	fprintf(fp, "               nlm_file_f_file: %ld\n",
>  		OFFSET(nlm_file_f_file));
> 

Thanks for the patch.

Acked-by: Lianbo Jiang <lijiang at redhat.com>




More information about the Crash-utility mailing list