All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] include/pipe_fs_i.h: add missing #includes
@ 2022-02-25 18:54 Max Kellermann
  2022-02-25 18:54 ` [PATCH 2/4] fs/pipe: remove duplicate "offset" initializer Max Kellermann
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Max Kellermann @ 2022-02-25 18:54 UTC (permalink / raw)
  To: viro, linux-fsdevel, linux-kernel; +Cc: Max Kellermann

To verify that this header's #includes are correct, include it first
in fs/pipe.c.

To: Alexander Viro <viro@zeniv.linux.org.uk>
To: linux-fsdevel@vger.kernel.org
To: linux-kernel@vger.kernel.org
Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 fs/pipe.c                 | 2 +-
 include/linux/pipe_fs_i.h | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index cc28623a67b6..da842d13029d 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -5,6 +5,7 @@
  *  Copyright (C) 1991, 1992, 1999  Linus Torvalds
  */
 
+#include <linux/pipe_fs_i.h>
 #include <linux/mm.h>
 #include <linux/file.h>
 #include <linux/poll.h>
@@ -16,7 +17,6 @@
 #include <linux/mount.h>
 #include <linux/pseudo_fs.h>
 #include <linux/magic.h>
-#include <linux/pipe_fs_i.h>
 #include <linux/uio.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index c00c618ef290..0e36a58adf0e 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -2,6 +2,9 @@
 #ifndef _LINUX_PIPE_FS_I_H
 #define _LINUX_PIPE_FS_I_H
 
+#include <linux/mutex.h>
+#include <linux/wait.h>
+
 #define PIPE_DEF_BUFFERS	16
 
 #define PIPE_BUF_FLAG_LRU	0x01	/* page is on the LRU */
-- 
2.34.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/4] fs/pipe: remove duplicate "offset" initializer
  2022-02-25 18:54 [PATCH 1/4] include/pipe_fs_i.h: add missing #includes Max Kellermann
@ 2022-02-25 18:54 ` Max Kellermann
  2022-02-25 18:54 ` [PATCH 3/4] fs/pipe: remove unnecessary "buf" initializer Max Kellermann
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Max Kellermann @ 2022-02-25 18:54 UTC (permalink / raw)
  To: viro, linux-fsdevel, linux-kernel; +Cc: Max Kellermann

This code duplication was introduced by commit a194dfe6e6f6 ("pipe:
Rearrange sequence in pipe_write() to preallocate slot"), but since
the pipe's mutex is locked, nobody else can modify the value
meanwhile.

To: Alexander Viro <viro@zeniv.linux.org.uk>
To: linux-fsdevel@vger.kernel.org
To: linux-kernel@vger.kernel.org
Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 fs/pipe.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index da842d13029d..aca717a89631 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -535,7 +535,6 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
 				break;
 			}
 			ret += copied;
-			buf->offset = 0;
 			buf->len = copied;
 
 			if (!iov_iter_count(from))
-- 
2.34.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/4] fs/pipe: remove unnecessary "buf" initializer
  2022-02-25 18:54 [PATCH 1/4] include/pipe_fs_i.h: add missing #includes Max Kellermann
  2022-02-25 18:54 ` [PATCH 2/4] fs/pipe: remove duplicate "offset" initializer Max Kellermann
