I fixed this in the RCU version of pnotify I'm working per the lse-tech
community discussion - thanks for the reminder the other day (in a non-list
email).
If the RCU version crashes and burns for some reason and we go back to
the non-CUu one, I'll need to make the fix there too. The function now
looks like this. I hope this is what you had in mind (untested as of
this moment).
/**
* __pnotify_fork - Add kernel module subscriber to same subscribers as parent
* @to_task: The child task that will inherit the parent's subscribers
* @from_task: The parent task
*
* Used to attach a new task to the same subscribers the parent has in its
* subscriber list.
*
* The "from" argument is the parent task. The "to" argument is the child
* task.
*
* See Documentation/pnotify.txt for details on
* how to handle return codes from the attach function pointer.
*
* Locking: The to_task is currently in-construction, so we don't
* need to worry about write-locks. We do need to be sure the parent's
* subscriber list, which we copy here, doesn't go away on us. This is
* done via RCU.
*
*/
int
__pnotify_fork(struct task_struct *to_task, struct task_struct *from_task)
{
struct pnotify_subscriber *from_subscriber;
int ret;
/* We need to be sure the parent's list we copy from doesn't disappear
*/
rcu_read_lock();
list_for_each_entry_rcu(from_subscriber,
&from_task->pnotify_subscriber_list, entry) {
struct pnotify_subscriber *to_subscriber = NULL;
to_subscriber = pnotify_subscribe(to_task,
from_subscriber->events);
if (!to_subscriber) {
ret=-ENOMEM;
__pnotify_exit(to_task);
rcu_read_unlock();
return ret;
}
ret = to_subscriber->events->fork(to_task, to_subscriber,
from_subscriber->data);
rcu_read_unlock(); /* no more to do with the parent's data */
if (ret < 0) {
/* Propagates to copy_process as a fork failure */
/* No __pnotify_exit because there is one in the
failure path
* for copy_process in fork.c */
return ret; /* Fork failure */
}
else if (ret > 0) {
/* Success, but fork function pointer in the
pnotify_events structure
* doesn't want the kenrel module subscribed */
/* Again, this is the in-construction-child so no write
lock */
pnotify_unsubscribe(to_subscriber);
}
}
return 0; /* success */
}
|