From patchwork Tue Jul 29 15:14:15 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 4640751 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CCA3D9F32F for ; Tue, 29 Jul 2014 15:14:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A76B720115 for ; Tue, 29 Jul 2014 15:14:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8527220145 for ; Tue, 29 Jul 2014 15:14:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753964AbaG2POt (ORCPT ); Tue, 29 Jul 2014 11:14:49 -0400 Received: from mail-wg0-f47.google.com ([74.125.82.47]:42270 "EHLO mail-wg0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753949AbaG2POs (ORCPT ); Tue, 29 Jul 2014 11:14:48 -0400 Received: by mail-wg0-f47.google.com with SMTP id b13so9073397wgh.6 for ; Tue, 29 Jul 2014 08:14:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=N0/6z7UZR6QVGeKvVWCbAOlc7JxQvZfzSuD7feaQatI=; b=PLV5vMEd8kL0gUUARGgaPyD5X1sE4dvtf2Za7h2jluE3j3E7QCz+rmfTHlgfEel5Le wsBiluzx13HJxif5r9Q0Q+poGZIOi1NK0FWhCjgzMhvaL+BQuK+c413qBM7mVsbns5aa sK2l9uzVl4TwvuAjJzzrVKKgPOXm7K2a3+MonH2/+g0eAjRRY2nKRZF3xjbFRjhlRaCk Q8dC/DKCg/D++6dz6QrW3bnsVGko3M2y2tMSKBXIXfGVv9HU90SDEgkRezvzF64Z1l4U JfBKDGsGUtD0g6spX5wTHSRxb5uRcp0A3lcv2iGX/hNp016isr33cRwbp0R/7OMdgRsc 6T7Q== X-Received: by 10.180.93.8 with SMTP id cq8mr7085804wib.17.1406646885718; Tue, 29 Jul 2014 08:14:45 -0700 (PDT) Received: from david-tp.localdomain (stgt-4d0247ad.pool.mediaWays.net. [77.2.71.173]) by mx.google.com with ESMTPSA id fs3sm44361822wic.20.2014.07.29.08.14.44 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 29 Jul 2014 08:14:44 -0700 (PDT) From: David Herrmann To: linux-input@vger.kernel.org Cc: Jiri Kosina , Benjamin Tissoires , David Herrmann Subject: [PATCH 01/12] HID: uhid: simplify report-cb shutdown Date: Tue, 29 Jul 2014 17:14:15 +0200 Message-Id: <1406646866-999-2-git-send-email-dh.herrmann@gmail.com> X-Mailer: git-send-email 2.0.3 In-Reply-To: <1406646866-999-1-git-send-email-dh.herrmann@gmail.com> References: <1406646866-999-1-git-send-email-dh.herrmann@gmail.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The report-query is blocking, so when user-space destroys a device we have to wake up any blocking kernel context that is currently in the report-cb. We used some broken correlation between @report_done and @running so far. Replace it by a much more obvious use. We now wake up the report-cb if either @report_done or @running is set. wake_up() and wait_event() serve as implicit barriers (as they always do) so no need to use smp_rmb/wmb directly. Note that @report_done is never reset by anyone but the report-cb, thus it cannot flip twice while we wait for it. And whenever we set @running, we afterwards synchronously remove the HID device. Therefore, we wait for all report-cbs to finish before we return. This way, @running can never flip to true while we wait for it. Signed-off-by: David Herrmann --- drivers/hid/uhid.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 0cb92e3..16af4d3 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -172,13 +172,9 @@ static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, spin_unlock_irqrestore(&uhid->qlock, flags); ret = wait_event_interruptible_timeout(uhid->report_wait, - atomic_read(&uhid->report_done), 5 * HZ); + atomic_read(&uhid->report_done) || !uhid->running, + 5 * HZ); - /* - * Make sure "uhid->running" is cleared on shutdown before - * "uhid->report_done" is set. - */ - smp_rmb(); if (!ret || !uhid->running) { ret = -EIO; } else if (ret < 0) { @@ -493,10 +489,7 @@ static int uhid_dev_destroy(struct uhid_device *uhid) if (!uhid->running) return -EINVAL; - /* clear "running" before setting "report_done" */ uhid->running = false; - smp_wmb(); - atomic_set(&uhid->report_done, 1); wake_up_interruptible(&uhid->report_wait); hid_destroy_device(uhid->hid);