Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp6487888ybl; Wed, 15 Jan 2020 05:33:58 -0800 (PST) X-Google-Smtp-Source: APXvYqx+wrlNng4z74K3R8IMDjn2lKJA2a5EkleeaqAe2Tc8sdjx0+e9MkTtKJ/yyv0kWlvrAUPk X-Received: by 2002:a9d:2dca:: with SMTP id g68mr2531464otb.150.1579095238317; Wed, 15 Jan 2020 05:33:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579095238; cv=none; d=google.com; s=arc-20160816; b=FsjIV1ekvPLP5lA43edCW9soN9QxArioZy37Hu5PX4r2RojsI8OopL++ml354GNdYb p9awIQqZruT9rePGTaHtAFUIfkZZTV2CCOgUImCIplJv0OYb3wO9C1cwpLIHDHvDHvgx q4hBoyIPe9TshxnGiRsHvmyxTcvs6XS5Us9U5Cm7AjdlMTVOu6ERq3NTaa+2z3SgWr8t eL5NEReU38WuoNIXEn1h6SnwLV+zA0c0vegGwglVYBut+sV+l7TSg2bdHsS5TawMI6us LVWI3XsoplxEp+zcwcXjln4BbzCq1+OaoMV1g6MQ/os3VUTSRKWB8PWipxHECceR2XJr +cjg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject:organization:dkim-signature; bh=5OUJAHYH+7n8PLYu9ubyf15U0YG0j5mfxr+AIsbzQTk=; b=EbTIyrwQMUmlax5odhH5sEErkpYR45SF2epG7GazkHP5Tu9R+zsyQ3XjJYSKWbBgMk ByLkEaGFfyf6n7cAngz3aPI2+j6B86ebPVRwKy6AIha/EDGLu78+1PQ1nXQKJIZP7nGR tmUBkMH5sGSPNDu60jjqGPwXndGfHTcECxZByqXXOQZqD+3uyyFv86Rn8cEZJ/BFzk70 hB1o93G8aJlZxqbj6TYgh/FnkpsDMB6SDEZ/sbKbuu3D0DxY8ATr5Bid60x7QDGwKdy0 yWUrkzOi/G2sSUFcvoC4FMsAcuyfHAeyzGgBeqEWrr+uSH64ZzGSPAYAkBQn8gfxdOKM HiPA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=cFxAkFfU; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z16si11031321otk.80.2020.01.15.05.33.44; Wed, 15 Jan 2020 05:33:58 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=cFxAkFfU; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729327AbgAONcG (ORCPT + 99 others); Wed, 15 Jan 2020 08:32:06 -0500 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:35096 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729277AbgAONcF (ORCPT ); Wed, 15 Jan 2020 08:32:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1579095123; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5OUJAHYH+7n8PLYu9ubyf15U0YG0j5mfxr+AIsbzQTk=; b=cFxAkFfUATfFd4q2PaG/mqNeNVqh/6He7A1bxMqiyNXIC4lDj8I8mtrBJbPnUqzZ6DDlif 8Jul7yBjYwAdmrkoUdziQyGggg4YcFZ1MH+HrLqR2TrCIvuGU4e70wDFBoTYhQLSrmCTbM 96BvqJKPzrrZKZ+jOXHHJpYBSDb5w4A= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-143-TzWTsey8NmWLhCGQNyuDpA-1; Wed, 15 Jan 2020 08:32:02 -0500 X-MC-Unique: TzWTsey8NmWLhCGQNyuDpA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id ADA2D800D5A; Wed, 15 Jan 2020 13:31:59 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-120-52.rdu2.redhat.com [10.10.120.52]) by smtp.corp.redhat.com (Postfix) with ESMTP id CAFFB60BE0; Wed, 15 Jan 2020 13:31:56 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [RFC PATCH 09/14] pipe: Add notification lossage handling [ver #3] From: David Howells To: torvalds@linux-foundation.org Cc: dhowells@redhat.com, Greg Kroah-Hartman , Casey Schaufler , Stephen Smalley , nicolas.dichtel@6wind.com, raven@themaw.net, Christian Brauner , 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 Date: Wed, 15 Jan 2020 13:31:56 +0000 Message-ID: <157909511604.20155.1902245459684441811.stgit@warthog.procyon.org.uk> In-Reply-To: <157909503552.20155.3030058841911628518.stgit@warthog.procyon.org.uk> References: <157909503552.20155.3030058841911628518.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- fs/pipe.c | 28 ++++++++++++++++++++++++++++ include/linux/pipe_fs_i.h | 7 +++++++ kernel/watch_queue.c | 2 ++ samples/watch_queue/watch_test.c | 3 +++ 4 files changed, 40 insertions(+) diff --git a/fs/pipe.c b/fs/pipe.c index 05d0b02ed08d..423aafca4338 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -311,6 +311,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 (!pipe_empty(head, tail)) { struct pipe_buffer *buf = &pipe->bufs[tail & mask]; size_t chars = buf->len; @@ -352,6 +376,10 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) if (!buf->len) { pipe_buf_release(pipe, buf); spin_lock_irq(&pipe->wait.lock); +#ifdef CONFIG_WATCH_QUEUE + if (buf->flags & PIPE_BUF_FLAG_LOSS) + pipe->note_loss = true; +#endif tail++; pipe->tail = tail; spin_unlock_irq(&pipe->wait.lock); diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index f86ae087aaca..810eb2b1efc6 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 @@ -55,6 +59,9 @@ struct pipe_inode_info { unsigned int tail; unsigned int max_usage; unsigned int ring_size; +#ifdef CONFIG_WATCH_QUEUE + bool note_loss; +#endif unsigned int nr_accounted; unsigned int readers; unsigned int writers; diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c index a01f2fed0983..d48f422f391a 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 924e13a49c37..0eaff5dc04c3 100644 --- a/samples/watch_queue/watch_test.c +++ b/samples/watch_queue/watch_test.c @@ -120,6 +120,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;