On Tue, Sep 27, 2005 at 03:10:20PM -0500, Erik Jacobson wrote:
> 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).
Erik,
I'm not sure that it does at this moment, not seeing the code for
copy_process() or __pnotify_exit().
__pnotify_exit() would need to call the exit callback for all clients
except for the client failing the fork call. To do this wouldn't the
following be needed in __pnotify_fork()?
> 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 */
>
Then, to make sure the current client does not have his exit callback
invoked:
...
if (ret != 0) {
pnotify_unsubscribe(to_subscriber);
if (ret < 0)
return ret;
}
}
return 0;
}
What do you think?
--
Kingsley
|