diff mbox series

pipe: remove needless spin_lock in pipe_read/pipe_write

Message ID 20211122041135.2450220-1-yangerkun@huawei.com (mailing list archive)
State New, archived
Headers show
Series pipe: remove needless spin_lock in pipe_read/pipe_write | expand

Commit Message

yangerkun Nov. 22, 2021, 4:11 a.m. UTC
Once enable CONFIG_WATCH_QUEUE, we should protect pipe with
pipe->rd_wait.lock since post_one_notification may write pipe from
contexts where pipe->mutex cannot be token. But nowdays we will try
take it for anycase, it seems needless. Besides, pipe_write will break
once it's pipe with O_NOTIFICATION_PIPE, pipe->rd_wait.lock seems no
need at all. We make some change base on that, and it can help improve
performance for some case like pipe_pst1 in libMicro.

ARMv7 for our scene, before this patch:
  5483 nsecs/call
After this patch:
  4854 nsecs/call

Signed-off-by: yangerkun <yangerkun@huawei.com>
---
 fs/pipe.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

Comments

yangerkun Nov. 29, 2021, 6:22 a.m. UTC | #1
ping

On 2021/11/22 12:11, yangerkun wrote:
> Once enable CONFIG_WATCH_QUEUE, we should protect pipe with
> pipe->rd_wait.lock since post_one_notification may write pipe from
> contexts where pipe->mutex cannot be token. But nowdays we will try
> take it for anycase, it seems needless. Besides, pipe_write will break
> once it's pipe with O_NOTIFICATION_PIPE, pipe->rd_wait.lock seems no
> need at all. We make some change base on that, and it can help improve
> performance for some case like pipe_pst1 in libMicro.
> 
> ARMv7 for our scene, before this patch:
>    5483 nsecs/call
> After this patch:
>    4854 nsecs/call
> 
> Signed-off-by: yangerkun <yangerkun@huawei.com>
> ---
>   fs/pipe.c | 15 +++++++--------
>   1 file changed, 7 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/pipe.c b/fs/pipe.c
> index 6d4342bad9f1..e8ced0c50824 100644
> --- a/fs/pipe.c
> +++ b/fs/pipe.c
> @@ -320,14 +320,18 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
>   
>   			if (!buf->len) {
>   				pipe_buf_release(pipe, buf);
> -				spin_lock_irq(&pipe->rd_wait.lock);
>   #ifdef CONFIG_WATCH_QUEUE
> +				if (pipe->watch_queue)
> +					spin_lock_irq(&pipe->rd_wait.lock);
>   				if (buf->flags & PIPE_BUF_FLAG_LOSS)
>   					pipe->note_loss = true;
>   #endif
>   				tail++;
>   				pipe->tail = tail;
> -				spin_unlock_irq(&pipe->rd_wait.lock);
> +#ifdef CONFIG_WATCH_QUEUE
> +				if (pipe->watch_queue)
> +					spin_unlock_irq(&pipe->rd_wait.lock);
> +#endif
>   			}
>   			total_len -= chars;
>   			if (!total_len)
> @@ -504,16 +508,11 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
>   			 * it, either the reader will consume it or it'll still
>   			 * be there for the next write.
>   			 */
> -			spin_lock_irq(&pipe->rd_wait.lock);
> -
>   			head = pipe->head;
> -			if (pipe_full(head, pipe->tail, pipe->max_usage)) {
> -				spin_unlock_irq(&pipe->rd_wait.lock);
> +			if (pipe_full(head, pipe->tail, pipe->max_usage))
>   				continue;
> -			}
>   
>   			pipe->head = head + 1;
> -			spin_unlock_irq(&pipe->rd_wait.lock);
>   
>   			/* Insert it into the buffer array */
>   			buf = &pipe->bufs[head & mask];
>
yangerkun Dec. 16, 2021, 8:31 a.m. UTC | #2
ping...

