Re: [BUG] NULL pointer deref with rcutorture

Paul E. McKenney
2009-01-04T21:14:03Z

On Sun, Jan 04, 2009 at 03:57:26PM +0100, Eric Sesterhenn wrote:
> * Paul E. McKenney (paulmck@linux.vnet.ibm.com) wrote:
> > On Sat, Jan 03, 2009 at 10:40:03AM +0100, Eric Sesterhenn wrote:
> > > * Paul E. McKenney (paulmck@linux.vnet.ibm.com) wrote:
> > > > On Sat, Jan 03, 2009 at 12:12:39AM +0100, Eric Sesterhenn wrote:
> > > > > * Paul E. McKenney (paulmck@linux.vnet.ibm.com) wrote:
> > > > >
> > > > > I tried to apply the patch from
> > > > > http://git.kernel.dk/?p=linux-2.6-block.git;a=commitdiff_plain;h=392ddc32982a5c661dd90dd49a3cb37f1c68b782;hp=bb799ca0202a360fa74d5f17039b9100caebdde7
> > > > > but get a message that it is already applied. Seems i already got that
> > > > > one.
> > > >
> > > > Is your configuration able to support ftrace?
> > >
> > > yes
> > >
> > > > Looks like someone is (wrongly) freeing some memory that was sent to
> > > > call_rcu(), and ftrace might be one way to locate the problem.
> > >
> > > I set the filter to call_rcu() and call_rcu_sched(), reproduced the
> > > oops, and got this in the trace file.
> >
> > Hmmm... The only unique ones are _rcu_barrier() used during module
> > removal by rcutorture and rt_worker_func(), which occurs near the
> > beginning of the trace. My next step would be to trace the addresses of
> > rcu_head structures passed to call_rcu() and friends and to also trace
> > the addresses of the structures as they are invoked (where the original
> > NULL-pointer exception occurred).
> >
> > Is this tracing something you would be interested in taking on? My
> > test setup is having some trouble, so it would probably be a couple of
> > days before I got it working. :-/
>
> Just tell me what i need to do, I am not really familiar with ftrace.
> I am only able to test 2.6.28-04980-gb58602a, since current -git is not
> able to boot on this box :|

Very cool!

The idea is to have __call_rcu() in kernel/rcutree.c record the
address of the callback (argument "head") and the function (argument
"func"). In rcu_do_batch(), just before invoking list->func(list),
also record the address of the callback ("list") and the function
(again, "func").

The new ftrace package has some mechanisms for doing this, but there is
always the old-fashioned way of using printk(), for example in
rcu_do_batch():

prefetch(next);
if (rcu_dump_callbacks)
printk("rcu_head=%p, func=%p\n", list, func);
list->func(list);

Initialize rcu_dump_callbacks to zero, then use a small kernel module
(or some such) to set it to one just before running your test.

If you would like, I could rough out the code, though as noted earlier,
I currently have no way of testing it. (Hopefully will be fixed in a
few days.)

I was wondering what should be done for ftrace plugins for RCU, I guess
I now have at least part of the answer. ;-)

Thanx, Paul