No. When we send a signal to multiple processes it needs to be an
atomic operation so that kill -KILL -pgrp won't let processes escape.
It is what posix specifies, it is what real programs expect, and it
is the useful semantic in userspace.
Just using rcu_read_lock() breaks that atomicity of sending a signal
to a process group, which means we can have new processes that escape
the signal. Even with the tasklist_lock we have to have a special
case in fork to ensure we don't add a process to a process group
while a signal is being delivered to it.
I have scratched my head a few times wondering if there is a way to
preserve the atomic guarantee without taking a global lock, but I
haven't found one I can wrap my head around yet.
Likely. At one point read_lock(&tasklist_lock) implied having the
rcu_read_lock(). As it no longer does in some cases we have a small
pile of places with outdated assumptions. I know I have been guilty a
few times of forgetting about the new rule that we have to take rcu_read_lock()
everywhere.
With the tasklist_lock the rule in these functions is that the caller
will take the lock, so we probably make the rule the caller should
take the lock in the same scenarios for the rcu_read_lock(). Aka just
say:
read_lock(&tasklist_lock);
rcu_read_lock();
everywhere, that today we say just:
read_lock(&tasklist_lock);
It is what was meant when the code was written and the rcu-ized, and
it will certainly preserve my human intuition and general practical
reality that when you have the tasklist_lock you have the
rcu_read_lock.
*Shrug* I don't think it matters a whole lot.
Eric
--