@ 2022-02-25 18:54 ` Max Kellermann
  2022-02-25 18:54 ` [PATCH 4/4] pipe_fs_i.h: add pipe_buf_init() Max Kellermann
  2022-03-13  1:49 ` [PATCH 1/4] include/pipe_fs_i.h: add missing #includes Al Viro
  3 siblings, 0 replies; 10+ messages in thread
From: Max Kellermann @ 2022-02-25 18:54 UTC (permalink / raw)
  To: viro, linux-fsdevel, linux-kernel; +Cc: Max Kellermann

This one has no effect because this value is not used before it is
assigned again.

To: Alexander Viro <viro@zeniv.linux.org.uk>
To: linux-fsdevel@vger.kernel.org
To: linux-kernel@vger.kernel.org
Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 fs/pipe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index aca717a89631..b2075ecd4751 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -487,7 +487,7 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
 		head = pipe->head;
 		if (!pipe_full(head, pipe->tail, pipe->max_usage)) {
 			unsigned int mask = pipe->ring_size - 1;
-			struct pipe_buffer *buf = &pipe->bufs[head & mask];
+			struct pipe_buffer *buf;
 			struct page *page = pipe->tmp_page;
 			int copied;
 
-- 
2.34.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/4] pipe_fs_i.h: add pipe_buf_init()
  2022-02-25 18:54 [PATCH 1/4] include/pipe_fs_i.h: add missing #includes Max Kellermann
  2022-02-25 18:54 ` [PATCH 2/4] fs/pipe: remove duplicate "offset" initializer Max Kellermann
  2022-02-25 18:54 ` [PATCH 3/4] fs/pipe: remove unnecessary "buf" initializer Max Kellermann
@ 2022-02-25 18:54 ` Max Kellermann
  2022-03-13  2:37   ` Al Viro
  2022-03-13  1:49 ` [PATCH 1/4] include/pipe_fs_i.h: add missing #includes Al Viro
  3 siblings, 1 reply; 10+ messages in thread
From: Max Kellermann @ 2022-02-25 18:54 UTC (permalink / raw)
  To: viro, linux-fsdevel, linux-kernel; +Cc: Max Kellermann

Adds one central function which shall be used to initialize a newly
allocated struct pipe_buffer.  This shall make the pipe code more
robust for the next time the pipe_buffer struct gets modified, to
avoid leaving new members uninitialized.  Instead, adding new members
should also add a new pipe_buf_init() parameter, which causes
compile-time errors in call sites that were not adapted.

This commit doesn't refactor fs/fuse/dev.c because this code looks
obscure to me; it initializes pipe_buffers incrementally through a
variety of functions, too complicated for me to understand.

To: Alexander Viro <viro@zeniv.linux.org.uk>
To: linux-fsdevel@vger.kernel.org
To: linux-kernel@vger.kernel.org
Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 fs/pipe.c                 | 11 +++--------
 fs/splice.c               |  9 ++++-----
 include/linux/pipe_fs_i.h | 20 ++++++++++++++++++++
 kernel/watch_queue.c      |  8 +++-----
 lib/iov_iter.c            | 13 +++----------
 5 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index b2075ecd4751..6da11ea9da49 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -518,14 +518,9 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
 
 			/* Insert it into the buffer array */
 			buf = &pipe->bufs[head & mask];
-			buf->page = page;
-			buf->ops = &anon_pipe_buf_ops;
-			buf->offset = 0;
-			buf->len = 0;
-			if (is_packetized(filp))
-				buf->flags = PIPE_BUF_FLAG_PACKET;
-			else
-				buf->flags = PIPE_BUF_FLAG_CAN_MERGE;
+			pipe_buf_init(buf, page, 0, 0,
+				      &anon_pipe_buf_ops,
+				      is_packetized(filp) ? PIPE_BUF_FLAG_PACKET : PIPE_BUF_FLAG_CAN_MERGE);
 			pipe->tmp_page = NULL;
 
 			copied = copy_page_from_iter(page, 0, PAGE_SIZE, from);
