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);