On 06/17, Mateusz Guzik wrote:
>
> There are trivial touch ups which can be done by adding a bunch of
> predicts and inlining kill_fasync if someone can be bothered.

I was thinking about another change, see below. It assumes that in the
likely case another writer won't steal the pages from ->tmp_page[]
before we take pipe->mutex.

I'm not sure this makes sense, and I have no idea how it would impact
performance in "real" workloads.

Oleg.
---

diff --git a/fs/pipe.c b/fs/pipe.c
index 429b0714ec57..9f07f469830a 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -131,7 +131,8 @@ struct anon_pipe_prealloc {
  * pipe->mutex hold-time being shrunk. Any shortfall is covered by the
  * in-lock alloc_page() fallback in anon_pipe_get_page().
  */
-static void anon_pipe_get_page_prealloc(struct anon_pipe_prealloc *prealloc,
+static void anon_pipe_get_page_prealloc(struct pipe_inode_info *pipe,
+                                       struct anon_pipe_prealloc *prealloc,
                                        size_t total_len)
 {
        unsigned int want, i;
@@ -144,6 +145,11 @@ static void anon_pipe_get_page_prealloc(struct 
anon_pipe_prealloc *prealloc,
        want = min_t(unsigned int, DIV_ROUND_UP(total_len, PAGE_SIZE),
                     PIPE_PREALLOC_MAX);
 
+       for (i = 0; i < ARRAY_SIZE(pipe->tmp_page); i++) {
+               if (pipe->tmp_page[i] && !--want)
+                       return;
+       }
+
        for (i = 0; i < want; i++) {
                page = alloc_page(GFP_HIGHUSER | __GFP_ACCOUNT);
                if (!page)
@@ -548,7 +554,7 @@ anon_pipe_write(struct kiocb *iocb, struct iov_iter *from)
        if (unlikely(total_len == 0))
                return 0;
 
-       anon_pipe_get_page_prealloc(&prealloc, total_len);
+       anon_pipe_get_page_prealloc(pipe, &prealloc, total_len);
 
        mutex_lock(&pipe->mutex);
 


Reply via email to