diff --git a/fs/splice.c b/fs/splice.c
index 5dbce4dcc1a7..d2e4205acc46 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -200,12 +200,11 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
 	while (!pipe_full(head, tail, pipe->max_usage)) {
 		struct pipe_buffer *buf = &pipe->bufs[head & mask];
 
-		buf->page = spd->pages[page_nr];
-		buf->offset = spd->partial[page_nr].offset;
-		buf->len = spd->partial[page_nr].len;
+		pipe_buf_init(buf, spd->pages[page_nr],
+			      spd->partial[page_nr].offset,
+			      spd->partial[page_nr].len,
+			      spd->ops, 0);
 		buf->private = spd->partial[page_nr].private;
-		buf->ops = spd->ops;
-		buf->flags = 0;
 
 		head++;
 		pipe->head = head;
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index 0e36a58adf0e..61639682cc4e 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -179,6 +179,26 @@ static inline unsigned int pipe_space_for_user(unsigned int head, unsigned int t
 	return p_space;
 }
 
+/**
+ * Initialize a struct pipe_buffer.
+ */
+static inline void pipe_buf_init(struct pipe_buffer *buf,
+				 struct page *page,
+				 unsigned int offset, unsigned int len,
+				 const struct pipe_buf_operations *ops,
+				 unsigned int flags)
+{
+	buf->page = page;
+	buf->offset = offset;
+	buf->len = len;
+	buf->ops = ops;
+	buf->flags = flags;
+
+	/* not initializing the "private" member because it is only
+	   used by pipe_buf_operations which inject it via struct
+	   partial_page / struct splice_pipe_desc */
+}
+
 /**
  * pipe_buf_get - get a reference to a pipe_buffer
  * @pipe:	the pipe that the buffer belongs to
diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
index 9c9eb20dd2c5..34720138cc22 100644
--- a/kernel/watch_queue.c
+++ b/kernel/watch_queue.c
@@ -106,12 +106,10 @@ static bool post_one_notification(struct watch_queue *wqueue,
 	kunmap_atomic(p);
 
 	buf = &pipe->bufs[head & mask];
-	buf->page = page;
+	pipe_buf_init(buf, page, offset, len,
+		      &watch_queue_pipe_buf_ops,
+		      PIPE_BUF_FLAG_WHOLE);
 	buf->private = (unsigned long)wqueue;
-	buf->ops = &watch_queue_pipe_buf_ops;
-	buf->offset = offset;
-	buf->len = len;
-	buf->flags = PIPE_BUF_FLAG_WHOLE;
 	pipe->head = head + 1;
 
 	if (!test_and_clear_bit(note, wqueue->notes_bitmap)) {
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 6dd5330f7a99..289e96947fb5 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -413,12 +413,8 @@ static size_t copy_page_to_iter_pipe(struct page *page, size_t offset, size_t by
 	if (pipe_full(i_head, p_tail, pipe->max_usage))
 		return 0;
 
-	buf->ops = &page_cache_pipe_buf_ops;
-	buf->flags = 0;
 	get_page(page);
-	buf->page = page;
-	buf->offset = offset;
-	buf->len = bytes;
+	pipe_buf_init(buf, page, offset, bytes, &page_cache_pipe_buf_ops, 0);
 
 	pipe->head = i_head + 1;
 	i->iov_offset = offset + bytes;
@@ -577,11 +573,8 @@ static size_t push_pipe(struct iov_iter *i, size_t size,
 		if (!page)
 			break;
 
-		buf->ops = &default_pipe_buf_ops;
-		buf->flags = 0;
-		buf->page = page;
-		buf->offset = 0;
-		buf->len = min_t(ssize_t, left, PAGE_SIZE);
+		pipe_buf_init(buf, page, 0, min_t(ssize_t, left, PAGE_SIZE),
+			      &default_pipe_buf_ops, 0);
 		left -= buf->len;
 		iter_head++;
 		pipe->head = iter_head;
-- 
2.34.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] include/pipe_fs_i.h: add missing #includes
  2022-02-25 18:54 [PATCH 1/4] include/pipe_fs_i.h: add missing #includes Max Kellermann
                   ` (2 preceding siblings ...)
  2022-02-25 18:54 ` [PATCH 4/4] pipe_fs_i.h: add pipe_buf_init() Max Kellermann
@ 2022-03-13  1:49 ` Al Viro
  2022-03-13  6:45   ` Max Kellermann
  3 siblings, 1 reply; 10+ messages in thread
From: Al Viro @ 2022-03-13  1:49 UTC (permalink / raw)
  To: Max Kellermann; +Cc: linux-fsdevel, linux-kernel

On Fri, Feb 25, 2022 at 07:54:28PM +0100, Max Kellermann wrote:

> diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
> index c00c618ef290..0e36a58adf0e 100644
> --- a/include/linux/pipe_fs_i.h
> +++ b/include/linux/pipe_fs_i.h
> @@ -2,6 +2,9 @@
>  #ifndef _LINUX_PIPE_FS_I_H
>  #define _LINUX_PIPE_FS_I_H
>  
> +#include <linux/mutex.h>
> +#include <linux/wait.h>

TBH, I'd rather avoid breeding chain includes; sure, mutex.h and wait.h
are extremely common anyway.  Oh, well....

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] pipe_fs_i.h: add pipe_buf_init()
  2022-02-25 18:54 ` [PATCH 4/4] pipe_fs_i.h: add pipe_buf_init() Max Kellermann
@ 2022-03-13  2:37   ` Al Viro
  2022-03-13  2:48     ` Matthew Wilcox
  2022-03-13  6:47     ` Max Kellermann
  0 siblings, 2 replies; 10+ messages in thread
From: Al Viro @ 2022-03-13  2:37 UTC (permalink / raw)
  To: Max Kellermann; +Cc: linux-fsdevel, linux-kernel

On Fri, Feb 25, 2022 at 07:54:31PM +0100, Max Kellermann wrote:

>  			/* Insert it into the buffer array */
>  			buf = &pipe->bufs[head & mask];
> -			buf->page = page;
> -			buf->ops = &anon_pipe_buf_ops;
> -			buf->offset = 0;
> -			buf->len = 0;
> -			if (is_packetized(filp))
> -				buf->flags = PIPE_BUF_FLAG_PACKET;
> -			else
> -				buf->flags = PIPE_BUF_FLAG_CAN_MERGE;
> +			pipe_buf_init(buf, page, 0, 0,
> +				      &anon_pipe_buf_ops,
> +				      is_packetized(filp) ? PIPE_BUF_FLAG_PACKET : PIPE_BUF_FLAG_CAN_MERGE);

*cringe*
FWIW, packetized case is very rare, so how about turning that into
			pipe_buf_init(buf, page, 0, 0,
				      &anon_pipe_buf_ops,
				      PIPE_BUF_FLAG_CAN_MERGE);
			if (unlikely(is_packetized(filp)))
				buf->flags = PIPE_BUF_FLAG_PACKET;
Your pipe_buf_init() is inlined, so it shouldn't be worse from the optimizer
POV - it should be able to start with calculating that value and then storing
that, etc.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] pipe_fs_i.h: add pipe_buf_init()
  2022-03-13  2:37   ` Al Viro
@ 2022-03-13  2:48     ` Matthew Wilcox
  2022-03-13  4:34       ` Al Viro
  2022-03-13  6:47     ` Max Kellermann
  1 sibling, 1 reply; 10+ messages in thread
