Re: [PATCH RT] locking: Make spinlock_t and rwlock_t a RCU section on RT

From: Steven Rostedt
Date: Mon Nov 25 2019 - 12:25:52 EST


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.

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