Messages in this thread | | | Subject | Re: [RFC PATCH 2/2] pipe: use pipe busy wait | From | Subhra Mazumdar <> | Date | Mon, 17 Sep 2018 14:05:40 -0700 |
| |
On 09/07/2018 05:25 AM, Peter Zijlstra wrote: > On Thu, Aug 30, 2018 at 01:24:58PM -0700, subhra mazumdar wrote: >> +void pipe_busy_wait(struct pipe_inode_info *pipe) >> +{ >> + unsigned long wait_flag = pipe->pipe_wait_flag; >> + unsigned long start_time = pipe_busy_loop_current_time(); >> + >> + pipe_unlock(pipe); >> + preempt_disable(); >> + for (;;) { >> + if (pipe->pipe_wait_flag > wait_flag) { >> + preempt_enable(); >> + pipe_lock(pipe); >> + return; >> + } >> + if (pipe_busy_loop_timeout(pipe, start_time)) >> + break; >> + cpu_relax(); >> + } >> + preempt_enable(); >> + pipe_lock(pipe); >> + if (pipe->pipe_wait_flag > wait_flag) >> + return; >> + pipe_wait(pipe); >> +} >> + >> +void wake_up_busy_poll(struct pipe_inode_info *pipe) >> +{ >> + pipe->pipe_wait_flag++; >> +} > 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.
| |