From: Matthew Wilcox @ 2022-03-13  2:48 UTC (permalink / raw)
  To: Al Viro; +Cc: Max Kellermann, linux-fsdevel, linux-kernel

On Sun, Mar 13, 2022 at 02:37:43AM +0000, Al Viro wrote:
> On Fri, Feb 25, 2022 at 07:54:31PM +0100, Max Kellermann wrote:
> 
> >  			/* Insert it into the buffer array */
> >  			buf = &pipe->bufs[head & mask];
> > -			buf->page = page;
> > -			buf->ops = &anon_pipe_buf_ops;
> > -			buf->offset = 0;
> > -			buf->len = 0;
> > -			if (is_packetized(filp))
> > -				buf->flags = PIPE_BUF_FLAG_PACKET;
> > -			else
> > -				buf->flags = PIPE_BUF_FLAG_CAN_MERGE;
> > +			pipe_buf_init(buf, page, 0, 0,
> > +				      &anon_pipe_buf_ops,
> > +				      is_packetized(filp) ? PIPE_BUF_FLAG_PACKET : PIPE_BUF_FLAG_CAN_MERGE);
> 
> *cringe*
> FWIW, packetized case is very rare, so how about turning that into
> 			pipe_buf_init(buf, page, 0, 0,
> 				      &anon_pipe_buf_ops,
> 				      PIPE_BUF_FLAG_CAN_MERGE);
> 			if (unlikely(is_packetized(filp)))
> 				buf->flags = PIPE_BUF_FLAG_PACKET;
> Your pipe_buf_init() is inlined, so it shouldn't be worse from the optimizer
> POV - it should be able to start with calculating that value and then storing
> that, etc.

