Re: [PATCH] Fix for "search" command failing in maple tree kernel

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

 



On 2023/02/22 15:32, Tao Liu wrote:
> Kernel with maple tree enabled doesn't have mmap as a member of mm_struct[1],
> so OFFSET(mm_struct_mmap) case needed to be handled differently for
> maple tree kernel.
> 
> Before:
> crash> search -u a
> 
> search: invalid structure member offset: mm_struct_mmap
>          FILE: memory.c  LINE: 14255  FUNCTION: address_space_start()

Thank you for the patch.
My test did not have the "search -u", added it...

> 
> [crash] error trace: 549500 => 548fff => 5f1c91 => 5f1c13
> 
>    5f1c13: OFFSET_verify.part.36+51
>    5f1c91: OFFSET_verify+49
>    548fff: address_space_start+106
>    549500: cmd_search+855
> 
> search: invalid structure member offset: mm_struct_mmap
>          FILE: memory.c  LINE: 14255  FUNCTION: address_space_start()
> 
> After:
> crash> search -u a
> 7ffea63e6440: a
> 
> [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=763ecb035029f500d7e6dc99acd1ad299b7726a1
> 
> Signed-off-by: Tao Liu <ltao@xxxxxxxxxx>
> ---
>   memory.c | 87 ++++++++++++++++++++++++++++++++++++++++++--------------
>   1 file changed, 65 insertions(+), 22 deletions(-)
> 
> diff --git a/memory.c b/memory.c
> index d9cd616..63ea9f4 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -14245,14 +14245,28 @@ vaddr_type(ulong vaddr, struct task_context *tc)
>   static int
>   address_space_start(struct task_context *tc, ulong *addr)
>   {
> -        ulong vma;
> +	ulong mm_mt, entry_num, i, vma = 0;
>           char *vma_buf;
> +	struct list_pair *entry_list;
>   
>           if (!tc->mm_struct)
>                   return FALSE;
>   
> -        fill_mm_struct(tc->mm_struct);
> -        vma = ULONG(tt->mm_struct + OFFSET(mm_struct_mmap));
> +	if (INVALID_MEMBER(mm_struct_mmap) && VALID_MEMBER(mm_struct_mm_mt)) {
> +		mm_mt = tc->mm_struct + OFFSET(mm_struct_mm_mt);
> +		entry_num = do_maple_tree(mm_mt, MAPLE_TREE_COUNT, NULL);
> +		entry_list = (struct list_pair *)GETBUF(entry_num * sizeof(struct list_pair));
> +		do_maple_tree(mm_mt, MAPLE_TREE_GATHER, entry_list);
> +		for (i = 0; i < entry_num; i++) {
> +			if (!!(vma = (ulong)entry_list[i].value))
> +				break;
> +		}
> +		FREEBUF(entry_list);
> +	} else {
> +		fill_mm_struct(tc->mm_struct);
> +		vma = ULONG(tt->mm_struct + OFFSET(mm_struct_mmap));
> +	}
> +
>           if (!vma)
>                   return FALSE;
>   	vma_buf = fill_vma_cache(vma);
> @@ -15491,6 +15505,30 @@ search_physical(struct searchinfo *si)
>   	FREEBUF(pagebuf);
>   }
>   
> +static bool
> +check_vma(ulong vma, ulong vaddr, ulong *vm_next, ulong *nextvaddr)
> +{
> +	char *vma_buf;
> +	ulong vm_start, vm_end;
> +
> +	vma_buf = fill_vma_cache(vma);
> +
> +	vm_start = ULONG(vma_buf + OFFSET(vm_area_struct_vm_start));
> +	vm_end = ULONG(vma_buf + OFFSET(vm_area_struct_vm_end));
> +	if (vm_next)
> +		*vm_next = ULONG(vma_buf + OFFSET(vm_area_struct_vm_next));
> +
> +	if (vaddr <= vm_start) {
> +		*nextvaddr = vm_start;
> +		return TRUE;
> +	}
> +
> +	if ((vaddr > vm_start) && (vaddr < vm_end)) {
> +		*nextvaddr = vaddr;
> +		return TRUE;
> +	}
> +	return FALSE;
> +}
>   
>   /*
>    *  Return the next mapped user virtual address page that comes after
> @@ -15503,34 +15541,39 @@ next_upage(struct task_context *tc, ulong vaddr, ulong *nextvaddr)
>   	char *vma_buf;
>           ulong vm_start, vm_end;
>   	ulong vm_next;

cc -c -g -DX86_64 -DLZO -DSNAPPY -DZSTD -DGDB_10_2  memory.c -Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector -Wformat-security
memory.c: In function ‘next_upage’:
memory.c:15542:25: warning: unused variable ‘vm_end’ [-Wunused-variable]
          ulong vm_start, vm_end;
                          ^~~~~~
memory.c:15542:15: warning: unused variable ‘vm_start’ [-Wunused-variable]
          ulong vm_start, vm_end;
                ^~~~~~~~
memory.c:15541:8: warning: unused variable ‘vma_buf’ [-Wunused-variable]
   char *vma_buf;
         ^~~~~~~

but we can remove these when applying.


> +	ulong mm_mt, entry_num, i;
> +	struct list_pair *entry_list;
>   
>           if (!tc->mm_struct)
>                   return FALSE;
>   
> -        fill_mm_struct(tc->mm_struct);
> -	vma = ULONG(tt->mm_struct + OFFSET(mm_struct_mmap));
> +	fill_mm_struct(tc->mm_struct);
> +	vaddr = VIRTPAGEBASE(vaddr) + PAGESIZE();  /* first possible page */
>   	total_vm = ULONG(tt->mm_struct + OFFSET(mm_struct_total_vm));
> -
> -	if (!vma || (total_vm == 0))
> +	if (!total_vm)
>   		return FALSE;
>   
> -	vaddr = VIRTPAGEBASE(vaddr) + PAGESIZE();  /* first possible page */
> -
> -        for ( ; vma; vma = vm_next) {
> -                vma_buf = fill_vma_cache(vma);
> -
> -                vm_start = ULONG(vma_buf + OFFSET(vm_area_struct_vm_start));
> -                vm_end = ULONG(vma_buf + OFFSET(vm_area_struct_vm_end));
> -                vm_next = ULONG(vma_buf + OFFSET(vm_area_struct_vm_next));
> -
> -		if (vaddr <= vm_start) {
> -			*nextvaddr = vm_start;
> -			return TRUE;
> +	if (INVALID_MEMBER(mm_struct_mmap) && VALID_MEMBER(mm_struct_mm_mt)) {
> +		mm_mt = tc->mm_struct + OFFSET(mm_struct_mm_mt);
> +		entry_num = do_maple_tree(mm_mt, MAPLE_TREE_COUNT, NULL);
> +		entry_list = (struct list_pair *)GETBUF(entry_num * sizeof(struct list_pair));
> +		do_maple_tree(mm_mt, MAPLE_TREE_GATHER, entry_list);
> +		for (i = 0; i < entry_num; i++) {
> +			if (!!(vma = (ulong)entry_list[i].value) &&
> +			    check_vma(vma, vaddr, NULL, nextvaddr)) {
> +				FREEBUF(entry_list);
> +				return TRUE;
> +			}
>   		}
> +		FREEBUF(entry_list);
> +	} else {
> +		vma = ULONG(tt->mm_struct + OFFSET(mm_struct_mmap));
>   
> -		if ((vaddr > vm_start) && (vaddr < vm_end)) {
> -			*nextvaddr = vaddr;
> -			return TRUE;
> +		if (!vma)
> +			return FALSE;
> +		for ( ; vma; vma = vm_next) {
> +			if (check_vma(vma, vaddr, &vm_next, nextvaddr))
> +				return TRUE;
>   		}
>   	}
>   

The above looks a bit inefficient due to the search function structure
and maple tree ops in the first place, but it's another viewpoint.

Acked-by: Kazuhito Hagio <k-hagio-ab@xxxxxxx>

Thanks,
Kazu
--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux