From patchwork Thu Sep 5 04:17:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 13791739 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 41807CD4F20 for ; Thu, 5 Sep 2024 04:38:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=j96TxrzClXBkhwjMJZl6JNr36upS20Gw21hZhz5UEQc=; b=NHQ0T5qiZsuR4Xv2utmGfEZyiO MgjeHygSl9HoMk9fpCbIe+1ee7seCD72Hop5mzEvIezVBd5KSRl19QAHa+ikeSUYw6TluUCs341Gn i6Ah8teGG3Tk6LqOQ5VrTI+Vg749kSHkTkGH8JMzd4h0zvthWAepCyw9SzVWKsP6nnPgh9Irr0ejI bWhEXBSx92vdYrBzgNy0VnszRW24+T+TN9GG78tNi6bLvzQ5YsP/9Fp7MS76t/qNbmJ3Ay/KjAjGl O2XUOVZnFQCZWVPlciwZX/zbqzj8SuXm81fzEAyqUzXE99g49RXyAHHiKpmBUDGjPqvpjjw06fT8K CE7TPwIg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sm4Fi-00000006xbX-0cRR; Thu, 05 Sep 2024 04:37:50 +0000 Received: from mail-pf1-x42a.google.com ([2607:f8b0:4864:20::42a]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sm3wk-00000006tXD-2brR for linux-arm-kernel@lists.infradead.org; Thu, 05 Sep 2024 04:18:16 +0000 Received: by mail-pf1-x42a.google.com with SMTP id d2e1a72fcca58-714187df604so933199b3a.1 for ; Wed, 04 Sep 2024 21:18:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1725509893; x=1726114693; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=j96TxrzClXBkhwjMJZl6JNr36upS20Gw21hZhz5UEQc=; b=hqKUN/fgtWPQttJ5x1vV47ElqKCPvBHchNBOxIj7EYUC2OE5K/aZFp0avaKvdbFWk1 D3I6kttDiUpKIB8TZDz0cvCz7N8EZpvdF0bBHL6cu2BV+vfqc10/vWdtNLUHcADFxfev BInvPSyGbE963aVZgvNJsVunw9ed4anEOCX/6FublFnm6mDcFDHmSo2X3Mlv0JjOUT81 N8tJp+q+Q9g33t+UmbR4vm9WEbJL8PZIqZ0/7mQ9jc7o1VVZ3R54rK9AfxulI7zwcP5C 4zVY4b4L3ROY1gIZFdLfIFmXFJdRlLfVYmN0pDr9QblNcxt3piIL4OhA790l9cfABBH0 01vA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725509893; x=1726114693; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=j96TxrzClXBkhwjMJZl6JNr36upS20Gw21hZhz5UEQc=; b=R7Vx7i+oRLq1gb1bHFhJMD1Z2lnkW/4u/4X73nh0lcPyHAHPf8CmW8nZLo9HhsN/9m Jv6pWFYSx9nAHjI4UdmauA8fbaKxL6BAO52IteUBc7jUYTF43w0extoqxqoBA9V1u1Km e/5g5liHgjwRHzfv38wY2BvuIjJVyuiG+Kx4qKUsvQm1/lAK9/9cEsZ7eY90pcbpQi/F H2TgEPHWhKjVdwlwJMvrGPsiakzDETO/29cHwUof8SuWjD+6d4MwQ+JFzU2vTw3lOgqU KkfidiRtImsU/2pX3vkdOYj0YMz8SxvkbhD6T+DGQ2JNRGmpczzogUj98/WFom7zFzvY l9Uw== X-Forwarded-Encrypted: i=1; AJvYcCUriu7AXJYSRrjqcVRjw03Ulq8LRKEIAOyS4+DQ7eIrKCBG8n1TAqpzBsWuTTI4Ve7gafHuybhwhTYe7Ns7Zgkg@lists.infradead.org X-Gm-Message-State: AOJu0YxGpcXRriNp8R/jQgUffFnVd2R5DzFlNSvuMxmhqn9CpG8KOCud t8WOojtFv1lby8nPIUZWKUb0hgtankHZqcT3Wwq3e6AZ32D3Okli5PPreQ== X-Google-Smtp-Source: AGHT+IEtbS6Hh36TyocrzyvtNt8382uDa9MHZZCYVlpcXz+bDRK1U/OJOVBLjLQwYZ/02bwTa26XXA== X-Received: by 2002:a05:6a20:4c10:b0:1cc:d5d1:fe64 with SMTP id adf61e73a8af0-1cf0803a591mr6663245637.14.1725509893151; Wed, 04 Sep 2024 21:18:13 -0700 (PDT) Received: from dtor-ws.sjc.corp.google.com ([2620:15c:9d:2:13bd:b4e:4c0f:4c37]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-7d4fbd8d52esm2450216a12.32.2024.09.04.21.18.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2024 21:18:12 -0700 (PDT) From: Dmitry Torokhov To: linux-input@vger.kernel.org Cc: =?utf-8?q?Pali_Roh=C3=A1r?= , Helge Deller , "K. Y. Srinivasan" , Wei Liu , Dexuan Cui , Samuel Holland , Lyude Paul , Michal Simek , Hans de Goede , linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: [PATCH 20/24] Input: serio_raw - use guard notation for locks and other resources Date: Wed, 4 Sep 2024 21:17:25 -0700 Message-ID: <20240905041732.2034348-21-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.46.0.469.g59c65b2a67-goog In-Reply-To: <20240905041732.2034348-1-dmitry.torokhov@gmail.com> References: <20240905041732.2034348-1-dmitry.torokhov@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240904_211814_763291_8FB411FB X-CRM114-Status: GOOD ( 16.31 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Use guard notation when acquiring mutexes and spinlocks, and when pausing and resuming serio port. Such guard notation makes the code more compact and error handling more robust by ensuring that locks are released in all code paths when control leaves critical section. Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio_raw.c | 121 +++++++++++++------------------- 1 file changed, 49 insertions(+), 72 deletions(-) diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 0186d1b38f49..aef8301313b2 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -75,41 +75,31 @@ static int serio_raw_open(struct inode *inode, struct file *file) { struct serio_raw *serio_raw; struct serio_raw_client *client; - int retval; - retval = mutex_lock_interruptible(&serio_raw_mutex); - if (retval) - return retval; + scoped_guard(mutex_intr, &serio_raw_mutex) { + serio_raw = serio_raw_locate(iminor(inode)); + if (!serio_raw) + return -ENODEV; - serio_raw = serio_raw_locate(iminor(inode)); - if (!serio_raw) { - retval = -ENODEV; - goto out; - } + if (serio_raw->dead) + return -ENODEV; - if (serio_raw->dead) { - retval = -ENODEV; - goto out; - } + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client) + return -ENOMEM; - client = kzalloc(sizeof(*client), GFP_KERNEL); - if (!client) { - retval = -ENOMEM; - goto out; - } + client->serio_raw = serio_raw; + file->private_data = client; - client->serio_raw = serio_raw; - file->private_data = client; + kref_get(&serio_raw->kref); - kref_get(&serio_raw->kref); + scoped_guard(serio_pause_rx, serio_raw->serio) + list_add_tail(&client->node, &serio_raw->client_list); - serio_pause_rx(serio_raw->serio); - list_add_tail(&client->node, &serio_raw->client_list); - serio_continue_rx(serio_raw->serio); + return 0; + } -out: - mutex_unlock(&serio_raw_mutex); - return retval; + return -EINTR; } static void serio_raw_free(struct kref *kref) @@ -126,9 +116,8 @@ static int serio_raw_release(struct inode *inode, struct file *file) struct serio_raw_client *client = file->private_data; struct serio_raw *serio_raw = client->serio_raw; - serio_pause_rx(serio_raw->serio); - list_del(&client->node); - serio_continue_rx(serio_raw->serio); + scoped_guard(serio_pause_rx, serio_raw->serio) + list_del(&client->node); kfree(client); @@ -139,19 +128,15 @@ static int serio_raw_release(struct inode *inode, struct file *file) static bool serio_raw_fetch_byte(struct serio_raw *serio_raw, char *c) { - bool empty; + guard(serio_pause_rx)(serio_raw->serio); - serio_pause_rx(serio_raw->serio); - - empty = serio_raw->head == serio_raw->tail; - if (!empty) { - *c = serio_raw->queue[serio_raw->tail]; - serio_raw->tail = (serio_raw->tail + 1) % SERIO_RAW_QUEUE_LEN; - } + if (serio_raw->head == serio_raw->tail) + return false; /* queue is empty */ - serio_continue_rx(serio_raw->serio); + *c = serio_raw->queue[serio_raw->tail]; + serio_raw->tail = (serio_raw->tail + 1) % SERIO_RAW_QUEUE_LEN; - return !empty; + return true; } static ssize_t serio_raw_read(struct file *file, char __user *buffer, @@ -200,40 +185,32 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer, { struct serio_raw_client *client = file->private_data; struct serio_raw *serio_raw = client->serio_raw; - int retval = 0; + int written; unsigned char c; - retval = mutex_lock_interruptible(&serio_raw_mutex); - if (retval) - return retval; + scoped_guard(mutex_intr, &serio_raw_mutex) { + if (serio_raw->dead) + return -ENODEV; - if (serio_raw->dead) { - retval = -ENODEV; - goto out; - } + if (count > 32) + count = 32; - if (count > 32) - count = 32; + while (count--) { + if (get_user(c, buffer++)) + return -EFAULT; - while (count--) { - if (get_user(c, buffer++)) { - retval = -EFAULT; - goto out; - } + if (serio_write(serio_raw->serio, c)) { + /* Either signal error or partial write */ + return written ?: -EIO; + } - if (serio_write(serio_raw->serio, c)) { - /* Either signal error or partial write */ - if (retval == 0) - retval = -EIO; - goto out; + written++; } - retval++; + return written; } -out: - mutex_unlock(&serio_raw_mutex); - return retval; + return -EINTR; } static __poll_t serio_raw_poll(struct file *file, poll_table *wait) @@ -379,10 +356,10 @@ static void serio_raw_hangup(struct serio_raw *serio_raw) { struct serio_raw_client *client; - serio_pause_rx(serio_raw->serio); - list_for_each_entry(client, &serio_raw->client_list, node) - kill_fasync(&client->fasync, SIGIO, POLL_HUP); - serio_continue_rx(serio_raw->serio); + scoped_guard(serio_pause_rx, serio_raw->serio) { + list_for_each_entry(client, &serio_raw->client_list, node) + kill_fasync(&client->fasync, SIGIO, POLL_HUP); + } wake_up_interruptible(&serio_raw->wait); } @@ -394,10 +371,10 @@ static void serio_raw_disconnect(struct serio *serio) misc_deregister(&serio_raw->dev); - mutex_lock(&serio_raw_mutex); - serio_raw->dead = true; - list_del_init(&serio_raw->node); - mutex_unlock(&serio_raw_mutex); + scoped_guard(mutex, &serio_raw_mutex) { + serio_raw->dead = true; + list_del_init(&serio_raw->node); + } serio_raw_hangup(serio_raw);