Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.5:Update
crash.23106
crash-Fix-kmem-i-option-on-Linux-5.9-rc1-and-la...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File crash-Fix-kmem-i-option-on-Linux-5.9-rc1-and-later-kernels.patch of Package crash.23106
From 37d9a33dbc3cfd68265fccea551ed5be53da1acd Mon Sep 17 00:00:00 2001 From: Kazuhito Hagio <k-hagio-ab@nec.com> Date: Mon, 17 Aug 2020 23:40:14 +0000 Subject: [PATCH] Fix "kmem -i" option on Linux 5.9-rc1 and later kernels References: bsc#1179970 ltc#188981 Upstream: 7.2.9 Git-commit: 37d9a33dbc3cfd68265fccea551ed5be53da1acd 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@nec.com> --- defs.h | 2 ++ memory.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ symbols.c | 4 ++++ 3 files changed, 64 insertions(+) diff --git a/defs.h b/defs.h --- a/defs.h +++ b/defs.h @@ -2075,6 +2075,8 @@ struct offset_table { /* stash of commonly-used offsets */ long device_private_knode_class; long timerqueue_head_rb_root; long rb_root_cached_rb_leftmost; + 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); @@ -8651,6 +8658,57 @@ nr_blockdev_pages(void) return nrpages; } +/* + * 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 311fdb7df29e..4babb50bea7f 100644 --- a/symbols.c +++ b/symbols.c @@ -9468,6 +9468,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)); @@ -9504,6 +9506,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)); -- 2.26.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor