From patchwork Wed Dec 2 11:59:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 1409674 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sipsolutions.net Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=kHtAn0+b; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CmHbH6R9hz9s1l for ; Wed, 2 Dec 2020 23:00:11 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=Htg1vb4lI0U4wFJWTV+3zkDdYaV6PVNe2Gy80iE5hLY=; b=kHtAn0+bbUMMA5PEhslBRJdvS U2Jo+Ym76YTVPafbZR4YSK8nFGXmqdRw4hTU25644qSbUBp/zFs6dZGoF7+GkQGCZ76mRgkqeVVU3 HoHJqEQr+P6bOY0mqCR2PZXCZTf3XSenh06IhyaOVjLxmuBwvyIOruhUt/qA37M+NeEqQw0H0kG5E SWWqav8d5nG/LNYPan40LVJn7+Faj9HXXV4uYwpXV+uWlsm2rz83GG1K6GsXj5geARfEBsGXZovEN 0SSm0BgkgY0u2tI1KTdlLkQY/u+AYBpSdMIVRCwpz+SkOW4901B6iwTgufP/o4VOQ6z9fcC6N5tGC 8lvDpQe6g==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQno-0008QW-F1; Wed, 02 Dec 2020 12:00:08 +0000 Received: from s3.sipsolutions.net ([2a01:4f8:191:4433::2] helo=sipsolutions.net) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQnk-0008Nu-Ee for linux-um@lists.infradead.org; Wed, 02 Dec 2020 12:00:05 +0000 Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.94) (envelope-from ) id 1kkQni-00151z-U9; Wed, 02 Dec 2020 13:00:03 +0100 From: Johannes Berg To: linux-um@lists.infradead.org Subject: [PATCH v2 1/7] um: support dynamic IRQ allocation Date: Wed, 2 Dec 2020 12:59:50 +0100 Message-Id: <20201202125915.23fd804ffc9d.I146af7c40025c748c020888df792d22c80b161e8@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201202115956.42963-1-johannes@sipsolutions.net> References: <20201202115956.42963-1-johannes@sipsolutions.net> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201202_070004_658295_F10CBC8F X-CRM114-Status: GOOD ( 24.93 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Johannes Berg , Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Johannes Berg It's cumbersome and error-prone to keep adding fixed IRQ numbers, and for proper device wakeup support for the virtio/vhost-user support we need to have different IRQs for each device. Even if in theory two IRQs (with and without wake) might be sufficient, it's much easier to reason about it when we have dynamic number assignment. It also makes it easier to add new devices that may dynamically exist or depending on the configuration, etc. Add support for this, up to 64 IRQs (the same limit as epoll FDs we have right now). Since it's not easy to port all the existing places to dynamic allocation (some data is statically initialized) keep the low numbers are reserved for the existing hard-coded IRQ numbers. Acked-By: Anton Ivanov Signed-off-by: Johannes Berg Acked-By: Anton Ivanov --- arch/um/drivers/line.c | 18 ++++++++++----- arch/um/drivers/mconsole_kern.c | 2 +- arch/um/drivers/net_kern.c | 2 +- arch/um/drivers/port_kern.c | 4 ++-- arch/um/drivers/random.c | 2 +- arch/um/drivers/ubd_kern.c | 2 +- arch/um/drivers/vector_kern.c | 4 ++-- arch/um/drivers/virtio_uml.c | 4 ++-- arch/um/drivers/xterm_kern.c | 2 +- arch/um/include/asm/irq.h | 6 ++--- arch/um/include/shared/irq_kern.h | 12 +++++----- arch/um/kernel/irq.c | 37 ++++++++++++++++++++++++++----- arch/um/kernel/sigio.c | 2 +- 13 files changed, 65 insertions(+), 32 deletions(-) diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 14ad9f495fe6..2d68f58ac54b 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -262,19 +262,25 @@ static irqreturn_t line_write_interrupt(int irq, void *data) int line_setup_irq(int fd, int input, int output, struct line *line, void *data) { const struct line_driver *driver = line->driver; - int err = 0; + int err; - if (input) + if (input) { err = um_request_irq(driver->read_irq, fd, IRQ_READ, line_interrupt, IRQF_SHARED, driver->read_irq_name, data); - if (err) - return err; - if (output) + if (err < 0) + return err; + } + + if (output) { err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, line_write_interrupt, IRQF_SHARED, driver->write_irq_name, data); - return err; + if (err < 0) + return err; + } + + return 0; } static int line_activate(struct tty_port *port, struct tty_struct *tty) diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index a2e680f7d39f..6d00af25ec6b 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -738,7 +738,7 @@ static int __init mconsole_init(void) err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, IRQF_SHARED, "mconsole", (void *)sock); - if (err) { + if (err < 0) { printk(KERN_ERR "Failed to get IRQ for management console\n"); goto out; } diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 1802cf4ef5a5..2fc0b038ff8a 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -160,7 +160,7 @@ static int uml_net_open(struct net_device *dev) err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt, IRQF_SHARED, dev->name, dev); - if (err != 0) { + if (err < 0) { printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err); err = -ENETUNREACH; goto out_close; diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index a47ca5376d9d..efa8b7304090 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -100,7 +100,7 @@ static int port_accept(struct port_list *port) .port = port }); if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, - IRQF_SHARED, "telnetd", conn)) { + IRQF_SHARED, "telnetd", conn) < 0) { printk(KERN_ERR "port_accept : failed to get IRQ for " "telnetd\n"); goto out_free; @@ -182,7 +182,7 @@ void *port_data(int port_num) } if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, - IRQF_SHARED, "port", port)) { + IRQF_SHARED, "port", port) < 0) { printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); goto out_close; } diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index ce115fce52f0..385cb08d7ec2 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c @@ -129,7 +129,7 @@ static int __init rng_init (void) err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt, 0, "random", NULL); - if (err) + if (err < 0) goto err_out_cleanup_hw; sigio_broken(random_fd, 1); diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index eae8c83364f7..d4c39e595c72 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1204,7 +1204,7 @@ static int __init ubd_driver_init(void){ } err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 0, "ubd", ubd_devs); - if(err != 0) + if(err < 0) printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); return 0; } diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c index 555203e3e7b4..e78a54ea72a4 100644 --- a/arch/um/drivers/vector_kern.c +++ b/arch/um/drivers/vector_kern.c @@ -1271,7 +1271,7 @@ static int vector_net_open(struct net_device *dev) irq_rr + VECTOR_BASE_IRQ, vp->fds->rx_fd, IRQ_READ, vector_rx_interrupt, IRQF_SHARED, dev->name, dev); - if (err != 0) { + if (err < 0) { netdev_err(dev, "vector_open: failed to get rx irq(%d)\n", err); err = -ENETUNREACH; goto out_close; @@ -1286,7 +1286,7 @@ static int vector_net_open(struct net_device *dev) irq_rr + VECTOR_BASE_IRQ, vp->fds->tx_fd, IRQ_WRITE, vector_tx_interrupt, IRQF_SHARED, dev->name, dev); - if (err != 0) { + if (err < 0) { netdev_err(dev, "vector_open: failed to get tx irq(%d)\n", err); err = -ENETUNREACH; diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index a6c4bb6c2c01..f76b8da28d20 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -412,7 +412,7 @@ static int vhost_user_init_slave_req(struct virtio_uml_device *vu_dev) rc = um_request_irq(VIRTIO_IRQ, vu_dev->req_fd, IRQ_READ, vu_req_interrupt, IRQF_SHARED, vu_dev->pdev->name, vu_dev); - if (rc) + if (rc < 0) goto err_close; rc = vhost_user_send_no_payload_fd(vu_dev, VHOST_USER_SET_SLAVE_REQ_FD, @@ -854,7 +854,7 @@ static int vu_setup_vq_call_fd(struct virtio_uml_device *vu_dev, info->call_fd = call_fds[0]; rc = um_request_irq(VIRTIO_IRQ, info->call_fd, IRQ_READ, vu_interrupt, IRQF_SHARED, info->name, vq); - if (rc) + if (rc < 0) goto close_both; rc = vhost_user_set_vring_call(vu_dev, vq->index, call_fds[1]); diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c index d64ef6d0d463..50f11b7b4774 100644 --- a/arch/um/drivers/xterm_kern.c +++ b/arch/um/drivers/xterm_kern.c @@ -51,7 +51,7 @@ int xterm_fd(int socket, int *pid_out) err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, IRQF_SHARED, "xterm", data); - if (err) { + if (err < 0) { printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " "err = %d\n", err); ret = err; diff --git a/arch/um/include/asm/irq.h b/arch/um/include/asm/irq.h index 42c6205e2dc4..b6fa6301c75b 100644 --- a/arch/um/include/asm/irq.h +++ b/arch/um/include/asm/irq.h @@ -24,14 +24,14 @@ #define VECTOR_BASE_IRQ (VIRTIO_IRQ + 1) #define VECTOR_IRQ_SPACE 8 -#define LAST_IRQ (VECTOR_IRQ_SPACE + VECTOR_BASE_IRQ - 1) +#define UM_FIRST_DYN_IRQ (VECTOR_IRQ_SPACE + VECTOR_BASE_IRQ) #else -#define LAST_IRQ VIRTIO_IRQ +#define UM_FIRST_DYN_IRQ (VIRTIO_IRQ + 1) #endif -#define NR_IRQS (LAST_IRQ + 1) +#define NR_IRQS 64 #endif diff --git a/arch/um/include/shared/irq_kern.h b/arch/um/include/shared/irq_kern.h index 7cd1a10c6244..7c04a0fd3a27 100644 --- a/arch/um/include/shared/irq_kern.h +++ b/arch/um/include/shared/irq_kern.h @@ -9,10 +9,10 @@ #include #include -extern int um_request_irq(unsigned int irq, int fd, int type, - irq_handler_t handler, - unsigned long irqflags, const char * devname, - void *dev_id); -void um_free_irq(unsigned int irq, void *dev); -#endif +#define UM_IRQ_ALLOC -1 +int um_request_irq(int irq, int fd, int type, irq_handler_t handler, + unsigned long irqflags, const char * devname, + void *dev_id); +void um_free_irq(int irq, void *dev_id); +#endif diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 3577118bb4a5..b94c72f56617 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -19,6 +19,7 @@ #include #include #include +#include extern void free_irqs(void); @@ -38,6 +39,7 @@ struct irq_entry { static struct irq_entry *active_fds; static DEFINE_SPINLOCK(irq_lock); +static DECLARE_BITMAP(irqs_allocated, NR_IRQS); static void irq_io_loop(struct irq_fd *irq, struct uml_pt_regs *regs) { @@ -421,27 +423,52 @@ unsigned int do_IRQ(int irq, struct uml_pt_regs *regs) return 1; } -void um_free_irq(unsigned int irq, void *dev) +void um_free_irq(int irq, void *dev) { + if (WARN(irq < 0 || irq > NR_IRQS, "freeing invalid irq %d", irq)) + return; + free_irq_by_irq_and_dev(irq, dev); free_irq(irq, dev); + clear_bit(irq, irqs_allocated); } EXPORT_SYMBOL(um_free_irq); -int um_request_irq(unsigned int irq, int fd, int type, +int um_request_irq(int irq, int fd, int type, irq_handler_t handler, unsigned long irqflags, const char * devname, void *dev_id) { int err; + if (irq == UM_IRQ_ALLOC) { + int i; + + for (i = UM_FIRST_DYN_IRQ; i < NR_IRQS; i++) { + if (!test_and_set_bit(i, irqs_allocated)) { + irq = i; + break; + } + } + } + + if (irq < 0) + return -ENOSPC; + if (fd != -1) { err = activate_fd(irq, fd, type, dev_id); if (err) - return err; + goto error; } - return request_irq(irq, handler, irqflags, devname, dev_id); + err = request_irq(irq, handler, irqflags, devname, dev_id); + if (err < 0) + goto error; + + return irq; +error: + clear_bit(irq, irqs_allocated); + return err; } EXPORT_SYMBOL(um_request_irq); @@ -480,7 +507,7 @@ void __init init_IRQ(void) irq_set_chip_and_handler(TIMER_IRQ, &SIGVTALRM_irq_type, handle_edge_irq); - for (i = 1; i <= LAST_IRQ; i++) + for (i = 1; i < NR_IRQS; i++) irq_set_chip_and_handler(i, &normal_irq_type, handle_edge_irq); /* Initialize EPOLL Loop */ os_setup_epoll(); diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c index d1cffc2a7f21..5085a50c3b8c 100644 --- a/arch/um/kernel/sigio.c +++ b/arch/um/kernel/sigio.c @@ -25,7 +25,7 @@ int write_sigio_irq(int fd) err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, 0, "write sigio", NULL); - if (err) { + if (err < 0) { printk(KERN_ERR "write_sigio_irq : um_request_irq failed, " "err = %d\n", err); return -1; From patchwork Wed Dec 2 11:59:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 1409675 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sipsolutions.net Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=zy2Vd9oM; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CmHbK1hcYz9sTL for ; Wed, 2 Dec 2020 23:00:13 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=Yg+0FQKdKO/gu7dWlJJVXCxMqTjUKUCRjwYVPGwHj74=; b=zy2Vd9oM3ujRxikAmB7ueouhf WEfy0e8VadRyBCoRR8AIfmmiC7/1L2PioOM9932kwi9CNJPSitE6wmafwrner8xH/s6hDAJXkoDam kQpqBj0M0xUSsu3Vu7ec1Qq1m+++zA5FtxroDRPBzFLKQcgugRWUjt1yVirZVzPC/plZJHuaXa7+l INTQCzzP2813iF7XBAq3T2ZgkJrIajcyVqa1i36TObRZ040/JrIKkBk2tAckxznuoNh0xpmbEZOsF OqCyHd9+u6mOogQXCEE1PGxfl1z48Tah+Q5o3nJqUauKcdvbkci6F9MumViA6sH96eEiIFJATrrD+ Qga6R7JOQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQnp-0008R9-Ml; Wed, 02 Dec 2020 12:00:09 +0000 Received: from s3.sipsolutions.net ([2a01:4f8:191:4433::2] helo=sipsolutions.net) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQnl-0008O7-2z for linux-um@lists.infradead.org; Wed, 02 Dec 2020 12:00:07 +0000 Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.94) (envelope-from ) id 1kkQnj-00151z-7k; Wed, 02 Dec 2020 13:00:03 +0100 From: Johannes Berg To: linux-um@lists.infradead.org Subject: [PATCH v2 2/7] um: virtio: use dynamic IRQ allocation Date: Wed, 2 Dec 2020 12:59:51 +0100 Message-Id: <20201202125915.d5cbac8ab2de.Id7bf6cf5659579ac53cce88552126e4d98a74e3d@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201202115956.42963-1-johannes@sipsolutions.net> References: <20201202115956.42963-1-johannes@sipsolutions.net> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201202_070005_202222_638050D9 X-CRM114-Status: GOOD ( 14.26 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Johannes Berg , Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Johannes Berg This separates the devices, which is better for debug and for later suspend/resume and wakeup support, since there we'll have to separate which IRQs can wake up the system and which cannot. Acked-By: Anton Ivanov Signed-off-by: Johannes Berg Acked-By: Anton Ivanov --- arch/um/drivers/virtio_uml.c | 22 ++++++++++++++-------- arch/um/include/asm/irq.h | 5 ++--- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index f76b8da28d20..94b112749d5b 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -55,7 +55,7 @@ struct virtio_uml_device { struct platform_device *pdev; spinlock_t sock_lock; - int sock, req_fd; + int sock, req_fd, irq; u64 features; u64 protocol_features; u8 status; @@ -409,12 +409,14 @@ static int vhost_user_init_slave_req(struct virtio_uml_device *vu_dev) return rc; vu_dev->req_fd = req_fds[0]; - rc = um_request_irq(VIRTIO_IRQ, vu_dev->req_fd, IRQ_READ, + rc = um_request_irq(UM_IRQ_ALLOC, vu_dev->req_fd, IRQ_READ, vu_req_interrupt, IRQF_SHARED, vu_dev->pdev->name, vu_dev); if (rc < 0) goto err_close; + vu_dev->irq = rc; + rc = vhost_user_send_no_payload_fd(vu_dev, VHOST_USER_SET_SLAVE_REQ_FD, req_fds[1]); if (rc) @@ -423,7 +425,7 @@ static int vhost_user_init_slave_req(struct virtio_uml_device *vu_dev) goto out; err_free_irq: - um_free_irq(VIRTIO_IRQ, vu_dev); + um_free_irq(vu_dev->irq, vu_dev); err_close: os_close_file(req_fds[0]); out: @@ -802,7 +804,11 @@ static void vu_del_vq(struct virtqueue *vq) struct virtio_uml_vq_info *info = vq->priv; if (info->call_fd >= 0) { - um_free_irq(VIRTIO_IRQ, vq); + struct virtio_uml_device *vu_dev; + + vu_dev = to_virtio_uml_device(vq->vdev); + + um_free_irq(vu_dev->irq, vq); os_close_file(info->call_fd); } @@ -852,7 +858,7 @@ static int vu_setup_vq_call_fd(struct virtio_uml_device *vu_dev, return rc; info->call_fd = call_fds[0]; - rc = um_request_irq(VIRTIO_IRQ, info->call_fd, IRQ_READ, + rc = um_request_irq(vu_dev->irq, info->call_fd, IRQ_READ, vu_interrupt, IRQF_SHARED, info->name, vq); if (rc < 0) goto close_both; @@ -864,7 +870,7 @@ static int vu_setup_vq_call_fd(struct virtio_uml_device *vu_dev, goto out; release_irq: - um_free_irq(VIRTIO_IRQ, vq); + um_free_irq(vu_dev->irq, vq); close_both: os_close_file(call_fds[0]); out: @@ -969,7 +975,7 @@ static struct virtqueue *vu_setup_vq(struct virtio_device *vdev, error_setup: if (info->call_fd >= 0) { - um_free_irq(VIRTIO_IRQ, vq); + um_free_irq(vu_dev->irq, vq); os_close_file(info->call_fd); } error_call: @@ -1078,7 +1084,7 @@ static void virtio_uml_release_dev(struct device *d) /* might not have been opened due to not negotiating the feature */ if (vu_dev->req_fd >= 0) { - um_free_irq(VIRTIO_IRQ, vu_dev); + um_free_irq(vu_dev->irq, vu_dev); os_close_file(vu_dev->req_fd); } diff --git a/arch/um/include/asm/irq.h b/arch/um/include/asm/irq.h index b6fa6301c75b..547bff7b3a89 100644 --- a/arch/um/include/asm/irq.h +++ b/arch/um/include/asm/irq.h @@ -17,18 +17,17 @@ #define TELNETD_IRQ 12 #define XTERM_IRQ 13 #define RANDOM_IRQ 14 -#define VIRTIO_IRQ 15 #ifdef CONFIG_UML_NET_VECTOR -#define VECTOR_BASE_IRQ (VIRTIO_IRQ + 1) +#define VECTOR_BASE_IRQ (RANDOM_IRQ + 1) #define VECTOR_IRQ_SPACE 8 #define UM_FIRST_DYN_IRQ (VECTOR_IRQ_SPACE + VECTOR_BASE_IRQ) #else -#define UM_FIRST_DYN_IRQ (VIRTIO_IRQ + 1) +#define UM_FIRST_DYN_IRQ (RANDOM_IRQ + 1) #endif From patchwork Wed Dec 2 11:59:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 1409673 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sipsolutions.net Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=iLNVaayL; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CmHbJ4Yy1z9sRK for ; Wed, 2 Dec 2020 23:00:12 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=BMGtsQ4e5YTENlS72SK1tebmYyXucRGjY7fZ6S7y+4Y=; b=iLNVaayLdd8Zm1sxyrPMB4wiR mCBVli9rvbbGbSBL8fTdJdDgE9nVqjiHIjzDtRN26/XVsW3F1lcyvlidyFPbk5u2K9kDK/ldvasOU p9PtcmkAFMMmrTlSasYy7aif6/06GchemU7C9pFNOWQhWjIN9pzcJFh0VdPajyyd+6tMQlhiV0XUQ svgq+sdNl/knyToDQxmujw3VI2RXKRMLrQ6BVk1XNwWUzKi6od4RxFCiq7wRI29WcEldMPJhrBGtU mVCvq5TSKxxxfVkpv1W7pitf1TomtySZtskp3Jf6bIYZleD0GqzozBKg9tcsr3Ng2NPhcHNQDriR9 vRgFmWzJg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQnp-0008Qp-35; Wed, 02 Dec 2020 12:00:09 +0000 Received: from s3.sipsolutions.net ([2a01:4f8:191:4433::2] helo=sipsolutions.net) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQnl-0008O6-2M for linux-um@lists.infradead.org; Wed, 02 Dec 2020 12:00:05 +0000 Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.94) (envelope-from ) id 1kkQnj-00151z-GS; Wed, 02 Dec 2020 13:00:03 +0100 From: Johannes Berg To: linux-um@lists.infradead.org Subject: [PATCH v2 3/7] um: clean up alarm IRQ chip name Date: Wed, 2 Dec 2020 12:59:52 +0100 Message-Id: <20201202125915.db46a482942e.I782d052498e91373788c1650029d3571a26e4bdf@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201202115956.42963-1-johannes@sipsolutions.net> References: <20201202115956.42963-1-johannes@sipsolutions.net> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201202_070005_158278_554FEB93 X-CRM114-Status: GOOD ( 13.21 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Johannes Berg , Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Johannes Berg We don't use "SIGVTALRM", it's just SIGALRM. Clean up the naming. While at it, fix the comment's grammar. Acked-By: Anton Ivanov Signed-off-by: Johannes Berg Acked-By: Anton Ivanov --- arch/um/kernel/irq.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index b94c72f56617..97ff77c297c8 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -481,7 +481,7 @@ static void dummy(struct irq_data *d) { } -/* This is used for everything else than the timer. */ +/* This is used for everything other than the timer. */ static struct irq_chip normal_irq_type = { .name = "SIGIO", .irq_disable = dummy, @@ -491,8 +491,8 @@ static struct irq_chip normal_irq_type = { .irq_unmask = dummy, }; -static struct irq_chip SIGVTALRM_irq_type = { - .name = "SIGVTALRM", +static struct irq_chip alarm_irq_type = { + .name = "SIGALRM", .irq_disable = dummy, .irq_enable = dummy, .irq_ack = dummy, @@ -504,8 +504,7 @@ void __init init_IRQ(void) { int i; - irq_set_chip_and_handler(TIMER_IRQ, &SIGVTALRM_irq_type, handle_edge_irq); - + irq_set_chip_and_handler(TIMER_IRQ, &alarm_irq_type, handle_edge_irq); for (i = 1; i < NR_IRQS; i++) irq_set_chip_and_handler(i, &normal_irq_type, handle_edge_irq); From patchwork Wed Dec 2 11:59:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 1409677 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sipsolutions.net Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=ezhxxT88; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CmHbL2HqQz9sVw for ; Wed, 2 Dec 2020 23:00:14 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=UyOmWmGjGgItJmb0OWlQRa99psFUXnzvhkucak4wyMo=; b=ezhxxT88AMndT8vtq0FnB+wNU 5JYkTMQV1144CgAf0Pqqu7Ju6/lY64F8GjDWh3ptz+5o2cVyXiN+FDqZrzvc/zpK4XCnfdqOK0UwD guiDoSyN2P9dsr2xJIqYC+WG++a2diFLPwQVUZub1DRb2dEz+8yhueBFTanFCA77hu3S+3HYKDe1R j6Kf5jJkbC4eizFL9RoXuL/Iqnpbo1zP+ZQnu/33JMtgAee20CSZWhoWzsIn7SmOOgQEyf7rmcv1h KLtwxZ1B1yloYK8zzdnONMn9RT8BV6M/87qrEbb1jQaCFgMDXs7s+w8cn7u+HoqIjQtaEV7DhduM4 JlsEVZoZA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQnq-0008Ro-VJ; Wed, 02 Dec 2020 12:00:10 +0000 Received: from s3.sipsolutions.net ([2a01:4f8:191:4433::2] helo=sipsolutions.net) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQnl-0008O8-76 for linux-um@lists.infradead.org; Wed, 02 Dec 2020 12:00:07 +0000 Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.94) (envelope-from ) id 1kkQnj-00151z-Py; Wed, 02 Dec 2020 13:00:03 +0100 From: Johannes Berg To: linux-um@lists.infradead.org Subject: [PATCH v2 4/7] um: irq: clean up and rename struct irq_fd Date: Wed, 2 Dec 2020 12:59:53 +0100 Message-Id: <20201202125915.f289768bd564.I24e33736cb579395f3005b9500b0b8c111983b03@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201202115956.42963-1-johannes@sipsolutions.net> References: <20201202115956.42963-1-johannes@sipsolutions.net> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201202_070005_379261_506363AB X-CRM114-Status: GOOD ( 20.92 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Johannes Berg , Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Johannes Berg This really shouldn't be called "irq_fd" since it doesn't carry an fd. Well, it used to, apparently, but that struct member is unused. Rename it to "irq_reg" since it more accurately reflects a registered interrupt, and remove the unused 'next' and 'fd' members from the struct as well. While at it, also move it to the implementation, it's not used anywhere else, and the header file is shared with the userspace components. Acked-By: Anton Ivanov Signed-off-by: Johannes Berg Acked-By: Anton Ivanov --- arch/um/include/shared/irq_user.h | 14 ------------- arch/um/kernel/irq.c | 34 ++++++++++++++++++++----------- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/arch/um/include/shared/irq_user.h b/arch/um/include/shared/irq_user.h index 107751dce153..2dd5fd7d9443 100644 --- a/arch/um/include/shared/irq_user.h +++ b/arch/um/include/shared/irq_user.h @@ -9,25 +9,11 @@ #include #include -struct irq_fd { - struct irq_fd *next; - void *id; - int fd; - int type; - int irq; - int events; - bool active; - bool pending; - bool purge; -}; - #define IRQ_READ 0 #define IRQ_WRITE 1 #define IRQ_NONE 2 #define MAX_IRQ_TYPE (IRQ_NONE + 1) - - struct siginfo; extern void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); extern void free_irq_by_fd(int fd); diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 97ff77c297c8..923a80c9808a 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -26,14 +26,24 @@ extern void free_irqs(void); /* When epoll triggers we do not know why it did so * we can also have different IRQs for read and write. - * This is why we keep a small irq_fd array for each fd - + * This is why we keep a small irq_reg array for each fd - * one entry per IRQ type */ +struct irq_reg { + void *id; + int type; + int irq; + int events; + bool active; + bool pending; + bool purge; +}; + struct irq_entry { struct irq_entry *next; int fd; - struct irq_fd *irq_array[MAX_IRQ_TYPE + 1]; + struct irq_reg *irq_array[MAX_IRQ_TYPE + 1]; }; static struct irq_entry *active_fds; @@ -41,7 +51,7 @@ static struct irq_entry *active_fds; static DEFINE_SPINLOCK(irq_lock); static DECLARE_BITMAP(irqs_allocated, NR_IRQS); -static void irq_io_loop(struct irq_fd *irq, struct uml_pt_regs *regs) +static void irq_io_loop(struct irq_reg *irq, struct uml_pt_regs *regs) { /* * irq->active guards against reentry @@ -65,7 +75,7 @@ static void irq_io_loop(struct irq_fd *irq, struct uml_pt_regs *regs) void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) { struct irq_entry *irq_entry; - struct irq_fd *irq; + struct irq_reg *irq; int n, i, j; @@ -86,7 +96,7 @@ void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) } for (i = 0; i < n ; i++) { - /* Epoll back reference is the entry with 3 irq_fd + /* Epoll back reference is the entry with 3 irq_reg * leaves - one for each irq type. */ irq_entry = (struct irq_entry *) @@ -112,7 +122,7 @@ static int assign_epoll_events_to_irq(struct irq_entry *irq_entry) { int i; int events = 0; - struct irq_fd *irq; + struct irq_reg *irq; for (i = 0; i < MAX_IRQ_TYPE ; i++) { irq = irq_entry->irq_array[i]; @@ -131,7 +141,7 @@ static int assign_epoll_events_to_irq(struct irq_entry *irq_entry) static int activate_fd(int irq, int fd, int type, void *dev_id) { - struct irq_fd *new_fd; + struct irq_reg *new_fd; struct irq_entry *irq_entry; int i, err, events; unsigned long flags; @@ -182,13 +192,13 @@ static int activate_fd(int irq, int fd, int type, void *dev_id) /* New entry for this fd */ err = -ENOMEM; - new_fd = kmalloc(sizeof(struct irq_fd), GFP_ATOMIC); + new_fd = kmalloc(sizeof(struct irq_reg), GFP_ATOMIC); if (new_fd == NULL) goto out_unlock; events = os_event_mask(type); - *new_fd = ((struct irq_fd) { + *new_fd = ((struct irq_reg) { .id = dev_id, .irq = irq, .type = type, @@ -273,8 +283,8 @@ static struct irq_entry *get_irq_entry_by_fd(int fd) /* * Walk the IRQ list and dispose of an entry for a specific - * device, fd and number. Note - if sharing an IRQ for read - * and writefor the same FD it will be disposed in either case. + * device and number. Note - if sharing an IRQ for read + * and write for the same FD it will be disposed in either case. * If this behaviour is undesirable use different IRQ ids. */ @@ -289,7 +299,7 @@ static void do_free_by_irq_and_dev( ) { int i; - struct irq_fd *to_free; + struct irq_reg *to_free; for (i = 0; i < MAX_IRQ_TYPE ; i++) { if (irq_entry->irq_array[i] != NULL) { From patchwork Wed Dec 2 11:59:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 1409676 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sipsolutions.net Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=0dD0O7ES; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CmHbK5td1z9sVl for ; Wed, 2 Dec 2020 23:00:13 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=oP0fBf31QEdv4LJwViyUAEVZcKEesL3Xtjk/ZCy3N/M=; b=0dD0O7ESdAha4tZl2nBvBBDH6 h/ouMUmSTBKN1t3gk+7vU+5gnCZWUKI70Bc8wtja1MsYYNUP0l1ygE2VO/LxICCf80GLhuA0SvUa/ NWOJWnp+7jwldG1xED4mFUlJIOyoPYPA4io+Jk49NwM9TZo+e6nZUfJpBtRiu//spUIASB9mNdEcQ eZ6i6saj3WTa13+be9TbtSBqc29TfDBNd3bLd736jm6/Tv/jWz6NGb5sNPSsTy02dkniUrV0y0U4h 4ZVwGcCE57jcvCaSQSfLneIitRW5gGKy101exLoy/JHmk78NnRupd2A8/QiJd3bl6ainAsgXlaMi2 T7+CTTEWg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQnq-0008RV-Cv; Wed, 02 Dec 2020 12:00:10 +0000 Received: from s3.sipsolutions.net ([2a01:4f8:191:4433::2] helo=sipsolutions.net) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQnl-0008OI-8b for linux-um@lists.infradead.org; Wed, 02 Dec 2020 12:00:07 +0000 Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.94) (envelope-from ) id 1kkQnk-00151z-38; Wed, 02 Dec 2020 13:00:04 +0100 From: Johannes Berg To: linux-um@lists.infradead.org Subject: [PATCH v2 5/7] um: irq: reduce irq_reg allocation Date: Wed, 2 Dec 2020 12:59:54 +0100 Message-Id: <20201202125915.069ecd8bffe6.I3351860a05d7ec403e2abc5337660c9d9726f095@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201202115956.42963-1-johannes@sipsolutions.net> References: <20201202115956.42963-1-johannes@sipsolutions.net> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201202_070005_394889_DA7B1B7D X-CRM114-Status: GOOD ( 14.80 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Johannes Berg Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Johannes Berg We don't need an array of 4 entries to capture three and the name 'MAX_IRQ_TYPE' really gets confusing as well. Remove it and add a correct NUM_IRQ_TYPES, and use that correctly. Signed-off-by: Johannes Berg Acked-By: Anton Ivanov --- arch/um/include/shared/irq_user.h | 2 +- arch/um/kernel/irq.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/um/include/shared/irq_user.h b/arch/um/include/shared/irq_user.h index 2dd5fd7d9443..5e975a9e8354 100644 --- a/arch/um/include/shared/irq_user.h +++ b/arch/um/include/shared/irq_user.h @@ -12,7 +12,7 @@ #define IRQ_READ 0 #define IRQ_WRITE 1 #define IRQ_NONE 2 -#define MAX_IRQ_TYPE (IRQ_NONE + 1) +#define NUM_IRQ_TYPES (IRQ_NONE + 1) struct siginfo; extern void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 923a80c9808a..93eb742ecafe 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -43,7 +43,7 @@ struct irq_reg { struct irq_entry { struct irq_entry *next; int fd; - struct irq_reg *irq_array[MAX_IRQ_TYPE + 1]; + struct irq_reg *irq_array[NUM_IRQ_TYPES]; }; static struct irq_entry *active_fds; @@ -101,7 +101,7 @@ void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) */ irq_entry = (struct irq_entry *) os_epoll_get_data_pointer(i); - for (j = 0; j < MAX_IRQ_TYPE ; j++) { + for (j = 0; j < NUM_IRQ_TYPES ; j++) { irq = irq_entry->irq_array[j]; if (irq == NULL) continue; @@ -124,7 +124,7 @@ static int assign_epoll_events_to_irq(struct irq_entry *irq_entry) int events = 0; struct irq_reg *irq; - for (i = 0; i < MAX_IRQ_TYPE ; i++) { + for (i = 0; i < NUM_IRQ_TYPES ; i++) { irq = irq_entry->irq_array[i]; if (irq != NULL) events = irq->events | events; @@ -172,7 +172,7 @@ static int activate_fd(int irq, int fd, int type, void *dev_id) goto out_unlock; } irq_entry->fd = fd; - for (i = 0; i < MAX_IRQ_TYPE; i++) + for (i = 0; i < NUM_IRQ_TYPES; i++) irq_entry->irq_array[i] = NULL; irq_entry->next = active_fds; active_fds = irq_entry; @@ -244,7 +244,7 @@ static void garbage_collect_irq_entries(void) walk = active_fds; while (walk != NULL) { reap = true; - for (i = 0; i < MAX_IRQ_TYPE ; i++) { + for (i = 0; i < NUM_IRQ_TYPES ; i++) { if (walk->irq_array[i] != NULL) { reap = false; break; @@ -301,7 +301,7 @@ static void do_free_by_irq_and_dev( int i; struct irq_reg *to_free; - for (i = 0; i < MAX_IRQ_TYPE ; i++) { + for (i = 0; i < NUM_IRQ_TYPES ; i++) { if (irq_entry->irq_array[i] != NULL) { if ( ((flags & IGNORE_IRQ) || From patchwork Wed Dec 2 11:59:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 1409678 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sipsolutions.net Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=t9itrA1q; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CmHbM3Jf9z9sRK for ; Wed, 2 Dec 2020 23:00:15 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=uWZTH4DxJwVhEAYQlecm9tA9v8lDRP6ClHOgLcTtW+M=; b=t9itrA1qMkG8MnJtoQhCPi5/c GmrwV3QXz7pxB9xZFEdYaDXqbp/i9CDhin6TwQR3lwP3Vd2vKC2cWIB3CXmwv8RuG9FCuzYyPrsQJ SDkjuafg6bJGwzw8+j7MTJ3okTGVeexknNgUxzkOl0dMJC5kwtJBmM0EApSy3uObwJ1fnDweBlRwe r2FBUzS5I5+CkbqRLOnklt1RSyxX0M/35UCljLQJTfb1AlH1NomZL0cn9QMmrBLkxP7RQJKXVJdRJ 73SAFkkyhuXoqLaii1bnvVle2IjTY/oI5t+fhFLxqpiCUHJok0Pew+JWSEdTwGdfVWsJhydg78ltn E2GfMD4tA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQnr-0008SA-HX; Wed, 02 Dec 2020 12:00:11 +0000 Received: from s3.sipsolutions.net ([2a01:4f8:191:4433::2] helo=sipsolutions.net) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQnl-0008OS-HI for linux-um@lists.infradead.org; Wed, 02 Dec 2020 12:00:08 +0000 Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.94) (envelope-from ) id 1kkQnk-00151z-Bq; Wed, 02 Dec 2020 13:00:04 +0100 From: Johannes Berg To: linux-um@lists.infradead.org Subject: [PATCH v2 6/7] um: remove IRQ_NONE type Date: Wed, 2 Dec 2020 12:59:55 +0100 Message-Id: <20201202125915.c5309340fc3e.Id467f02803b7fb8edf0255d7588e63a01ca9c1e8@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201202115956.42963-1-johannes@sipsolutions.net> References: <20201202115956.42963-1-johannes@sipsolutions.net> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201202_070005_733384_2B854B9A X-CRM114-Status: GOOD ( 23.79 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Johannes Berg , Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Johannes Berg We don't actually use this in um_request_irq(), so it can never be assigned. It's also not clear what that would be useful for, so just remove it. This results in quite a number of cleanups, all the way to removing the "SIGIO on close" startup check, since the data it assigns (pty_close_sigio) is not used anymore. While at it, also make this an enum so we get a minimum of type checking, and remove the IRQ_NONE hack in virtio since we now no longer have the name twice. Acked-By: Anton Ivanov Signed-off-by: Johannes Berg Acked-By: Anton Ivanov --- arch/um/drivers/random.c | 2 +- arch/um/drivers/virtio_uml.c | 5 ----- arch/um/include/shared/irq_kern.h | 7 ++++--- arch/um/include/shared/irq_user.h | 9 +++++---- arch/um/include/shared/os.h | 6 +++--- arch/um/kernel/irq.c | 15 +++++++-------- arch/um/os-Linux/irq.c | 2 +- arch/um/os-Linux/sigio.c | 25 +++++-------------------- 8 files changed, 26 insertions(+), 45 deletions(-) diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index 385cb08d7ec2..efbf88ec48ac 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c @@ -132,7 +132,7 @@ static int __init rng_init (void) if (err < 0) goto err_out_cleanup_hw; - sigio_broken(random_fd, 1); + sigio_broken(random_fd); err = misc_register (&rng_miscdev); if (err) { diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index 94b112749d5b..27e92d3881ff 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -33,11 +33,6 @@ #include #include "vhost_user.h" -/* Workaround due to a conflict between irq_user.h and irqreturn.h */ -#ifdef IRQ_NONE -#undef IRQ_NONE -#endif - #define MAX_SUPPORTED_QUEUE_SIZE 256 #define to_virtio_uml_device(_vdev) \ diff --git a/arch/um/include/shared/irq_kern.h b/arch/um/include/shared/irq_kern.h index 7c04a0fd3a27..7807de593bda 100644 --- a/arch/um/include/shared/irq_kern.h +++ b/arch/um/include/shared/irq_kern.h @@ -8,11 +8,12 @@ #include #include +#include "irq_user.h" #define UM_IRQ_ALLOC -1 -int um_request_irq(int irq, int fd, int type, irq_handler_t handler, - unsigned long irqflags, const char * devname, - void *dev_id); +int um_request_irq(int irq, int fd, enum um_irq_type type, + irq_handler_t handler, unsigned long irqflags, + const char *devname, void *dev_id); void um_free_irq(int irq, void *dev_id); #endif diff --git a/arch/um/include/shared/irq_user.h b/arch/um/include/shared/irq_user.h index 5e975a9e8354..07239e801a5b 100644 --- a/arch/um/include/shared/irq_user.h +++ b/arch/um/include/shared/irq_user.h @@ -9,10 +9,11 @@ #include #include -#define IRQ_READ 0 -#define IRQ_WRITE 1 -#define IRQ_NONE 2 -#define NUM_IRQ_TYPES (IRQ_NONE + 1) +enum um_irq_type { + IRQ_READ, + IRQ_WRITE, + NUM_IRQ_TYPES, +}; struct siginfo; extern void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index f467d28fc0b4..e2bb7e488d59 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -299,7 +299,7 @@ extern void reboot_skas(void); extern int os_waiting_for_events_epoll(void); extern void *os_epoll_get_data_pointer(int index); extern int os_epoll_triggered(int index, int events); -extern int os_event_mask(int irq_type); +extern int os_event_mask(enum um_irq_type irq_type); extern int os_setup_epoll(void); extern int os_add_epoll_fd(int events, int fd, void *data); extern int os_mod_epoll_fd(int events, int fd, void *data); @@ -310,8 +310,8 @@ extern void os_close_epoll_fd(void); /* sigio.c */ extern int add_sigio_fd(int fd); extern int ignore_sigio_fd(int fd); -extern void maybe_sigio_broken(int fd, int read); -extern void sigio_broken(int fd, int read); +extern void maybe_sigio_broken(int fd); +extern void sigio_broken(int fd); /* prctl.c */ extern int os_arch_prctl(int pid, int option, unsigned long *arg2); diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 93eb742ecafe..9e8f776bb43a 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -32,7 +32,7 @@ extern void free_irqs(void); struct irq_reg { void *id; - int type; + enum um_irq_type type; int irq; int events; bool active; @@ -96,7 +96,7 @@ void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) } for (i = 0; i < n ; i++) { - /* Epoll back reference is the entry with 3 irq_reg + /* Epoll back reference is the entry with 2 irq_reg * leaves - one for each irq type. */ irq_entry = (struct irq_entry *) @@ -139,7 +139,7 @@ static int assign_epoll_events_to_irq(struct irq_entry *irq_entry) -static int activate_fd(int irq, int fd, int type, void *dev_id) +static int activate_fd(int irq, int fd, enum um_irq_type type, void *dev_id) { struct irq_reg *new_fd; struct irq_entry *irq_entry; @@ -217,7 +217,7 @@ static int activate_fd(int irq, int fd, int type, void *dev_id) /* Turn back IO on with the correct (new) IO event mask */ assign_epoll_events_to_irq(irq_entry); spin_unlock_irqrestore(&irq_lock, flags); - maybe_sigio_broken(fd, (type != IRQ_NONE)); + maybe_sigio_broken(fd); return 0; out_unlock: @@ -444,10 +444,9 @@ void um_free_irq(int irq, void *dev) } EXPORT_SYMBOL(um_free_irq); -int um_request_irq(int irq, int fd, int type, - irq_handler_t handler, - unsigned long irqflags, const char * devname, - void *dev_id) +int um_request_irq(int irq, int fd, enum um_irq_type type, + irq_handler_t handler, unsigned long irqflags, + const char *devname, void *dev_id) { int err; diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index d508310ee5e1..aa90a05b3d78 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c @@ -45,7 +45,7 @@ int os_epoll_triggered(int index, int events) * access to the right includes/defines for EPOLL constants. */ -int os_event_mask(int irq_type) +int os_event_mask(enum um_irq_type irq_type) { if (irq_type == IRQ_READ) return EPOLLIN | EPOLLPRI; diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 75558080d0bf..233b2b2212f1 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -336,7 +336,7 @@ static void write_sigio_workaround(void) close(l_write_sigio_fds[1]); } -void sigio_broken(int fd, int read) +void sigio_broken(int fd) { int err; @@ -352,7 +352,7 @@ void sigio_broken(int fd, int read) all_sigio_fds.poll[all_sigio_fds.used++] = ((struct pollfd) { .fd = fd, - .events = read ? POLLIN : POLLOUT, + .events = POLLIN, .revents = 0 }); out: sigio_unlock(); @@ -360,17 +360,16 @@ void sigio_broken(int fd, int read) /* Changed during early boot */ static int pty_output_sigio; -static int pty_close_sigio; -void maybe_sigio_broken(int fd, int read) +void maybe_sigio_broken(int fd) { if (!isatty(fd)) return; - if ((read || pty_output_sigio) && (!read || pty_close_sigio)) + if (pty_output_sigio) return; - sigio_broken(fd, read); + sigio_broken(fd); } static void sigio_cleanup(void) @@ -514,19 +513,6 @@ static void tty_output(int master, int slave) printk(UM_KERN_CONT "tty_output : read failed, err = %d\n", n); } -static void tty_close(int master, int slave) -{ - printk(UM_KERN_INFO "Checking that host ptys support SIGIO on " - "close..."); - - close(slave); - if (got_sigio) { - printk(UM_KERN_CONT "Yes\n"); - pty_close_sigio = 1; - } else - printk(UM_KERN_CONT "No, enabling workaround\n"); -} - static void __init check_sigio(void) { if ((access("/dev/ptmx", R_OK) < 0) && @@ -536,7 +522,6 @@ static void __init check_sigio(void) return; } check_one_sigio(tty_output); - check_one_sigio(tty_close); } /* Here because it only does the SIGIO testing for now */ From patchwork Wed Dec 2 11:59:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 1409679 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sipsolutions.net Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=Hnipnn2I; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CmHbM4874z9sW0 for ; Wed, 2 Dec 2020 23:00:15 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=+fndVlwC0B4W2b8BMUaHEoTVja4dN7nA0V62DibbHnY=; b=Hnipnn2If/y+RaYUWAR0/oxa1 NSttaqOFTQcjN/shRI2RyYtD3H+T1V33VYtSRjcCWqoepR7faTh7ebE8Vv/XG9Gei+19MP4+NXvjy OFy7N2xOmkSDxfQWKJpuAdq1HYO6Xu0lSVtwwEB0CfVv4/AI9Mqj+8u7xr0efbcmQh1O0PPUSeBcq ueOoECcZx0kTkJCZE3fshqqBcQtocBltNxXbI6qqoHzvOly4NIoZPmTsgWmMIW0+PjUrW1LgE0C+W Y4atRMjv2+X7OwLB/HVWQlmZIoAZSYSaQ1SCgK9joLMrCTN3gA6WjD9pXYmegH75AA3q8c5iOM25Q sDNel+f7w==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQns-0008SW-0E; Wed, 02 Dec 2020 12:00:12 +0000 Received: from s3.sipsolutions.net ([2a01:4f8:191:4433::2] helo=sipsolutions.net) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kkQnl-0008Ok-QS for linux-um@lists.infradead.org; Wed, 02 Dec 2020 12:00:09 +0000 Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.94) (envelope-from ) id 1kkQnk-00151z-JR; Wed, 02 Dec 2020 13:00:04 +0100 From: Johannes Berg To: linux-um@lists.infradead.org Subject: [PATCH v2 7/7] um: simplify IRQ handling code Date: Wed, 2 Dec 2020 12:59:56 +0100 Message-Id: <20201202125915.762ac2a43be6.I811873233b8d71fbde9154b84c85b498521e3b12@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201202115956.42963-1-johannes@sipsolutions.net> References: <20201202115956.42963-1-johannes@sipsolutions.net> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201202_070006_090546_D274CAC6 X-CRM114-Status: GOOD ( 29.35 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Johannes Berg Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Johannes Berg Reduce dynamic allocations (and thereby cache misses) by simply embedding the registration data for IRQs in the irq_entry, we never supported these being really dynamic anyway as only one was ever allowed ("Trying to reregister ..."). Lockless behaviour is preserved by removing the FD from the poll set appropriately, but we use reg->events to indicate whether or not this entry is used, rather than dynamically allocating them. Also port the list of IRQ entries to list_head instead of the current open-coded singly-linked list implementation, just for sanity. Signed-off-by: Johannes Berg Acked-By: Anton Ivanov --- arch/um/kernel/irq.c | 370 +++++++++++++++---------------------------- 1 file changed, 128 insertions(+), 242 deletions(-) diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 9e8f776bb43a..482269580b79 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -29,26 +29,23 @@ extern void free_irqs(void); * This is why we keep a small irq_reg array for each fd - * one entry per IRQ type */ - struct irq_reg { void *id; - enum um_irq_type type; int irq; + /* it's cheaper to store this than to query it */ int events; bool active; bool pending; - bool purge; }; struct irq_entry { - struct irq_entry *next; + struct list_head list; int fd; - struct irq_reg *irq_array[NUM_IRQ_TYPES]; + struct irq_reg reg[NUM_IRQ_TYPES]; }; -static struct irq_entry *active_fds; - static DEFINE_SPINLOCK(irq_lock); +static LIST_HEAD(active_fds); static DECLARE_BITMAP(irqs_allocated, NR_IRQS); static void irq_io_loop(struct irq_reg *irq, struct uml_pt_regs *regs) @@ -61,12 +58,13 @@ static void irq_io_loop(struct irq_reg *irq, struct uml_pt_regs *regs) */ if (irq->active) { irq->active = false; + do { irq->pending = false; do_IRQ(irq->irq, regs); - } while (irq->pending && (!irq->purge)); - if (!irq->purge) - irq->active = true; + } while (irq->pending); + + irq->active = true; } else { irq->pending = true; } @@ -75,9 +73,7 @@ static void irq_io_loop(struct irq_reg *irq, struct uml_pt_regs *regs) void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) { struct irq_entry *irq_entry; - struct irq_reg *irq; - - int n, i, j; + int n, i; while (1) { /* This is now lockless - epoll keeps back-referencesto the irqs @@ -96,21 +92,18 @@ void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) } for (i = 0; i < n ; i++) { - /* Epoll back reference is the entry with 2 irq_reg - * leaves - one for each irq type. - */ - irq_entry = (struct irq_entry *) - os_epoll_get_data_pointer(i); - for (j = 0; j < NUM_IRQ_TYPES ; j++) { - irq = irq_entry->irq_array[j]; - if (irq == NULL) + enum um_irq_type t; + + irq_entry = os_epoll_get_data_pointer(i); + + for (t = 0; t < NUM_IRQ_TYPES; t++) { + int events = irq_entry->reg[t].events; + + if (!events) continue; - if (os_epoll_triggered(i, irq->events) > 0) - irq_io_loop(irq, regs); - if (irq->purge) { - irq_entry->irq_array[j] = NULL; - kfree(irq); - } + + if (os_epoll_triggered(i, events) > 0) + irq_io_loop(&irq_entry->reg[t], regs); } } } @@ -118,32 +111,59 @@ void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) free_irqs(); } -static int assign_epoll_events_to_irq(struct irq_entry *irq_entry) +static struct irq_entry *get_irq_entry_by_fd(int fd) { - int i; - int events = 0; - struct irq_reg *irq; + struct irq_entry *walk; - for (i = 0; i < NUM_IRQ_TYPES ; i++) { - irq = irq_entry->irq_array[i]; - if (irq != NULL) - events = irq->events | events; - } - if (events > 0) { - /* os_add_epoll will call os_mod_epoll if this already exists */ - return os_add_epoll_fd(events, irq_entry->fd, irq_entry); + lockdep_assert_held(&irq_lock); + + list_for_each_entry(walk, &active_fds, list) { + if (walk->fd == fd) + return walk; } - /* No events - delete */ - return os_del_epoll_fd(irq_entry->fd); + + return NULL; +} + +static void free_irq_entry(struct irq_entry *to_free, bool remove) +{ + if (!to_free) + return; + + if (remove) + os_del_epoll_fd(to_free->fd); + list_del(&to_free->list); + kfree(to_free); } +static bool update_irq_entry(struct irq_entry *entry) +{ + enum um_irq_type i; + int events = 0; + + for (i = 0; i < NUM_IRQ_TYPES; i++) + events |= entry->reg[i].events; + if (events) { + /* will modify (instead of add) if needed */ + os_add_epoll_fd(events, entry->fd, entry); + return true; + } + + os_del_epoll_fd(entry->fd); + return false; +} + +static void update_or_free_irq_entry(struct irq_entry *entry) +{ + if (!update_irq_entry(entry)) + free_irq_entry(entry, false); +} static int activate_fd(int irq, int fd, enum um_irq_type type, void *dev_id) { - struct irq_reg *new_fd; struct irq_entry *irq_entry; - int i, err, events; + int err, events = os_event_mask(type); unsigned long flags; err = os_set_fd_async(fd); @@ -151,73 +171,34 @@ static int activate_fd(int irq, int fd, enum um_irq_type type, void *dev_id) goto out; spin_lock_irqsave(&irq_lock, flags); - - /* Check if we have an entry for this fd */ - - err = -EBUSY; - for (irq_entry = active_fds; - irq_entry != NULL; irq_entry = irq_entry->next) { - if (irq_entry->fd == fd) - break; - } - - if (irq_entry == NULL) { - /* This needs to be atomic as it may be called from an - * IRQ context. - */ - irq_entry = kmalloc(sizeof(struct irq_entry), GFP_ATOMIC); - if (irq_entry == NULL) { - printk(KERN_ERR - "Failed to allocate new IRQ entry\n"); + irq_entry = get_irq_entry_by_fd(fd); + if (irq_entry) { + /* cannot register the same FD twice with the same type */ + if (WARN_ON(irq_entry->reg[type].events)) { + err = -EALREADY; goto out_unlock; } - irq_entry->fd = fd; - for (i = 0; i < NUM_IRQ_TYPES; i++) - irq_entry->irq_array[i] = NULL; - irq_entry->next = active_fds; - active_fds = irq_entry; - } - - /* Check if we are trying to re-register an interrupt for a - * particular fd - */ - if (irq_entry->irq_array[type] != NULL) { - printk(KERN_ERR - "Trying to reregister IRQ %d FD %d TYPE %d ID %p\n", - irq, fd, type, dev_id - ); - goto out_unlock; + /* temporarily disable to avoid IRQ-side locking */ + os_del_epoll_fd(fd); } else { - /* New entry for this fd */ - - err = -ENOMEM; - new_fd = kmalloc(sizeof(struct irq_reg), GFP_ATOMIC); - if (new_fd == NULL) + irq_entry = kzalloc(sizeof(*irq_entry), GFP_ATOMIC); + if (!irq_entry) { + err = -ENOMEM; goto out_unlock; - - events = os_event_mask(type); - - *new_fd = ((struct irq_reg) { - .id = dev_id, - .irq = irq, - .type = type, - .events = events, - .active = true, - .pending = false, - .purge = false - }); - /* Turn off any IO on this fd - allows us to - * avoid locking the IRQ loop - */ - os_del_epoll_fd(irq_entry->fd); - irq_entry->irq_array[type] = new_fd; + } + irq_entry->fd = fd; + list_add_tail(&irq_entry->list, &active_fds); + maybe_sigio_broken(fd); } - /* Turn back IO on with the correct (new) IO event mask */ - assign_epoll_events_to_irq(irq_entry); + irq_entry->reg[type].id = dev_id; + irq_entry->reg[type].irq = irq; + irq_entry->reg[type].active = true; + irq_entry->reg[type].events = events; + + WARN_ON(!update_irq_entry(irq_entry)); spin_unlock_irqrestore(&irq_lock, flags); - maybe_sigio_broken(fd); return 0; out_unlock: @@ -227,104 +208,10 @@ static int activate_fd(int irq, int fd, enum um_irq_type type, void *dev_id) } /* - * Walk the IRQ list and dispose of any unused entries. - * Should be done under irq_lock. + * Remove the entry or entries for a specific FD, if you + * don't want to remove all the possible entries then use + * um_free_irq() or deactivate_fd() instead. */ - -static void garbage_collect_irq_entries(void) -{ - int i; - bool reap; - struct irq_entry *walk; - struct irq_entry *previous = NULL; - struct irq_entry *to_free; - - if (active_fds == NULL) - return; - walk = active_fds; - while (walk != NULL) { - reap = true; - for (i = 0; i < NUM_IRQ_TYPES ; i++) { - if (walk->irq_array[i] != NULL) { - reap = false; - break; - } - } - if (reap) { - if (previous == NULL) - active_fds = walk->next; - else - previous->next = walk->next; - to_free = walk; - } else { - to_free = NULL; - } - walk = walk->next; - kfree(to_free); - } -} - -/* - * Walk the IRQ list and get the descriptor for our FD - */ - -static struct irq_entry *get_irq_entry_by_fd(int fd) -{ - struct irq_entry *walk = active_fds; - - while (walk != NULL) { - if (walk->fd == fd) - return walk; - walk = walk->next; - } - return NULL; -} - - -/* - * Walk the IRQ list and dispose of an entry for a specific - * device and number. Note - if sharing an IRQ for read - * and write for the same FD it will be disposed in either case. - * If this behaviour is undesirable use different IRQ ids. - */ - -#define IGNORE_IRQ 1 -#define IGNORE_DEV (1<<1) - -static void do_free_by_irq_and_dev( - struct irq_entry *irq_entry, - unsigned int irq, - void *dev, - int flags -) -{ - int i; - struct irq_reg *to_free; - - for (i = 0; i < NUM_IRQ_TYPES ; i++) { - if (irq_entry->irq_array[i] != NULL) { - if ( - ((flags & IGNORE_IRQ) || - (irq_entry->irq_array[i]->irq == irq)) && - ((flags & IGNORE_DEV) || - (irq_entry->irq_array[i]->id == dev)) - ) { - /* Turn off any IO on this fd - allows us to - * avoid locking the IRQ loop - */ - os_del_epoll_fd(irq_entry->fd); - to_free = irq_entry->irq_array[i]; - irq_entry->irq_array[i] = NULL; - assign_epoll_events_to_irq(irq_entry); - if (to_free->active) - to_free->purge = true; - else - kfree(to_free); - } - } - } -} - void free_irq_by_fd(int fd) { struct irq_entry *to_free; @@ -332,58 +219,64 @@ void free_irq_by_fd(int fd) spin_lock_irqsave(&irq_lock, flags); to_free = get_irq_entry_by_fd(fd); - if (to_free != NULL) { - do_free_by_irq_and_dev( - to_free, - -1, - NULL, - IGNORE_IRQ | IGNORE_DEV - ); - } - garbage_collect_irq_entries(); + free_irq_entry(to_free, true); spin_unlock_irqrestore(&irq_lock, flags); } EXPORT_SYMBOL(free_irq_by_fd); static void free_irq_by_irq_and_dev(unsigned int irq, void *dev) { - struct irq_entry *to_free; + struct irq_entry *entry; unsigned long flags; spin_lock_irqsave(&irq_lock, flags); - to_free = active_fds; - while (to_free != NULL) { - do_free_by_irq_and_dev( - to_free, - irq, - dev, - 0 - ); - to_free = to_free->next; + list_for_each_entry(entry, &active_fds, list) { + enum um_irq_type i; + + for (i = 0; i < NUM_IRQ_TYPES; i++) { + struct irq_reg *reg = &entry->reg[i]; + + if (!reg->events) + continue; + if (reg->irq != irq) + continue; + if (reg->id != dev) + continue; + + os_del_epoll_fd(entry->fd); + reg->events = 0; + update_or_free_irq_entry(entry); + goto out; + } } - garbage_collect_irq_entries(); +out: spin_unlock_irqrestore(&irq_lock, flags); } - void deactivate_fd(int fd, int irqnum) { - struct irq_entry *to_free; + struct irq_entry *entry; unsigned long flags; + enum um_irq_type i; os_del_epoll_fd(fd); + spin_lock_irqsave(&irq_lock, flags); - to_free = get_irq_entry_by_fd(fd); - if (to_free != NULL) { - do_free_by_irq_and_dev( - to_free, - irqnum, - NULL, - IGNORE_DEV - ); + entry = get_irq_entry_by_fd(fd); + if (!entry) + goto out; + + for (i = 0; i < NUM_IRQ_TYPES; i++) { + if (!entry->reg[i].events) + continue; + if (entry->reg[i].irq == irqnum) + entry->reg[i].events = 0; } - garbage_collect_irq_entries(); + + update_or_free_irq_entry(entry); +out: spin_unlock_irqrestore(&irq_lock, flags); + ignore_sigio_fd(fd); } EXPORT_SYMBOL(deactivate_fd); @@ -396,24 +289,17 @@ EXPORT_SYMBOL(deactivate_fd); */ int deactivate_all_fds(void) { - struct irq_entry *to_free; + struct irq_entry *entry; /* Stop IO. The IRQ loop has no lock so this is our * only way of making sure we are safe to dispose * of all IRQ handlers */ os_set_ioignore(); - to_free = active_fds; - while (to_free != NULL) { - do_free_by_irq_and_dev( - to_free, - -1, - NULL, - IGNORE_IRQ | IGNORE_DEV - ); - to_free = to_free->next; - } - /* don't garbage collect - we can no longer call kfree() here */ + + /* we can no longer call kfree() here so just deactivate */ + list_for_each_entry(entry, &active_fds, list) + os_del_epoll_fd(entry->fd); os_close_epoll_fd(); return 0; }