On 04/07, Oleg Nesterov wrote: > > On 04/06, Jens Axboe wrote: > > > > +extern struct callback_head task_work_exited; > > + > > static inline void > > init_task_work(struct callback_head *twork, task_work_func_t func) > > { > > @@ -19,7 +21,7 @@ void __task_work_run(void); > > > > static inline bool task_work_pending(void) > > { > > - return current->task_works; > > + return current->task_works && current->task_works != &task_work_exited; > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > Well, this penalizes all the current users, they can't hit work_exited. > > IIUC, this is needed for the next change which adds task_work_run() into > io_ring_ctx_wait_and_kill(), right? > > could you explain how the exiting can call io_ring_ctx_wait_and_kill() > after it passed exit_task_work() ? Note also that currently we assume that task_work_run() must not be called by the exiting process (except exit_task_work). If io_ring adds the precedent we need change the PF_EXITING logic in task_work_run(). Oleg.