Received: by 2002:a25:e7d8:0:0:0:0:0 with SMTP id e207csp1037548ybh; Wed, 18 Mar 2020 13:47:59 -0700 (PDT) X-Google-Smtp-Source: ADFU+vvB/Vjh1Vt7Jzb8WqObeFUwYZNQde47KRfanfVYZHYYMuj5iJf/yDUbPEaOOMAzm0K6zdTg X-Received: by 2002:a9d:6443:: with SMTP id m3mr5419139otl.20.1584564478695; Wed, 18 Mar 2020 13:47:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1584564478; cv=none; d=google.com; s=arc-20160816; b=rezG7xGTCYE2VXZpTw9r2pTzaRiO7nhnc7AGBvvjZlXeDsGqeuWHb2g9ZBGh0/yNA3 lY9ByygEMLf4RzjC5sRtYB016Nsyx6rIGwGqdiMF6kTbGHbpcgAsikvPGa3TplyXPW+k UR+8ka7YR11yphQRh7gXA8Lqwb/tc2I+daTNxBISccPCgHWZNWJ35Of7/GTBY5hMJIXs vzd2KPm7BP6DgBYO9AZWqYdjn9ipdr+ZVDJlkJnw99foqbro6z66mskME6R6f88QnpJx SCLbvtSWKF/6pd54eUjBJppdAeOYuFAqoRU4uu6foreYzfisPvmX8WUW5jbTWY5GLLIo WBRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:subject:cc:to :from:date:user-agent:message-id; bh=IMa97JSEO4qO6Yg2/cDyrqhGT6GfZ6rKLlKqdPg4bVU=; b=egpbRz+OhZkbMrhh3E0l079P892WMCGJxjtoWGTtNjaQehLcnr3/5tEGmdaGuhe1G0 VmJG/37Ku/0uuNiNNn4ZK+vgwOAsIkAyO3RuzjA98KMEY92qPQ+iaLMdql/st3RHQyLy iMkfEaYSoeK7uGgY/Sy8V7GtM9qNb9DFcy4nthmQaytvzzP6kZmNXWEnQQpZD3W0Mhoq /mRxJdPG2a9zsAw6N9QjxwB75Ls9ypQkd0ARmcGN/WYHUvD5dJGfddTt7EqxTviP4mm1 Ll6H4QpRmWltPDpqIDFckqx6hrVBLJIdaV2k2FhRvCGllUiMVvzMeSZvEe36oKO5JZ0p Y4sw== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r184si3639424oie.79.2020.03.18.13.47.44; Wed, 18 Mar 2020 13:47:58 -0700 (PDT) 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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727093AbgCRUrV (ORCPT + 99 others); Wed, 18 Mar 2020 16:47:21 -0400 Received: from Galois.linutronix.de ([193.142.43.55]:58397 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726631AbgCRUrR (ORCPT ); Wed, 18 Mar 2020 16:47:17 -0400 Received: from p5de0bf0b.dip0.t-ipconnect.de ([93.224.191.11] helo=nanos.tec.linutronix.de) by Galois.linutronix.de with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1jEfaH-00065h-5J; Wed, 18 Mar 2020 21:46:37 +0100 Received: from nanos.tec.linutronix.de (localhost [IPv6:::1]) by nanos.tec.linutronix.de (Postfix) with ESMTP id 79FA31040C6; Wed, 18 Mar 2020 21:46:35 +0100 (CET) Message-Id: <20200318204407.607241357@linutronix.de> User-Agent: quilt/0.65 Date: Wed, 18 Mar 2020 21:43:04 +0100 From: Thomas Gleixner To: LKML Cc: Peter Zijlstra , Linus Torvalds , Ingo Molnar , Will Deacon , "Paul E . McKenney" , Joel Fernandes , Steven Rostedt , Randy Dunlap , Sebastian Andrzej Siewior , Kurt Schwemmer , Logan Gunthorpe , Bjorn Helgaas , linux-pci@vger.kernel.org, Felipe Balbi , Greg Kroah-Hartman , linux-usb@vger.kernel.org, Kalle Valo , "David S. Miller" , linux-wireless@vger.kernel.org, netdev@vger.kernel.org, Oleg Nesterov , Davidlohr Bueso , Michael Ellerman , Arnd Bergmann , linuxppc-dev@lists.ozlabs.org Subject: [patch V2 02/15] pci/switchtec: Replace completion wait queue usage for poll References: <20200318204302.693307984@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sebastian Andrzej Siewior The poll callback is using the completion wait queue and sticks it into poll_wait() to wake up pollers after a command has completed. This works to some extent, but cannot provide EPOLLEXCLUSIVE support because the waker side uses complete_all() which unconditionally wakes up all waiters. complete_all() is required because completions internally use exclusive wait and complete() only wakes up one waiter by default. This mixes conceptually different mechanisms and relies on internal implementation details of completions, which in turn puts contraints on changing the internal implementation of completions. Replace it with a regular wait queue and store the state in struct switchtec_user. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Peter Zijlstra (Intel) Cc: Kurt Schwemmer Cc: Logan Gunthorpe Cc: Bjorn Helgaas Cc: linux-pci@vger.kernel.org --- V2: Reworded changelog. --- drivers/pci/switch/switchtec.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) --- a/drivers/pci/switch/switchtec.c +++ b/drivers/pci/switch/switchtec.c @@ -52,10 +52,11 @@ struct switchtec_user { enum mrpc_state state; - struct completion comp; + wait_queue_head_t cmd_comp; struct kref kref; struct list_head list; + bool cmd_done; u32 cmd; u32 status; u32 return_code; @@ -77,7 +78,7 @@ static struct switchtec_user *stuser_cre stuser->stdev = stdev; kref_init(&stuser->kref); INIT_LIST_HEAD(&stuser->list); - init_completion(&stuser->comp); + init_waitqueue_head(&stuser->cmd_comp); stuser->event_cnt = atomic_read(&stdev->event_cnt); dev_dbg(&stdev->dev, "%s: %p\n", __func__, stuser); @@ -175,7 +176,7 @@ static int mrpc_queue_cmd(struct switcht kref_get(&stuser->kref); stuser->read_len = sizeof(stuser->data); stuser_set_state(stuser, MRPC_QUEUED); - reinit_completion(&stuser->comp); + stuser->cmd_done = false; list_add_tail(&stuser->list, &stdev->mrpc_queue); mrpc_cmd_submit(stdev); @@ -222,7 +223,8 @@ static void mrpc_complete_cmd(struct swi memcpy_fromio(stuser->data, &stdev->mmio_mrpc->output_data, stuser->read_len); out: - complete_all(&stuser->comp); + stuser->cmd_done = true; + wake_up_interruptible(&stuser->cmd_comp); list_del_init(&stuser->list); stuser_put(stuser); stdev->mrpc_busy = 0; @@ -529,10 +531,11 @@ static ssize_t switchtec_dev_read(struct mutex_unlock(&stdev->mrpc_mutex); if (filp->f_flags & O_NONBLOCK) { - if (!try_wait_for_completion(&stuser->comp)) + if (!stuser->cmd_done) return -EAGAIN; } else { - rc = wait_for_completion_interruptible(&stuser->comp); + rc = wait_event_interruptible(stuser->cmd_comp, + stuser->cmd_done); if (rc < 0) return rc; } @@ -580,7 +583,7 @@ static __poll_t switchtec_dev_poll(struc struct switchtec_dev *stdev = stuser->stdev; __poll_t ret = 0; - poll_wait(filp, &stuser->comp.wait, wait); + poll_wait(filp, &stuser->cmd_comp, wait); poll_wait(filp, &stdev->event_wq, wait); if (lock_mutex_and_test_alive(stdev)) @@ -588,7 +591,7 @@ static __poll_t switchtec_dev_poll(struc mutex_unlock(&stdev->mrpc_mutex); - if (try_wait_for_completion(&stuser->comp)) + if (stuser->cmd_done) ret |= EPOLLIN | EPOLLRDNORM; if (stuser->event_cnt != atomic_read(&stdev->event_cnt)) @@ -1272,7 +1275,8 @@ static void stdev_kill(struct switchtec_ /* Wake up and kill any users waiting on an MRPC request */ list_for_each_entry_safe(stuser, tmpuser, &stdev->mrpc_queue, list) { - complete_all(&stuser->comp); + stuser->cmd_done = true; + wake_up_interruptible(&stuser->cmd_comp); list_del_init(&stuser->list); stuser_put(stuser); }