[Crash-utility] Problem with "timer" command on RHEL7.6

Dave Anderson anderson at redhat.com
Thu Aug 1 17:22:28 UTC 2019



----- Original Message -----
> Hi Dave,
> 
> I noticed that the "timer" command prints somewhat wrongly for RHEL7.6 or
> later kernels (not including RHEL8 / upstream) and found that it is because
> struct tvec and tvec_root have an array of list_head, instead of hlist_head
> in upstream kernels.
> 
> So the following patch looks good only for RHEL7, but I don't know how we
> should determine the list type in order to switch the size, etc in this case.
> What do you think?

Try using the MEMBER_TYPE_NAME() macro.  For example, adding this to cmd_test():

--- a/test.c	2011-09-01 14:06:56.000000000 -0400
+++ b/test.c	2019-08-01 13:16:13.783615151 -0400
@@ -58,6 +58,7 @@ cmd_test(void)
                 ;
                 optind++;
         }
+fprintf(fp, "%s\n", MEMBER_TYPE_NAME("tvec_root", "vec"));
 }
 
shows this on a RHEL7 kernel:

  crash> struct tvec_root
  struct tvec_root {
      struct list_head vec[256];
  }
  SIZE: 409
  crash> test
  list_head
  crash> s

Dave

> 
> Thanks,
> Kazu
> 
> ---
> diff --git a/kernel.c b/kernel.c
> index a79e5a3010ea..419cca3ac7ae 100644
> --- a/kernel.c
> +++ b/kernel.c
> @@ -8376,7 +8376,7 @@ dump_timer_data_tvec_bases_v3(const ulong *cpus)
>  	char buf4[BUFSIZE];
>  
>  	vec_root_size = vec_size = 0;
> -	head_size = SIZE(hlist_head);
> +	head_size = SIZE(list_head);
>  
>  	if ((i = get_array_length("tvec_root.vec", NULL, head_size)))
>  		vec_root_size = i;
> @@ -8804,19 +8804,19 @@ do_timer_list_v3(ulong vec_kvaddr,
>  			tdx++;
>  	}
>  
> -	readmem(vec_kvaddr, KVADDR, vec, SIZE(hlist_head) * size,
> +	readmem(vec_kvaddr, KVADDR, vec, SIZE(list_head) * size,
>  		"timer_list vec array", FAULT_ON_ERROR);
>  
>  	ld = &list_data;
>  	timer_list_buf = GETBUF(SIZE(timer_list));
>  
> -	for (i = count = 0; i < size; i++, vec_kvaddr += SIZE(hlist_head)) {
> +	for (i = count = 0; i < size; i++, vec_kvaddr += SIZE(list_head)) {
>  
> -		if (vec[i] == 0)
> +		if (vec[i*2] == vec_kvaddr)
>  			continue;
>  
>  		BZERO(ld, sizeof(struct list_data));
> -		ld->start = vec[i];
> +		ld->start = vec[i*2];
>  		ld->list_head_offset = OFFSET(timer_list_entry);
>  		ld->end = vec_kvaddr;
>  		ld->flags = RETURN_ON_LIST_ERROR;
> 




More information about the Crash-utility mailing list