On 2021/11/29 14:22, yangerkun wrote:
> ping
> 
> On 2021/11/22 12:11, yangerkun wrote:
>> Once enable CONFIG_WATCH_QUEUE, we should protect pipe with
>> pipe->rd_wait.lock since post_one_notification may write pipe from
>> contexts where pipe->mutex cannot be token. But nowdays we will try
>> take it for anycase, it seems needless. Besides, pipe_write will break
>> once it's pipe with O_NOTIFICATION_PIPE, pipe->rd_wait.lock seems no
>> need at all. We make some change base on that, and it can help improve
>> performance for some case like pipe_pst1 in libMicro.
>>
>> ARMv7 for our scene, before this patch:
>>    5483 nsecs/call
>> After this patch:
>>    4854 nsecs/call
>>
>> Signed-off-by: yangerkun <yangerkun@huawei.com>
>> ---
>>   fs/pipe.c | 15 +++++++--------
>>   1 file changed, 7 insertions(+), 8 deletions(-)
>>
>> diff --git a/fs/pipe.c b/fs/pipe.c
>> index 6d4342bad9f1..e8ced0c50824 100644
>> --- a/fs/pipe.c
>> +++ b/fs/pipe.c
>> @@ -320,14 +320,18 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
>>               if (!buf->len) {
>>                   pipe_buf_release(pipe, buf);
>> -                spin_lock_irq(&pipe->rd_wait.lock);
>>   #ifdef CONFIG_WATCH_QUEUE
>> +                if (pipe->watch_queue)
>> +                    spin_lock_irq(&pipe->rd_wait.lock);
>>                   if (buf->flags & PIPE_BUF_FLAG_LOSS)
>>                       pipe->note_loss = true;
>>   #endif
>>                   tail++;
>>                   pipe->tail = tail;
>> -                spin_unlock_irq(&pipe->rd_wait.lock);
>> +#ifdef CONFIG_WATCH_QUEUE
>> +                if (pipe->watch_queue)
>> +                    spin_unlock_irq(&pipe->rd_wait.lock);
>> +#endif
>>               }
>>               total_len -= chars;
>>               if (!total_len)
>> @@ -504,16 +508,11 @@ pipe_write(struct kiocb *iocb, struct iov_iter 
>> *from)
>>                * it, either the reader will consume it or it'll still
>>                * be there for the next write.
>>                */
>> -            spin_lock_irq(&pipe->rd_wait.lock);
>> -
>>               head = pipe->head;
>> -            if (pipe_full(head, pipe->tail, pipe->max_usage)) {
>> -                spin_unlock_irq(&pipe->rd_wait.lock);
>> +            if (pipe_full(head, pipe->tail, pipe->max_usage))
>>                   continue;
>> -            }
>>               pipe->head = head + 1;
>> -            spin_unlock_irq(&pipe->rd_wait.lock);
>>               /* Insert it into the buffer array */
>>               buf = &pipe->bufs[head & mask];
>>
> .
diff mbox series

Patch

diff --git a/fs/pipe.c b/fs/pipe.c
index 6d4342bad9f1..e8ced0c50824 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -320,14 +320,18 @@  pipe_read(struct kiocb *iocb, struct iov_iter *to)
 
 			if (!buf->len) {
 				pipe_buf_release(pipe, buf);
-				spin_lock_irq(&pipe->rd_wait.lock);
 #ifdef CONFIG_WATCH_QUEUE
+				if (pipe->watch_queue)
+					spin_lock_irq(&pipe->rd_wait.lock);
 				if (buf->flags & PIPE_BUF_FLAG_LOSS)
 					pipe->note_loss = true;
 #endif
 				tail++;
 				pipe->tail = tail;
-				spin_unlock_irq(&pipe->rd_wait.lock);
+#ifdef CONFIG_WATCH_QUEUE
+				if (pipe->watch_queue)
+					spin_unlock_irq(&pipe->rd_wait.lock);
+#endif
 			}
 			total_len -= chars;
 			if (!total_len)
@@ -504,16 +508,11 @@  pipe_write(struct kiocb *iocb, struct iov_iter *from)
 			 * it, either the reader will consume it or it'll still
 			 * be there for the next write.
 			 */
-			spin_lock_irq(&pipe->rd_wait.lock);
-
 			head = pipe->head;
-			if (pipe_full(head, pipe->tail, pipe->max_usage)) {
-				spin_unlock_irq(&pipe->rd_wait.lock);
+			if (pipe_full(head, pipe->tail, pipe->max_usage))
 				continue;
-			}
 
 			pipe->head = head + 1;
-			spin_unlock_irq(&pipe->rd_wait.lock);
 
 			/* Insert it into the buffer array */
 			buf = &pipe->bufs[head & mask];