On Mon, Sep 17, 2018 at 02:05:40PM -0700, Subhra Mazumdar wrote: > On 09/07/2018 05:25 AM, Peter Zijlstra wrote:
> >Why not just busy wait on current->state ? A little something like: > > > >diff --git a/fs/pipe.c b/fs/pipe.c > >index bdc5d3c0977d..8d9f1c95ff99 100644 > >--- a/fs/pipe.c > >+++ b/fs/pipe.c > >@@ -106,6 +106,7 @@ void pipe_double_lock(struct pipe_inode_info *pipe1, > > void pipe_wait(struct pipe_inode_info *pipe) > > { > > DEFINE_WAIT(wait); > >+ u64 start; > > /* > > * Pipes are system-local resources, so sleeping on them > >@@ -113,7 +114,15 @@ void pipe_wait(struct pipe_inode_info *pipe) > > */ > > prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE); > > pipe_unlock(pipe); > >- schedule(); > >+ > >+ preempt_disable(); > >+ start = local_clock(); > >+ while (!need_resched() && current->state != TASK_RUNNING && > >+ (local_clock() - start) < pipe->poll_usec) > >+ cpu_relax(); > >+ schedule_preempt_disabled(); > >+ preempt_enable(); > >+ > > finish_wait(&pipe->wait, &wait); > > pipe_lock(pipe); > > } > This will make the current thread always spin and block as it itself does > the state change to TASK_RUNNING in finish_wait. Nah, the actual wakeup will also do that state change. The one in finish_wait() is for the case where the wait condition became true without wakeup, such that we don't 'leak' the INTERRUPTIBLE state.