From: David Howells <dhowells@redhat.com> To: torvalds@linux-foundation.org Cc: dhowells@redhat.com, Casey Schaufler <casey@schaufler-ca.com>, Stephen Smalley <sds@tycho.nsa.gov>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, nicolas.dichtel@6wind.com, raven@themaw.net, Christian Brauner <christian@brauner.io>, dhowells@redhat.com, keyrings@vger.kernel.org, linux-usb@vger.kernel.org, linux-block@vger.kernel.org, linux-security-module@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-api@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 16/21] pipe: Add notification lossage handling Date: Tue, 15 Oct 2019 22:50:13 +0100 [thread overview] Message-ID: <157117621377.15019.972929561165477583.stgit@warthog.procyon.org.uk> (raw) In-Reply-To: <157117606853.15019.15459271147790470307.stgit@warthog.procyon.org.uk> Add handling for loss of notifications by having read() insert a loss-notification message after it has read the pipe buffer that was last in the ring when the loss occurred. Lossage can come about either by running out of notification descriptors or by running out of space in the pipe ring. Signed-off-by: David Howells <dhowells@redhat.com> --- fs/pipe.c | 26 ++++++++++++++++++++++++++ include/linux/pipe_fs_i.h | 5 +++++ kernel/watch_queue.c | 2 ++ samples/watch_queue/watch_test.c | 3 +++ 4 files changed, 36 insertions(+) diff --git a/fs/pipe.c b/fs/pipe.c index f4c9d5480636..4685fa6d6c56 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -291,6 +291,30 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) unsigned int tail = pipe->tail; unsigned int mask = pipe->ring_size - 1; +#ifdef CONFIG_WATCH_QUEUE + if (pipe->note_loss) { + struct watch_notification n; + + if (total_len < 8) { + if (ret == 0) + ret = -ENOBUFS; + break; + } + + n.type = WATCH_TYPE_META; + n.subtype = WATCH_META_LOSS_NOTIFICATION; + n.info = watch_sizeof(n); + if (copy_to_iter(&n, sizeof(n), to) != sizeof(n)) { + if (ret == 0) + ret = -EFAULT; + break; + } + ret += sizeof(n); + total_len -= sizeof(n); + pipe->note_loss = false; + } +#endif + if (tail != head) { struct pipe_buffer *buf = &pipe->bufs[tail & mask]; size_t chars = buf->len; @@ -332,6 +356,8 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) if (!buf->len) { pipe_buf_release(pipe, buf); spin_lock_irq(&pipe->wait.lock); + if (buf->flags & PIPE_BUF_FLAG_LOSS) + pipe->note_loss = true; tail++; pipe_commit_read(pipe, tail); do_wakeup = 1; diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 58583ba056e8..66822b39626e 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -9,6 +9,9 @@ #define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */ #define PIPE_BUF_FLAG_PACKET 0x08 /* read() as a packet */ #define PIPE_BUF_FLAG_WHOLE 0x10 /* read() must return entire buffer or error */ +#ifdef CONFIG_WATCH_QUEUE +#define PIPE_BUF_FLAG_LOSS 0x20 /* Message loss happened after this buffer */ +#endif /** * struct pipe_buffer - a linux kernel pipe buffer @@ -33,6 +36,7 @@ struct pipe_buffer { * @wait: reader/writer wait point in case of empty/full pipe * @head: The point of buffer production * @tail: The point of buffer consumption + * @note_loss: The next read() should insert a data-lost message * @max_usage: The maximum number of slots that may be used in the ring * @ring_size: total number of buffers (should be a power of 2) * @nr_accounted: The amount this pipe accounts for in user->pipe_bufs @@ -56,6 +60,7 @@ struct pipe_inode_info { unsigned int tail; unsigned int max_usage; unsigned int ring_size; + bool note_loss; unsigned int nr_accounted; unsigned int readers; unsigned int writers; diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c index f1d78da5309d..c7a3d8cef378 100644 --- a/kernel/watch_queue.c +++ b/kernel/watch_queue.c @@ -132,6 +132,8 @@ static bool post_one_notification(struct watch_queue *wqueue, return done; lost: + buf = &pipe->bufs[(head - 1) & mask]; + buf->flags |= PIPE_BUF_FLAG_LOSS; goto out; } diff --git a/samples/watch_queue/watch_test.c b/samples/watch_queue/watch_test.c index 363f1d77386f..1ffed42bfece 100644 --- a/samples/watch_queue/watch_test.c +++ b/samples/watch_queue/watch_test.c @@ -121,6 +121,9 @@ static void consumer(int fd) (n.n.info & WATCH_INFO_ID) >> WATCH_INFO_ID__SHIFT); break; + case WATCH_META_LOSS_NOTIFICATION: + printf("-- LOSS --\n"); + break; default: printf("other meta record\n"); break;
next prev parent reply other threads:[~2019-10-15 21:50 UTC|newest] Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-10-15 21:47 [RFC PATCH 00/21] pipe: Keyrings, Block and USB notifications David Howells 2019-10-15 21:47 ` [RFC PATCH 01/21] pipe: Reduce #inclusion of pipe_fs_i.h David Howells 2019-10-15 21:48 ` [RFC PATCH 02/21] Add a prelocked wake-up David Howells 2019-10-15 22:14 ` Linus Torvalds 2019-10-16 17:02 ` Tim Chen 2019-10-15 22:33 ` David Howells 2019-10-16 14:26 ` David Howells 2019-10-16 15:31 ` Linus Torvalds 2019-10-15 21:48 ` [RFC PATCH 03/21] pipe: Use head and tail pointers for the ring, not cursor and length David Howells 2019-10-16 7:46 ` Rasmus Villemoes 2019-10-17 10:53 ` David Howells 2019-10-15 21:48 ` [RFC PATCH 04/21] pipe: Advance tail pointer inside of wait spinlock in pipe_read() David Howells 2019-10-15 21:48 ` [RFC PATCH 05/21] pipe: Conditionalise wakeup " David Howells 2019-10-15 21:48 ` [RFC PATCH 06/21] pipe: Rearrange sequence in pipe_write() to preallocate slot David Howells 2019-10-15 21:48 ` [RFC PATCH 07/21] pipe: Remove redundant wakeup from pipe_write() David Howells 2019-10-15 21:49 ` [RFC PATCH 08/21] pipe: Check for ring full inside of the spinlock in pipe_write() David Howells 2019-10-15 22:20 ` Linus Torvalds 2019-10-15 21:49 ` [RFC PATCH 09/21] uapi: General notification queue definitions David Howells 2019-10-15 21:49 ` [RFC PATCH 10/21] security: Add hooks to rule on setting a watch David Howells 2019-10-15 21:49 ` [RFC PATCH 11/21] security: Add a hook for the point of notification insertion David Howells 2019-10-15 21:49 ` [RFC PATCH 12/21] pipe: Add general notification queue support David Howells 2019-10-15 21:49 ` [RFC PATCH 13/21] keys: Add a notification facility David Howells 2019-10-15 21:49 ` [RFC PATCH 14/21] Add sample notification program David Howells 2019-10-15 21:50 ` [RFC PATCH 15/21] pipe: Allow buffers to be marked read-whole-or-error for notifications David Howells 2019-10-15 21:50 ` David Howells [this message] 2019-10-15 21:50 ` [RFC PATCH 17/21] Add a general, global device notification watch list David Howells 2019-10-15 21:50 ` [RFC PATCH 18/21] block: Add block layer notifications David Howells 2019-10-15 21:50 ` [RFC PATCH 19/21] usb: Add USB subsystem notifications David Howells 2019-10-15 21:50 ` [RFC PATCH 20/21] selinux: Implement the watch_key security hook David Howells 2019-10-15 21:50 ` [RFC PATCH 21/21] smack: Implement the watch_key and post_notification hooks David Howells 2019-10-15 22:11 ` [RFC PATCH 00/21] pipe: Keyrings, Block and USB notifications James Morris 2019-10-15 22:32 ` Linus Torvalds
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=157117621377.15019.972929561165477583.stgit@warthog.procyon.org.uk \ --to=dhowells@redhat.com \ --cc=casey@schaufler-ca.com \ --cc=christian@brauner.io \ --cc=gregkh@linuxfoundation.org \ --cc=keyrings@vger.kernel.org \ --cc=linux-api@vger.kernel.org \ --cc=linux-block@vger.kernel.org \ --cc=linux-fsdevel@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-security-module@vger.kernel.org \ --cc=linux-usb@vger.kernel.org \ --cc=nicolas.dichtel@6wind.com \ --cc=raven@themaw.net \ --cc=sds@tycho.nsa.gov \ --cc=torvalds@linux-foundation.org \ --subject='Re: [RFC PATCH 16/21] pipe: Add notification lossage handling' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).