Messages in this thread | | | Date | Mon, 25 Jun 2012 17:18:12 +0200 | From | Oleg Nesterov <> | Subject | Re: deferring __fput() |
| |
On 06/25, Al Viro wrote: > > On Sun, Jun 24, 2012 at 05:33:10PM +0200, Oleg Nesterov wrote: > > No, we can't do this? > > > > OK, perhaps we can check something else instead of PF_EXITING. > > But somehow we should ensuree that if task_work_add(twork) succeeds, > > then twork->func() will be called. IOW, if task_work_add() races with > > the exiting task, it should not succeed after exit_task_work(). > > Hrm... I still think that callers can bloody well check it themselves,
Why? I don't think this would be very convenient, and it is not easy to avoid the races. Unless task == current.
OK, if task == current it can do the necessary checks, so we could add "force" argument for fput(). But I agree, it would be better to avoid this.
And since we want to move exit_task_work() after exit_fs() we can't rely on PF_EXITING (unless we add "force").
> but anyway - we can add a new PF_... bit and have it set on kernel threads > (all along)
Why? irq_thread() already uses task_work_add()...
> the real question is in locking > and barriers needed there. Suggestions?
Yes, we need more barries. Or, perhaps exit_task_work() should simply take ->pi_lock unconditionally? I don't think additional STORE + mb() is better.
And if it always takes ->pi_lock we do not need the new PF_ or something else, exit_task_work() can set task->task_works = NO_MORE under ->pi_lock (task_work_run() can check PF_EXITING), and task_work_add() ensures that task_works != NO_MORE.
What do you think?
Oleg.
| |