Fix for Linux 5.4-rc1 and later kernels that contain commit
 511885d7061eda3eb1faf3f57dcc936ff75863f1, titled "lib/timerqueue: Rely on
 rbtree semantics for next timer".  Without the patch, "timer -r" option
 fails with the following error:
 
   timer: invalid structure member offset: timerqueue_head_next
          FILE: kernel.c  LINE: 7652  FUNCTION: dump_active_timers()
 
 Also fix a typo in MEMBER_OFFSET_INIT(timerqueue_node_node, ...).
 
 Signed-off-by: Kazuhito Hagio <k-hagio(a)ab.jp.nec.com>
 ---
  defs.h    |  2 ++
  kernel.c  | 16 ++++++++++++++--
  symbols.c |  4 ++++
  3 files changed, 20 insertions(+), 2 deletions(-)
 
 diff --git a/defs.h b/defs.h
 index 502e7c268448..efa40b9e1688 100644
 --- a/defs.h
 +++ b/defs.h
 @@ -2073,6 +2073,8 @@ struct offset_table {                    /* stash of
 commonly-used offsets */
  	long cpu_context_save_r7;
  	long dentry_d_sb;
  	long device_private_knode_class;
 +	long timerqueue_head_rb_root;
 +	long rb_root_cached_rb_leftmost;
  };
  
  struct size_table {         /* stash of commonly-used sizes */
 diff --git a/kernel.c b/kernel.c
 index 375e1b4ceb67..c4cb0018962e 100644
 --- a/kernel.c
 +++ b/kernel.c
 @@ -783,7 +783,13 @@ kernel_init()
  		MEMBER_OFFSET_INIT(timerqueue_node_expires,
  			"timerqueue_node", "expires");
  		MEMBER_OFFSET_INIT(timerqueue_node_node,
 -			"timerqueue_node_node", "node");
 +			"timerqueue_node", "node");
 +		if (INVALID_MEMBER(timerqueue_head_next)) {
 +			MEMBER_OFFSET_INIT(timerqueue_head_rb_root,
 +				"timerqueue_head", "rb_root");
 +			MEMBER_OFFSET_INIT(rb_root_cached_rb_leftmost,
 +				"rb_root_cached", "rb_leftmost");
 +		}
  	}
  	MEMBER_OFFSET_INIT(hrtimer_softexpires, "hrtimer",
"_softexpires");
  	MEMBER_OFFSET_INIT(hrtimer_function, "hrtimer", "function");
 @@ -7647,11 +7653,17 @@ next_one:
  		readmem((ulong)(base + OFFSET(hrtimer_clock_base_first)),
  			KVADDR,	&curr, sizeof(curr), "hrtimer_clock_base first",
  			FAULT_ON_ERROR);
 -	else
 +	else if (VALID_MEMBER(timerqueue_head_next))
  		readmem((ulong)(base + OFFSET(hrtimer_clock_base_active) +
  				OFFSET(timerqueue_head_next)),
  			KVADDR, &curr, sizeof(curr), "hrtimer_clock base",
  			FAULT_ON_ERROR);
 +	else
 +		readmem((ulong)(base + OFFSET(hrtimer_clock_base_active) +
 +				OFFSET(timerqueue_head_rb_root) +
 +				OFFSET(rb_root_cached_rb_leftmost)),
 +			KVADDR, &curr, sizeof(curr),
 +			"hrtimer_clock_base active", FAULT_ON_ERROR);
  
  	while (curr && i < next) {
  		curr = rb_next(curr);
 diff --git a/symbols.c b/symbols.c
 index 7af5e69da39b..eb88ca119751 100644
 --- a/symbols.c
 +++ b/symbols.c
 @@ -10032,6 +10032,8 @@ dump_offset_table(char *spec, ulong makestruct)
                  OFFSET(rb_node_rb_left));
          fprintf(fp, "              rb_node_rb_right: %ld\n",
                  OFFSET(rb_node_rb_right));
 +        fprintf(fp, "    rb_root_cached_rb_leftmost: %ld\n",
 +                OFFSET(rb_root_cached_rb_leftmost));
  
  	fprintf(fp, "            x8664_pda_pcurrent: %ld\n",
  		OFFSET(x8664_pda_pcurrent));
 @@ -10388,6 +10390,8 @@ dump_offset_table(char *spec, ulong makestruct)
  		OFFSET(hrtimer_function));
  	fprintf(fp, "          timerqueue_head_next: %ld\n",
  		OFFSET(timerqueue_head_next));
 +	fprintf(fp, "       timerqueue_head_rb_root: %ld\n",
 +		OFFSET(timerqueue_head_rb_root));
  	fprintf(fp, "       timerqueue_node_expires: %ld\n",
  		OFFSET(timerqueue_node_expires));
  	fprintf(fp, "          timerqueue_node_node: %ld\n",
 --
 2.18.1
 
 --
 Crash-utility mailing list
 Crash-utility(a)redhat.com
 
https://www.redhat.com/mailman/listinfo/crash-utility