That's not equivalent.  I think the better option here is to always
initialise flags to 0 (and not have a parameter for it):

			pipe_buf_init(buf, page, 0, 0, &anon_pipe_buf_ops);
			if (is_packetized(filp))
				buf->flags = PIPE_BUF_FLAG_PACKET;
			else
				buf->flags = PIPE_BUF_FLAG_CAN_MERGE;


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] pipe_fs_i.h: add pipe_buf_init()
  2022-03-13  2:48     ` Matthew Wilcox
@ 2022-03-13  4:34       ` Al Viro
  0 siblings, 0 replies; 10+ messages in thread
From: Al Viro @ 2022-03-13  4:34 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: Max Kellermann, linux-fsdevel, linux-kernel

On Sun, Mar 13, 2022 at 02:48:10AM +0000, Matthew Wilcox wrote:

> That's not equivalent.  I think the better option here is to always
> initialise flags to 0 (and not have a parameter for it):
> 
> 			pipe_buf_init(buf, page, 0, 0, &anon_pipe_buf_ops);
> 			if (is_packetized(filp))
> 				buf->flags = PIPE_BUF_FLAG_PACKET;
> 			else
> 				buf->flags = PIPE_BUF_FLAG_CAN_MERGE;

Not equivalent in which sense?  IDGI...  Your variant is basically

	X = 0;
	if (Y == constant)
		X = 1;
	else
		X = 2;

If gcc can optimize that to 

	X = (Y == constant) ? 1 : 2;

it should be able to do the same to
	X = 1;
	if (Y != constant)
		X = 2;

	What obstacles are there, besides a (false) assumption that
X might alias Y?  Which would apply to both variants...  Granted, I'm
half-asleep right now, so I might be missing something obvious...

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] include/pipe_fs_i.h: add missing #includes
  2022-03-13  1:49 ` [PATCH 1/4] include/pipe_fs_i.h: add missing #includes Al Viro
@ 2022-03-13  6:45   ` Max Kellermann
  0 siblings, 0 replies; 10+ messages in thread
From: Max Kellermann @ 2022-03-13  6:45 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-fsdevel, linux-kernel

On 2022/03/13 02:49, Al Viro <viro@zeniv.linux.org.uk> wrote:
> TBH, I'd rather avoid breeding chain includes; sure, mutex.h and wait.h
> are extremely common anyway.  Oh, well....

In my usual coding style, I expect I can include any header and it
will bring its whole dependency chain (which should be as small as
possible, but not smaller).  This seems cleaner to me, because .c
files need to have no insight what a .h file needs (even if the
dependencies are "extremely common").

If the kernel coding style does not consider this useful, we can of
course easily drop that patch.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] pipe_fs_i.h: add pipe_buf_init()
  2022-03-13  2:37   ` Al Viro
  2022-03-13  2:48     ` Matthew Wilcox
@ 2022-03-13  6:47     ` Max Kellermann
  1 sibling, 0 replies; 10+ messages in thread
From: Max Kellermann @ 2022-03-13  6:47 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-fsdevel, linux-kernel

On 2022/03/13 03:37, Al Viro <viro@zeniv.linux.org.uk> wrote:
> *cringe*
> FWIW, packetized case is very rare, so how about turning that into

I have no hard feelings how this API must look like, I only want it to
exist, to reduce code fragility a bit.  Tell me how you want it, and
I'll resubmit.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-03-13  6:51 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-25 18:54 [PATCH 1/4] include/pipe_fs_i.h: add missing #includes Max Kellermann
2022-02-25 18:54 ` [PATCH 2/4] fs/pipe: remove duplicate "offset" initializer Max Kellermann
2022-02-25 18:54 ` [PATCH 3/4] fs/pipe: remove unnecessary "buf" initializer Max Kellermann
2022-02-25 18:54 ` [PATCH 4/4] pipe_fs_i.h: add pipe_buf_init() Max Kellermann
2022-03-13  2:37   ` Al Viro
2022-03-13  2:48     ` Matthew Wilcox
2022-03-13  4:34       ` Al Viro
2022-03-13  6:47     ` Max Kellermann
2022-03-13  1:49 ` [PATCH 1/4] include/pipe_fs_i.h: add missing #includes Al Viro
2022-03-13  6:45   ` Max Kellermann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.