Re: call_rcu from trace_preempt

From: Daniel Wagner
Date: Wed Jun 17 2015 - 04:12:12 EST


On 06/16/2015 07:20 PM, Alexei Starovoitov wrote:
> On 6/16/15 5:38 AM, Daniel Wagner wrote:
>> static int free_thread(void *arg)
>> +{
>> + unsigned long flags;
>> + struct htab_elem *l;
>> +
>> + while (!kthread_should_stop()) {
>> + spin_lock_irqsave(&elem_freelist_lock, flags);
>> + while (!list_empty(&elem_freelist)) {
>> + l = list_entry(elem_freelist.next,
>> + struct htab_elem, list);
>> + list_del(&l->list);
>> + kfree(l);
>
> that's not right, since such thread defeats rcu protection of lookup.
> We need either kfree_rcu/call_rcu or synchronize_rcu.

D'oh, I have not seen the elephant in the room.

/me grabs a brown bag.

> Obviously the former is preferred that's why I'm still digging into it.
> Probably a thread that does kfree_rcu would be ok, but we shouldn't
> be doing it unconditionally. For all networking programs and 99%
> of tracing programs the existing code is fine and I don't want to
> slow it down to tackle the corner case.
> Extra spin_lock just to add it to the list is also quite costly.

Anyway, I changed to above kfree() to a kfree_rcu() and it explodes
again. With the same stack trace we seen.

Steven's suggestion deferring the work via irq_work results in the same
stack trace. (Now I get cold feets, without the nice heat from the CPU
busy looping...)

It looks like there is something else somewhere hidden.

cheers,
daniel