[Crash-utility] [PATCH] Fix machdep->HZ calculation for kernel versions > 2.6.0

HAGIO KAZUHITO(萩尾 一仁) k-hagio-ab at nec.com
Fri Apr 23 07:08:13 UTC 2021


> -----Original Message-----
> > Sure. On my ppc64le machine, crash got 96hz after applying the above patch. The reason
> > is that kernel calculates the value of bfq_timeout as below:
> >
> > bfq_timeout = HZ / 8;
> >
> > The actual value of HZ is 100, so bfq_timeout = 100 / 8 = 12, but in crash, we calculate
> > the value of HZ:
> >
> > HZ = bfq_timeout * 8 = 12 * 8 = 96
> >
> > It seems that this is not the result what we expected.

Oh, you are right.

> >
> >> btw, I thought 'read_expire' was better than the 'bfq_timeout' because it
> >> was introduced at 2.6.16 and has been unchanged, but most of kernels(vmlinux)
> >
> > Sounds good. But unfortunately, the 'read_expire' is a static variable in kernel, we
> > can not get it directly by the symbol search. Maybe we should try to find a static
> > variable(kernel) in another ways.
> >
> > If it is possible, I would tend to use the 'write_expire' to calculate the value of HZ
> > in crash as below, that can avoid the above issues and get a correct result.
> >
> > HZ = write_expire / 5;
> >
> > /*
> >  * source: block/mq-deadline.c
> >  */
> > static const int write_expire = 5 * HZ
> >
> > For example:
> > +       if (symbol_exists("write_expire")) { ----> Here, it failed, maybe we can try to find the symbol
> in another way.
> > +               uint write_expire;
> > +               get_symbol_data("write_expire", sizeof(int), &write_expire);
> > +               if (write_expire) {
> > +                       machdep->hz = write_expire / 5;
> > +                       if (CRASHDEBUG(2))
> > +                               fprintf(fp, "write_expire exists: setting hz to %d\n",
> > +                                       machdep->hz);
> > +               }
> > +       }  else
> >
> >> that I have do not have a symbol for it.  (some optimization?)
> >>
> > I can get the values of 'read_expire' and 'write_expire' in the latest rhel8 or later.
> >
> > crash> p read_expire
> > $1 = 50
> > crash> p write_expire
> > $2 = 500
> >
> > Thanks.
> > Linabo
> >
> 
> How do you think about the following changes? It works for me.
> 
> /*
>  * source: net/ipv4/inetpeer.c
>  * int inet_peer_minttl __read_mostly = 120 * HZ;  /* TTL under high load: 120 sec */
>  */

um, unfortunately this is a sysctl parameter and can be changed.


As for the 'write_expire' way, I found that it can be printed after
"set scope dd_init_queue" or "set scope deadline_init_queue" on old kernels.

crash> p write_expire
No symbol "write_expire" in current context.
p: gdb request failed: p write_expire
crash> set scope dd_init_queue
scope: ffffffffa43e3f80 (dd_init_queue)
crash> p write_expire
$1 = 5000

Maybe we can make use of gdb_set_crash_scope() and gdb_pass_through() to
get this value?

Thanks,
Kazu






More information about the Crash-utility mailing list