Re: [PATCH RT] locking: Make spinlock_t and rwlock_t a RCU section on RT
From: Sebastian Andrzej Siewior
Date: Fri Nov 29 2019 - 10:45:40 EST
On 2019-11-25 12:25:45 [-0500], Steven Rostedt wrote:
> On Fri, 22 Nov 2019 19:01:40 +0100
> Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> wrote:
>
> > Let me give you an example how I got into this:
> >
> > do_sigaction() acquires p->sighand->siglock and then iterates over list
> > via for_each_thread() which is a list_for_each_entry_rcu(). No RCU lock
> > is held, just the siglock.
> > On removal side, __unhash_process() removes a task from the list but
> > while doing so it holds the siglock and tasklist_lock. So it is
> > perfectly fine.
> > Later, we have:
> > |do_exit()
> > | -> exit_notify()
> > | -> write_lock_irq(&tasklist_lock);
> > | -> forget_original_parent()
> > | -> find_child_reaper()
> > | -> find_alive_thread()
> > | -> for_each_thread()
> >
> > find_alive_thread() does the for_each_thread() and checks PF_EXITING.
> > it might be enough for not operating on "removed" task_struct. It
> > dereferences task_struct->flags while looking for PF_EXITING. At this
> > point only tasklist_lock is acquired.
> > I have *no* idea if the whole synchronisation based on siglock/
> > PF_EXITING/ tasklist_lock is enough and RCU simply doesn't matter. It
> > seems so.
> >
> > I am a little worried if this construct here (or somewhere else) assumes
> > that holding one of those locks, which disable preemption, is the same
> > as rcu_read_lock() (or rcu_read_lock_sched()).
>
> I'm wondering if instead, we should start throwing in rcu_read_lock()
> and explicitly have the preempt disabled rcu use that as well, since
> today it's basically one and the same.
Any comment from the RCU camp on this?
Maybe just adding the missing RCU annotation for the list annotation is
enough (like if lock X or Y is held then everything fine). !RT gets this
implicit via preempt_disable(). I'm just worried if someone expects
this kind of behaviour.
If I remember correctly, Scott added rcu_read_lock() recently to
local_bh_disable() because RCU-torture expected it.
> Although, we still need to be careful for some special cases like
> function tracing, that uses its own kind of RCU. But that should be
> fixed when I introduce rcu_read_lock_tasks() :-)
>
> -- Steve
Sebastian