From nobody Wed Oct 8 14:15:38 2025 Received: from mail-wr1-f52.google.com (mail-wr1-f52.google.com [209.85.221.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7B6C621C9EA for ; Fri, 27 Jun 2025 07:29:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751009395; cv=none; b=GwYcn0IzdJik6TJrwgibwai7EBVvIRx2GxkmVhCGM6ydd56kizssNAmxCy0UkPbPdsp2W455Vh8Oj9Kgc9ZGD14BeOYUsJ9WcOD86SypLaP3oopcKf8egpi1gC5T+lTyeEC1ffPdLLgznW1+d3oqZLRAOQAurTK/5/Cqqf6n/ak= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751009395; c=relaxed/simple; bh=D07LL7FI3Rq7CLxTrZdx2gLhFRY9YWPapNFxE1JUjXU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=L2JVwVRCEDA9puWg/RlC2wGOTwoUirwoqzGybdPwcfSQTML7eeLFh0BZGl7FmzlVhBrR9sV2XAfWaLcxxA440GAoLSIN2NVDCIO0ChEblXJhXrY7T06qXH50tLXUS4WnPFP8+cOwuwuhHhmMlhbTuwQfvq0FPQoQXswVXeAoXZE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=gVCfB55M; arc=none smtp.client-ip=209.85.221.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gVCfB55M" Received: by mail-wr1-f52.google.com with SMTP id ffacd0b85a97d-3a54690d369so1646890f8f.3 for ; Fri, 27 Jun 2025 00:29:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1751009390; x=1751614190; darn=vger.kernel.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=XGwVQ5Flc+D7Cd++9w3V1W8ZV4LDw0kGbLT/w49WWjo=; b=gVCfB55MzISyGR/QERvnTLkuWLTfoKv/dTwQBAyC+ZhZu8QJ47MI3G493UxS9zIKLp A13dn1ywTzzR7QOAC44hdzXT2/SZqMSHR0ZvGfZrIrUELJ7MlsUHPC5oYYZh0TEYq4GD a7awFM1NqAZbVaOjxBMS0bq/UbRVpY5uuCmh9aQ2cGbffHkQ+/fFEQkJJGt+XUeC1EXW GgENs2JXXZBHjsfP60ilrKmgOFF3H2mnNj80W5RferHNO/fM9jTW1ES0wgfP52r6IKVZ U4R+Ogtsjnq7bWZq5MjJVwYUtO4r8eH+Q7oqSe0+O7cOdkY6BsFrT5dq8A75JMc1FC31 fDyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751009390; x=1751614190; 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=XGwVQ5Flc+D7Cd++9w3V1W8ZV4LDw0kGbLT/w49WWjo=; b=bIGafk7BwyRZd8pfPSmGGhYvzCIa1u89yEy8XB6yRjUeJ7bjHU74IfUMapJypAttn+ lug7UULZL6sCea7ul04I96U4BFjHOhg+E/f3cbAb5kegwL7YqOkD0eWrEwrX71bd2xaQ 2iEFD+iYS6lIEDJadAvizMF4k8XpFPiV6VrC7rh9sIf9G/wes1KWN8M+iZF5ZB/Z7niA L0OwMglvmh5bZ3fr4ge2iV7P6JFWOKiPrDsVBTZLGrMacaj8t7v/U7vHjAzZmCtvRBF5 mQr2c0/ZBMWdGrLMrEoipiZ0qTiN3MVdSNPXowvv0AndPOWn8WdPOwCgd55FhWMDxPDe Kg0w== X-Forwarded-Encrypted: i=1; AJvYcCXgP1J8LLI5oRurssM62wAwGfGPrMz51qlJN2JwIDzXxBjU8sHg6r5wFZEEIsQUL4/0rUJQHkmMZvlnZ0c=@vger.kernel.org X-Gm-Message-State: AOJu0YyfKWzjnIf3ViFPCg2GSFIVBwcbok0QfMCaWqSO8FoD2MA8Z/0H 6tibBpJNKBf65xum89lJiy8iQuX9A+OYOARj4+Nd9DWwZOCIchyjpAp6 X-Gm-Gg: ASbGncu+1vg3YMNKez9CeXllDaHo1NsHtNh6rUZofND482jAiIrJlT5bVtPu8AISp/e IIixexwi3pvh6TdoXf3lJA6vgvk09R9//AzWFHgz96nWslya/4tuNDyr5vy2jmLivpnOn0Z4M7X MpCPHRTJZewXci1PBDIin6G/GHsNDVHMIurCFKAEQwd0GQ/6uW4T73WtHEkuS0pOJ2M3HVb6gPt T/VMxa6nx1/TClK15TBE4ZGSidWdnqZMHP1TlGXoVNQivQmSIubcyYruLFajbMU1w79XmdFd6PD crzb7ZB9Ro3ZuwogIPCwr38th75VUVF+U1Ov8L8ZwpzIKkGD X-Google-Smtp-Source: AGHT+IHI3IoRcF9+IQUF8gWE3fQXWuiQLLXT2Oez5CFa8WdZTlx+Nhe9/6i4seFp0sL2p2UFPLhcLw== X-Received: by 2002:adf:9c93:0:b0:3a4:ed2f:e80c with SMTP id ffacd0b85a97d-3a8fdeff3a2mr1719522f8f.31.1751009390109; Fri, 27 Jun 2025 00:29:50 -0700 (PDT) Received: from EBJ9932692.tcent.cn ([2a09:0:1:2::302c]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3a88c7e72b6sm1955665f8f.15.2025.06.27.00.29.45 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Fri, 27 Jun 2025 00:29:49 -0700 (PDT) From: Lance Yang X-Google-Original-From: Lance Yang To: akpm@linux-foundation.org Cc: zi.li@linux.dev, anna.schumaker@oracle.com, boqun.feng@gmail.com, joel.granados@kernel.org, jstultz@google.com, kent.overstreet@linux.dev, leonylgao@tencent.com, linux-kernel@vger.kernel.org, longman@redhat.com, mhiramat@kernel.org, mingo@redhat.com, mingzhe.yang@ly.com, peterz@infradead.org, rostedt@goodmis.org, senozhatsky@chromium.org, tfiga@chromium.org, will@kernel.org, Lance Yang Subject: [PATCH 1/3] locking/rwsem: make owner helpers globally available Date: Fri, 27 Jun 2025 15:29:22 +0800 Message-ID: <20250627072924.36567-2-lance.yang@linux.dev> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250627072924.36567-1-lance.yang@linux.dev> References: <20250627072924.36567-1-lance.yang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Lance Yang In preparation for extending blocker tracking to support rwsems, make the rwsem_owner() and is_rwsem_reader_owned() helpers globally available for determining if the blocker is a writer or one of the readers. Additionally, a stale owner pointer in a reader-owned rwsem can lead to false positives in blocker tracking when CONFIG_DETECT_HUNG_TASK_BLOCKER is enabled. To mitigate this, clear the owner field on the reader unlock path, similar to what CONFIG_DEBUG_RWSEMS does. A NULL owner is better than a stale one for diagnostics. Reviewed-by: Masami Hiramatsu (Google) Signed-off-by: Lance Yang --- include/linux/rwsem.h | 12 ++++++++++++ kernel/locking/rwsem.c | 14 +++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h index c8b543d428b0..544853bed5b9 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h @@ -132,6 +132,18 @@ static inline int rwsem_is_contended(struct rw_semapho= re *sem) return !list_empty(&sem->wait_list); } =20 +#if defined(CONFIG_DEBUG_RWSEMS) || defined(CONFIG_DETECT_HUNG_TASK_BLOCKE= R) +/* + * Return just the real task structure pointer of the owner + */ +extern struct task_struct *rwsem_owner(struct rw_semaphore *sem); + +/* + * Return true if the rwsem is owned by a reader. + */ +extern bool is_rwsem_reader_owned(struct rw_semaphore *sem); +#endif + #else /* !CONFIG_PREEMPT_RT */ =20 #include diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index 2ddb827e3bea..a310eb9896de 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -181,11 +181,11 @@ static inline void rwsem_set_reader_owned(struct rw_s= emaphore *sem) __rwsem_set_reader_owned(sem, current); } =20 -#ifdef CONFIG_DEBUG_RWSEMS +#if defined(CONFIG_DEBUG_RWSEMS) || defined(CONFIG_DETECT_HUNG_TASK_BLOCKE= R) /* * Return just the real task structure pointer of the owner */ -static inline struct task_struct *rwsem_owner(struct rw_semaphore *sem) +struct task_struct *rwsem_owner(struct rw_semaphore *sem) { return (struct task_struct *) (atomic_long_read(&sem->owner) & ~RWSEM_OWNER_FLAGS_MASK); @@ -194,7 +194,7 @@ static inline struct task_struct *rwsem_owner(struct rw= _semaphore *sem) /* * Return true if the rwsem is owned by a reader. */ -static inline bool is_rwsem_reader_owned(struct rw_semaphore *sem) +bool is_rwsem_reader_owned(struct rw_semaphore *sem) { /* * Check the count to see if it is write-locked. @@ -207,10 +207,10 @@ static inline bool is_rwsem_reader_owned(struct rw_se= maphore *sem) } =20 /* - * With CONFIG_DEBUG_RWSEMS configured, it will make sure that if there - * is a task pointer in owner of a reader-owned rwsem, it will be the - * real owner or one of the real owners. The only exception is when the - * unlock is done by up_read_non_owner(). + * With CONFIG_DEBUG_RWSEMS or CONFIG_DETECT_HUNG_TASK_BLOCKER configured, + * it will make sure that the owner field of a reader-owned rwsem either + * points to a real reader-owner(s) or gets cleared. The only exception is + * when the unlock is done by up_read_non_owner(). */ static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem) { --=20 2.49.0 From nobody Wed Oct 8 14:15:38 2025 Received: from mail-wr1-f54.google.com (mail-wr1-f54.google.com [209.85.221.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DD87F21D3C9 for ; Fri, 27 Jun 2025 07:29:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751009402; cv=none; b=M9LA4J3aLcl8po9Qa1VLl9vywDTSNGWydKAGJQrtLI/5dswl0UggkdAT8VYtWJySsAfH+onJ9GFX8N+5D0U6OItI3xB7T6OvDlxUtoIpmeffvPhnQN+X5h3oBGthLwNDn7xB+g+NyWJXBPHVFInNc9i+ys+stVCDSbTZLSMQiOU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751009402; c=relaxed/simple; bh=upp2XMMSzydYHE6K9Q/3J5VDUWJ4aO4qTCokV6k89qw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SSwEd5Lff65qxwokd/+eJiR4ML4K/+CZTQkbOCIcaDXOLj4t09PCIRjDHqWvVhrlXzZjZIQ2AdstfZcJCNI/Jd8nvfvWbcHjFFzOvRM56odIfvYFccuCXsvsYM21yeTHG3HPZdhQnf+KkgfiZrdlD+tp+eaFHL4XEuMcYHI6SJw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=UqpkvF8L; arc=none smtp.client-ip=209.85.221.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UqpkvF8L" Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-3a536ecbf6fso1035495f8f.2 for ; Fri, 27 Jun 2025 00:29:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1751009398; x=1751614198; darn=vger.kernel.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=frViLy0H+mcv5Vd2p65vOchSjpU8NXW7W8lMsYCNBFw=; b=UqpkvF8LxAHDX04piBtsNvM0EZ2fbpELjtnZxVzi6PQxOIdHbirFFGAgVttZxSHdXF xrJWgU6Zjl4Qf/fPmM+1ZsVgsR9hOIXSBsHPzJoy6yGMOwR9GNanHZTj9yeHna0cackU 6sx5kFMGXuFDspWQ6utzOGwU2CwzIMH2/HI/Wbz4WFWczaxeGRV6IL8emvehywRIX29G X4KymKxLIY0diqh57hG4QUNiqZhFP5GJnHACErLMskDiUOlODyUeQI6RTnDaXHCPRbdj EqHrIRtUOkRt19q1BD5L9Rv7SlzuMDcHlC6fvcrpYycx69qD+c35wcqnxLB7WBP78ObF 8jaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751009398; x=1751614198; 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=frViLy0H+mcv5Vd2p65vOchSjpU8NXW7W8lMsYCNBFw=; b=cEmgRRHPy+ZOBBn1kGB5NFI8pxSNTMnLBDu9lEc7t/pPH/mGOsS05OVX7mvjloyDpy LB78jSEcdv6ZP+KW1VEhJUMrfyTwNF2XHfOluZY7k/gDn9/V/yPaJxYt8V8pcHR3mngi hnfBxE0Km4UccdjzdorNdQ93hrbLfye127UIgXFuC//WVzg98LC6jIdmN+UZFl5xK22Q SnwJKyXLv9/AiRhb6bSgh4NjSU4qhlvwzWaLSgoZyXFfmnkBCwzzd3ATBSosx3CS4j9h UvH+ft02ILegofpKNkWrZw/0uOvYf+93zFrlkQSNhLjOMwQtZMwHAM6g/vmCLz/CiUwh zo+g== X-Forwarded-Encrypted: i=1; AJvYcCVMSol6vcpzP5j89vuiqgEpADt4Xu2FBfmi03uHVADVMGgN6to/sMzL/kXjHzzYlaG0fNVT8EizaAwe+C8=@vger.kernel.org X-Gm-Message-State: AOJu0Yxgzw29rveLRfCMoxo/cguxjXI8O6ELohlkGP84m4ZdmkxSt50R eo2zq0yZy8VKEb0Z8W5kmBlz5bMydFvjnYP6wp9dETW8Xr1b06YCdBAE X-Gm-Gg: ASbGnctS1ZCcJtfQ8AP5M7ypMxt6qVIlJVsrCztzJmsUfnlWpVCytmVsm+aiaz95pOG IXG4g5s7WHS138Gw0a88jokB1B+F23ogCNbsLQauHYmgezdeTQjK6cU68hCsnMA1EA7nGqenYeK 2WAVTyBUSBa25aQ7wIAemJuUQqem7xTwzaaYqLCvKa7W/Bf0/qHU7a1RWz5SUHL8790okzrgr6R kO1vgigfBGA7KWrgwXuDK5GaHyaKcOcEbcD/Q8ALLzRLNhW4jzS410+b3FM1ir+zLo1UZeVas3U xoqafQWDhwchwqSupwcVrADRYDKDniULJuSXJnyymNP3aSpf X-Google-Smtp-Source: AGHT+IE9uEGFp1zc0imGlKPcumD/KOulw91C2XL3gMaggE949OJic2VxzPk9dCh3aR+aapVEjrDUUw== X-Received: by 2002:a05:6000:2307:b0:3a6:d145:e2cc with SMTP id ffacd0b85a97d-3a8fdff46e4mr1961474f8f.15.1751009397879; Fri, 27 Jun 2025 00:29:57 -0700 (PDT) Received: from EBJ9932692.tcent.cn ([2a09:0:1:2::302c]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3a88c7e72b6sm1955665f8f.15.2025.06.27.00.29.50 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Fri, 27 Jun 2025 00:29:57 -0700 (PDT) From: Lance Yang X-Google-Original-From: Lance Yang To: akpm@linux-foundation.org Cc: zi.li@linux.dev, anna.schumaker@oracle.com, boqun.feng@gmail.com, joel.granados@kernel.org, jstultz@google.com, kent.overstreet@linux.dev, leonylgao@tencent.com, linux-kernel@vger.kernel.org, longman@redhat.com, mhiramat@kernel.org, mingo@redhat.com, mingzhe.yang@ly.com, peterz@infradead.org, rostedt@goodmis.org, senozhatsky@chromium.org, tfiga@chromium.org, will@kernel.org, Lance Yang Subject: [PATCH 2/3] hung_task: extend hung task blocker tracking to rwsems Date: Fri, 27 Jun 2025 15:29:23 +0800 Message-ID: <20250627072924.36567-3-lance.yang@linux.dev> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250627072924.36567-1-lance.yang@linux.dev> References: <20250627072924.36567-1-lance.yang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Lance Yang Inspired by mutex blocker tracking[1], and having already extended it to semaphores, let's now add support for reader-writer semaphores (rwsems). The approach is simple: when a task enters TASK_UNINTERRUPTIBLE while waiting for an rwsem, we just call hung_task_set_blocker(). The hung task detector can then query the rwsem's owner to identify the lock holder. Tracking works reliably for writers, as there can only be a single writer holding the lock, and its task struct is stored in the owner field. The main challenge lies with readers. The owner field points to only one of many concurrent readers, so we might lose track of the blocker if that specific reader unlocks, even while others remain. This is not a significant issue, however. In practice, long-lasting lock contention is almost always caused by a writer. Therefore, reliably tracking the writer is the primary goal of this patch series ;) With this change, the hung task detector can now show blocker task's info like below: [Fri Jun 27 15:21:34 2025] INFO: task cat:28631 blocked for more than 122 s= econds. [Fri Jun 27 15:21:34 2025] Tainted: G S 6.16.0-rc3 #8 [Fri Jun 27 15:21:34 2025] "echo 0 > /proc/sys/kernel/hung_task_timeout_sec= s" disables this message. [Fri Jun 27 15:21:34 2025] task:cat state:D stack:0 pid:286= 31 tgid:28631 ppid:28501 task_flags:0x400000 flags:0x00004000 [Fri Jun 27 15:21:34 2025] Call Trace: [Fri Jun 27 15:21:34 2025] [Fri Jun 27 15:21:34 2025] __schedule+0x7c7/0x1930 [Fri Jun 27 15:21:34 2025] ? __pfx___schedule+0x10/0x10 [Fri Jun 27 15:21:34 2025] ? policy_nodemask+0x215/0x340 [Fri Jun 27 15:21:34 2025] ? _raw_spin_lock_irq+0x8a/0xe0 [Fri Jun 27 15:21:34 2025] ? __pfx__raw_spin_lock_irq+0x10/0x10 [Fri Jun 27 15:21:34 2025] schedule+0x6a/0x180 [Fri Jun 27 15:21:34 2025] schedule_preempt_disabled+0x15/0x30 [Fri Jun 27 15:21:34 2025] rwsem_down_read_slowpath+0x55e/0xe10 [Fri Jun 27 15:21:34 2025] ? __pfx_rwsem_down_read_slowpath+0x10/0x10 [Fri Jun 27 15:21:34 2025] ? __pfx___might_resched+0x10/0x10 [Fri Jun 27 15:21:34 2025] down_read+0xc9/0x230 [Fri Jun 27 15:21:34 2025] ? __pfx_down_read+0x10/0x10 [Fri Jun 27 15:21:34 2025] ? __debugfs_file_get+0x14d/0x700 [Fri Jun 27 15:21:34 2025] ? __pfx___debugfs_file_get+0x10/0x10 [Fri Jun 27 15:21:34 2025] ? handle_pte_fault+0x52a/0x710 [Fri Jun 27 15:21:34 2025] ? selinux_file_permission+0x3a9/0x590 [Fri Jun 27 15:21:34 2025] read_dummy_rwsem_read+0x4a/0x90 [Fri Jun 27 15:21:34 2025] full_proxy_read+0xff/0x1c0 [Fri Jun 27 15:21:34 2025] ? rw_verify_area+0x6d/0x410 [Fri Jun 27 15:21:34 2025] vfs_read+0x177/0xa50 [Fri Jun 27 15:21:34 2025] ? __pfx_vfs_read+0x10/0x10 [Fri Jun 27 15:21:34 2025] ? fdget_pos+0x1cf/0x4c0 [Fri Jun 27 15:21:34 2025] ksys_read+0xfc/0x1d0 [Fri Jun 27 15:21:34 2025] ? __pfx_ksys_read+0x10/0x10 [Fri Jun 27 15:21:34 2025] do_syscall_64+0x66/0x2d0 [Fri Jun 27 15:21:34 2025] entry_SYSCALL_64_after_hwframe+0x76/0x7e [Fri Jun 27 15:21:34 2025] RIP: 0033:0x7f3f8faefb40 [Fri Jun 27 15:21:34 2025] RSP: 002b:00007ffdeda5ab98 EFLAGS: 00000246 ORIG= _RAX: 0000000000000000 [Fri Jun 27 15:21:34 2025] RAX: ffffffffffffffda RBX: 0000000000010000 RCX:= 00007f3f8faefb40 [Fri Jun 27 15:21:34 2025] RDX: 0000000000010000 RSI: 00000000010fa000 RDI:= 0000000000000003 [Fri Jun 27 15:21:34 2025] RBP: 00000000010fa000 R08: 0000000000000000 R09:= 0000000000010fff [Fri Jun 27 15:21:34 2025] R10: 00007ffdeda59fe0 R11: 0000000000000246 R12:= 00000000010fa000 [Fri Jun 27 15:21:34 2025] R13: 0000000000000003 R14: 0000000000000000 R15:= 0000000000000fff [Fri Jun 27 15:21:34 2025] [Fri Jun 27 15:21:34 2025] INFO: task cat:28631 blocked on an rw-s= emaphore likely owned by task cat:28630 [Fri Jun 27 15:21:34 2025] task:cat state:S stack:0 pid:286= 30 tgid:28630 ppid:28501 task_flags:0x400000 flags:0x00004000 [Fri Jun 27 15:21:34 2025] Call Trace: [Fri Jun 27 15:21:34 2025] [Fri Jun 27 15:21:34 2025] __schedule+0x7c7/0x1930 [Fri Jun 27 15:21:34 2025] ? __pfx___schedule+0x10/0x10 [Fri Jun 27 15:21:34 2025] ? __mod_timer+0x304/0xa80 [Fri Jun 27 15:21:34 2025] schedule+0x6a/0x180 [Fri Jun 27 15:21:34 2025] schedule_timeout+0xfb/0x230 [Fri Jun 27 15:21:34 2025] ? __pfx_schedule_timeout+0x10/0x10 [Fri Jun 27 15:21:34 2025] ? __pfx_process_timeout+0x10/0x10 [Fri Jun 27 15:21:34 2025] ? down_write+0xc4/0x140 [Fri Jun 27 15:21:34 2025] msleep_interruptible+0xbe/0x150 [Fri Jun 27 15:21:34 2025] read_dummy_rwsem_write+0x54/0x90 [Fri Jun 27 15:21:34 2025] full_proxy_read+0xff/0x1c0 [Fri Jun 27 15:21:34 2025] ? rw_verify_area+0x6d/0x410 [Fri Jun 27 15:21:34 2025] vfs_read+0x177/0xa50 [Fri Jun 27 15:21:34 2025] ? __pfx_vfs_read+0x10/0x10 [Fri Jun 27 15:21:34 2025] ? fdget_pos+0x1cf/0x4c0 [Fri Jun 27 15:21:34 2025] ksys_read+0xfc/0x1d0 [Fri Jun 27 15:21:34 2025] ? __pfx_ksys_read+0x10/0x10 [Fri Jun 27 15:21:34 2025] do_syscall_64+0x66/0x2d0 [Fri Jun 27 15:21:34 2025] entry_SYSCALL_64_after_hwframe+0x76/0x7e [Fri Jun 27 15:21:34 2025] RIP: 0033:0x7f8f288efb40 [Fri Jun 27 15:21:34 2025] RSP: 002b:00007ffffb631038 EFLAGS: 00000246 ORIG= _RAX: 0000000000000000 [Fri Jun 27 15:21:34 2025] RAX: ffffffffffffffda RBX: 0000000000010000 RCX:= 00007f8f288efb40 [Fri Jun 27 15:21:34 2025] RDX: 0000000000010000 RSI: 000000002a4b5000 RDI:= 0000000000000003 [Fri Jun 27 15:21:34 2025] RBP: 000000002a4b5000 R08: 0000000000000000 R09:= 0000000000010fff [Fri Jun 27 15:21:34 2025] R10: 00007ffffb630460 R11: 0000000000000246 R12:= 000000002a4b5000 [Fri Jun 27 15:21:34 2025] R13: 0000000000000003 R14: 0000000000000000 R15:= 0000000000000fff [Fri Jun 27 15:21:34 2025] [1] https://lore.kernel.org/all/174046694331.2194069.15472952050240807469.s= tgit@mhiramat.tok.corp.google.com/ Reviewed-by: Masami Hiramatsu (Google) Suggested-by: Masami Hiramatsu (Google) Signed-off-by: Lance Yang --- include/linux/hung_task.h | 18 +++++++++--------- kernel/hung_task.c | 29 +++++++++++++++++++++++++---- kernel/locking/rwsem.c | 17 ++++++++++++++++- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/include/linux/hung_task.h b/include/linux/hung_task.h index 1bc2b3244613..34e615c76ca5 100644 --- a/include/linux/hung_task.h +++ b/include/linux/hung_task.h @@ -21,17 +21,17 @@ * type. * * Type encoding: - * 00 - Blocked on mutex (BLOCKER_TYPE_MUTEX) - * 01 - Blocked on semaphore (BLOCKER_TYPE_SEM) - * 10 - Blocked on rt-mutex (BLOCKER_TYPE_RTMUTEX) - * 11 - Blocked on rw-semaphore (BLOCKER_TYPE_RWSEM) + * 00 - Blocked on mutex (BLOCKER_TYPE_MUTEX) + * 01 - Blocked on semaphore (BLOCKER_TYPE_SEM) + * 10 - Blocked on rw-semaphore as READER (BLOCKER_TYPE_RWSEM_READER) + * 11 - Blocked on rw-semaphore as WRITER (BLOCKER_TYPE_RWSEM_WRITER) */ -#define BLOCKER_TYPE_MUTEX 0x00UL -#define BLOCKER_TYPE_SEM 0x01UL -#define BLOCKER_TYPE_RTMUTEX 0x02UL -#define BLOCKER_TYPE_RWSEM 0x03UL +#define BLOCKER_TYPE_MUTEX 0x00UL +#define BLOCKER_TYPE_SEM 0x01UL +#define BLOCKER_TYPE_RWSEM_READER 0x02UL +#define BLOCKER_TYPE_RWSEM_WRITER 0x03UL =20 -#define BLOCKER_TYPE_MASK 0x03UL +#define BLOCKER_TYPE_MASK 0x03UL =20 #ifdef CONFIG_DETECT_HUNG_TASK_BLOCKER static inline void hung_task_set_blocker(void *lock, unsigned long type) diff --git a/kernel/hung_task.c b/kernel/hung_task.c index d2432df2b905..8708a1205f82 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c @@ -23,6 +23,7 @@ #include #include #include +#include =20 #include =20 @@ -100,6 +101,7 @@ static void debug_show_blocker(struct task_struct *task) { struct task_struct *g, *t; unsigned long owner, blocker, blocker_type; + const char *rwsem_blocked_by, *rwsem_blocked_as; =20 RCU_LOCKDEP_WARN(!rcu_read_lock_held(), "No rcu lock held"); =20 @@ -111,12 +113,20 @@ static void debug_show_blocker(struct task_struct *ta= sk) =20 switch (blocker_type) { case BLOCKER_TYPE_MUTEX: - owner =3D mutex_get_owner( - (struct mutex *)hung_task_blocker_to_lock(blocker)); + owner =3D mutex_get_owner(hung_task_blocker_to_lock(blocker)); break; case BLOCKER_TYPE_SEM: - owner =3D sem_last_holder( - (struct semaphore *)hung_task_blocker_to_lock(blocker)); + owner =3D sem_last_holder(hung_task_blocker_to_lock(blocker)); + break; + case BLOCKER_TYPE_RWSEM_READER: + case BLOCKER_TYPE_RWSEM_WRITER: + owner =3D (unsigned long)rwsem_owner( + hung_task_blocker_to_lock(blocker)); + rwsem_blocked_as =3D (blocker_type =3D=3D BLOCKER_TYPE_RWSEM_READER) ? + "reader" : "writer"; + rwsem_blocked_by =3D is_rwsem_reader_owned( + hung_task_blocker_to_lock(blocker)) ? + "reader" : "writer"; break; default: WARN_ON_ONCE(1); @@ -134,6 +144,11 @@ static void debug_show_blocker(struct task_struct *tas= k) pr_err("INFO: task %s:%d is blocked on a semaphore, but the last holder= is not found.\n", task->comm, task->pid); break; + case BLOCKER_TYPE_RWSEM_READER: + case BLOCKER_TYPE_RWSEM_WRITER: + pr_err("INFO: task %s:%d is blocked on an rw-semaphore, but the owner i= s not found.\n", + task->comm, task->pid); + break; } return; } @@ -152,6 +167,12 @@ static void debug_show_blocker(struct task_struct *tas= k) pr_err("INFO: task %s:%d blocked on a semaphore likely last held by tas= k %s:%d\n", task->comm, task->pid, t->comm, t->pid); break; + case BLOCKER_TYPE_RWSEM_READER: + case BLOCKER_TYPE_RWSEM_WRITER: + pr_err("INFO: task %s:%d <%s> blocked on an rw-semaphore likely owned b= y task %s:%d <%s>\n", + task->comm, task->pid, rwsem_blocked_as, t->comm, + t->pid, rwsem_blocked_by); + break; } sched_show_task(t); return; diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index a310eb9896de..92c6332da401 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -27,6 +27,7 @@ #include #include #include +#include #include =20 #ifndef CONFIG_PREEMPT_RT @@ -1065,10 +1066,13 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, = long count, unsigned int stat wake_up_q(&wake_q); =20 trace_contention_begin(sem, LCB_F_READ); + set_current_state(state); + + if (state =3D=3D TASK_UNINTERRUPTIBLE) + hung_task_set_blocker(sem, BLOCKER_TYPE_RWSEM_READER); =20 /* wait to be given the lock */ for (;;) { - set_current_state(state); if (!smp_load_acquire(&waiter.task)) { /* Matches rwsem_mark_wake()'s smp_store_release(). */ break; @@ -1083,8 +1087,12 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, l= ong count, unsigned int stat } schedule_preempt_disabled(); lockevent_inc(rwsem_sleep_reader); + set_current_state(state); } =20 + if (state =3D=3D TASK_UNINTERRUPTIBLE) + hung_task_clear_blocker(); + __set_current_state(TASK_RUNNING); lockevent_inc(rwsem_rlock); trace_contention_end(sem, 0); @@ -1146,6 +1154,9 @@ rwsem_down_write_slowpath(struct rw_semaphore *sem, i= nt state) set_current_state(state); trace_contention_begin(sem, LCB_F_WRITE); =20 + if (state =3D=3D TASK_UNINTERRUPTIBLE) + hung_task_set_blocker(sem, BLOCKER_TYPE_RWSEM_WRITER); + for (;;) { if (rwsem_try_write_lock(sem, &waiter)) { /* rwsem_try_write_lock() implies ACQUIRE on success */ @@ -1179,6 +1190,10 @@ rwsem_down_write_slowpath(struct rw_semaphore *sem, = int state) trylock_again: raw_spin_lock_irq(&sem->wait_lock); } + + if (state =3D=3D TASK_UNINTERRUPTIBLE) + hung_task_clear_blocker(); + __set_current_state(TASK_RUNNING); raw_spin_unlock_irq(&sem->wait_lock); lockevent_inc(rwsem_wlock); --=20 2.49.0 From nobody Wed Oct 8 14:15:38 2025 Received: from mail-wr1-f54.google.com (mail-wr1-f54.google.com [209.85.221.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80CAF221FA4 for ; Fri, 27 Jun 2025 07:30:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751009407; cv=none; b=M1eqReyWcljP9wqFynN7193VGoO3smj15Y/BtxcgkBErwiQluj/LLxZrW65x2K/2yYnseRYoP/IQ7yXQbv4FgCqXowGbyMerWAiDnGGxnjGDQHl/7FFN9MnX1POqFrYGDQaqjPZfkDM4MF91pzZC54ayvCa7JF1oHtQkQAEbR6Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751009407; c=relaxed/simple; bh=gLq5QR5UkZcDNZ4qEDEV0UgI3bwdOXiGKr7EDDC5UEg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aH3P7+BA5cPBwSiR3DCpWVVTjZiB3VJTeztCOehHP0E/5PaPut+RwLrkyOKy3c0EN+pDPAXm0zh6oBBoTrPhmZ9YgkIIO0BXpTKyeWfzrL65iGh5o/vXFg/bUWwYNNnCh7hfwfcrpytIVNwP+JHa10tWeD9M6hiAWv/hkt9S/Ls= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jx1B+4/Z; arc=none smtp.client-ip=209.85.221.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jx1B+4/Z" Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-3a57ae5cb17so1075914f8f.0 for ; Fri, 27 Jun 2025 00:30:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1751009404; x=1751614204; darn=vger.kernel.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=sZx7HLeDxFUsTV7MB27dJE7edqAxtdtwVAh6e83NzOY=; b=jx1B+4/ZaITLW7T3f5modf4Q44sMWwaaTUcHE/eUzcPTe1AcrYKehHiEzTfiCfmO4r nK6Xz0hTJdvv9gWuRoQtRuN4/qHDriOFjSZNLBDiP7bNXxSoiPN93jp0vw1P0NfjxLTd 1T8CBIkCnIv7mHqBJgKelRtDy1gqAMxbSooQQCNhJaI5qWqcgt64EV7R3oVeSAYIdSNb QKM86Z9whqbE6cR++ManLg398hUZLJYIdmXSXE9yNY0gJC8+2ATTH3kqz+Fl5rsd92n4 LYSyZtFcs4MgI4INpX3OvkSVHjwpucTi8R0nWd6dvtDV/XaC7fQA4mczp+xOx+/k6kP/ Xq4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751009404; x=1751614204; 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=sZx7HLeDxFUsTV7MB27dJE7edqAxtdtwVAh6e83NzOY=; b=OQ7mGI0G5kf7ZknKOQ4cohTdF6Pi3le6C1nq7EWnawNHQpLXIfDpj3ohYTpEr2oo3b 3wPrbMJpQhRe0rEyZSqBcWPayXea+KQ6xn7N06Z5QoVqDHGQM+btjSWYNFwsHyKhOOFZ 3VCVycaFlr57OAUDXoySaTnK1+9Q6SaMYwr1eVsOoKimkDeC1GOQyXK7jI8U96LepLsG 4AAzfgnvxEGieW/uoBn/5Vdzh+X3K1qhHH3McaWmkdqeAYLapgzyFcFX9lQQBw6Ft6H2 +oXK39KEbEA/dKG9n5lieVhWxFsmtlo2FGMRYwI68KNRvcYQxBW2Q4b/Y+i5SiUaXJrl L4zw== X-Forwarded-Encrypted: i=1; AJvYcCXkBw+RulktkBOMv80oaQ2Ur3oVzmcX4kjoT7EHcStmtK/O6amcs/KTDhY83tqbL9a5IN/wXy7KSIB3L1o=@vger.kernel.org X-Gm-Message-State: AOJu0YyaxtCA9cr2FMkk876B4Tk74X+k1flSCY/j2Bx1OlHSmfUORDo+ SPemOdctCmTyL1uokU0ARwOF+UQxBy3HgEq/mkWQ6iQNECF6BO/dEIZy X-Gm-Gg: ASbGncsWSjPklUvawTZPB+VkH0aV7YYXib9V9IuKTCgckhVkhosw9/hSBrGXKBoxxis YlRG6gE7GQlMSMVY9Q3jgYE57VlOqTkzOtT4u/JOGdbDuTVDnrFr7n9W9+rE8BsF8eE9ILh2ZIn jmTNZooMkjKAPjo7B1RbT+j3NnKbbrSo/or9Cc7ppSkRh0z7D0FTkR7pG0JVCEWv5/7IjWDjakm UpcOY+lRnV22gQ0hUf2lWEhsKOJsgiY1f7mhKQKeGk53XirsowakIq1bcioagPx4QAXR/EsgQAW HCC3E2lq268YVB8G7Wk1g7VcqqMSB1lZU2pxq30SdI2kImSI X-Google-Smtp-Source: AGHT+IHLxuzOhCr2ZOuAnoMckWZohG8XUTUNZtVdZrbctK4w8YIIgD/ecNFvLienpmYMqTMQ43Nwvg== X-Received: by 2002:a5d:59c9:0:b0:3a3:6b07:20a1 with SMTP id ffacd0b85a97d-3a8feb851f2mr1958251f8f.40.1751009403503; Fri, 27 Jun 2025 00:30:03 -0700 (PDT) Received: from EBJ9932692.tcent.cn ([2a09:0:1:2::302c]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3a88c7e72b6sm1955665f8f.15.2025.06.27.00.29.58 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Fri, 27 Jun 2025 00:30:03 -0700 (PDT) From: Lance Yang X-Google-Original-From: Lance Yang To: akpm@linux-foundation.org Cc: zi.li@linux.dev, anna.schumaker@oracle.com, boqun.feng@gmail.com, joel.granados@kernel.org, jstultz@google.com, kent.overstreet@linux.dev, leonylgao@tencent.com, linux-kernel@vger.kernel.org, longman@redhat.com, mhiramat@kernel.org, mingo@redhat.com, mingzhe.yang@ly.com, peterz@infradead.org, rostedt@goodmis.org, senozhatsky@chromium.org, tfiga@chromium.org, will@kernel.org Subject: [PATCH 3/3] samples: enhance hung_task detector test with read-write semaphore support Date: Fri, 27 Jun 2025 15:29:24 +0800 Message-ID: <20250627072924.36567-4-lance.yang@linux.dev> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250627072924.36567-1-lance.yang@linux.dev> References: <20250627072924.36567-1-lance.yang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zi Li Extend the hung_task detector test module to include read-write semaphore support alongside existing mutex and semaphore tests. This module now creates additional debugfs files under /hung_task, namely 'rw_semaphore_read' and 'rw_semaphore_write', in addition to 'mutex' and 'semaphore'. Reading these files with multiple processes triggers a prolonged sleep (256 seconds) while holding the respective lock, enabling hung_task detector testing for various locking mechanisms. This change builds on the extensible hung_task_tests module, adding read-write semaphore functionality to improve test coverage for kernel locking primitives. The implementation ensures proper lock handling and includes checks to prevent redundant data reads. Usage is: > cd /sys/kernel/debug/hung_task > cat mutex & cat mutex # Test mutex blocking > cat semaphore & cat semaphore # Test semaphore blocking > cat rw_semaphore_write \ & cat rw_semaphore_read # Test rwsem blocking > cat rw_semaphore_write \ & cat rw_semaphore_write # Test rwsem blocking Update the Kconfig description to reflect the addition of read-write semaphore debugfs files. Suggested-by: Masami Hiramatsu (Google) Signed-off-by: Zi Li --- samples/Kconfig | 7 ++- samples/hung_task/hung_task_tests.c | 81 ++++++++++++++++++++++++++--- 2 files changed, 77 insertions(+), 11 deletions(-) diff --git a/samples/Kconfig b/samples/Kconfig index ffef99950206..a8880c62d4c8 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -316,10 +316,9 @@ config SAMPLE_HUNG_TASK depends on DETECT_HUNG_TASK && DEBUG_FS help Build a module that provides debugfs files (e.g., mutex, semaphore, - etc.) under /hung_task. If user reads one of these files, - it will sleep long time (256 seconds) with holding a lock. Thus, - if 2 or more processes read the same file concurrently, it will - be detected by the hung_task watchdog. + rw_semaphore_read, rw_semaphore_write) under /hung_task. + Reading these files with multiple processes triggers hung task + detection by holding locks for a long time (256 seconds). =20 source "samples/rust/Kconfig" =20 diff --git a/samples/hung_task/hung_task_tests.c b/samples/hung_task/hung_t= ask_tests.c index a5c09bd3a47d..0360ec916890 100644 --- a/samples/hung_task/hung_task_tests.c +++ b/samples/hung_task/hung_task_tests.c @@ -4,11 +4,12 @@ * semaphore, etc. * * Usage: Load this module and read `/hung_task/mutex`, - * `/hung_task/semaphore`, etc., with 2 or more processes. + * `/hung_task/semaphore`, `/hung_task/rw_semapho= re_read`, + * `/hung_task/rw_semaphore_write`, etc., with 2 or more p= rocesses. * * This is for testing kernel hung_task error messages with various locking - * mechanisms (e.g., mutex, semaphore, etc.). Note that this may freeze - * your system or cause a panic. Use only for testing purposes. + * mechanisms (e.g., mutex, semaphore, rw_semaphore_read, rw_semaphore_wri= te, etc.). + * Note that this may freeze your system or cause a panic. Use only for te= sting purposes. */ =20 #include @@ -17,21 +18,29 @@ #include #include #include +#include =20 -#define HUNG_TASK_DIR "hung_task" -#define HUNG_TASK_MUTEX_FILE "mutex" -#define HUNG_TASK_SEM_FILE "semaphore" -#define SLEEP_SECOND 256 +#define HUNG_TASK_DIR "hung_task" +#define HUNG_TASK_MUTEX_FILE "mutex" +#define HUNG_TASK_SEM_FILE "semaphore" +#define HUNG_TASK_RWSEM_READ_FILE "rw_semaphore_read" +#define HUNG_TASK_RWSEM_WRITE_FILE "rw_semaphore_write" +#define SLEEP_SECOND 256 =20 static const char dummy_string[] =3D "This is a dummy string."; static DEFINE_MUTEX(dummy_mutex); static DEFINE_SEMAPHORE(dummy_sem, 1); +static DECLARE_RWSEM(dummy_rwsem); static struct dentry *hung_task_dir; =20 /* Mutex-based read function */ static ssize_t read_dummy_mutex(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { + /* Check if data is already read */ + if (*ppos >=3D sizeof(dummy_string)) + return 0; + /* Second task waits on mutex, entering uninterruptible sleep */ guard(mutex)(&dummy_mutex); =20 @@ -46,6 +55,10 @@ static ssize_t read_dummy_mutex(struct file *file, char = __user *user_buf, static ssize_t read_dummy_semaphore(struct file *file, char __user *user_b= uf, size_t count, loff_t *ppos) { + /* Check if data is already read */ + if (*ppos >=3D sizeof(dummy_string)) + return 0; + /* Second task waits on semaphore, entering uninterruptible sleep */ down(&dummy_sem); =20 @@ -58,6 +71,46 @@ static ssize_t read_dummy_semaphore(struct file *file, c= har __user *user_buf, sizeof(dummy_string)); } =20 +/* Read-write semaphore read function */ +static ssize_t read_dummy_rwsem_read(struct file *file, char __user *user_= buf, + size_t count, loff_t *ppos) +{ + /* Check if data is already read */ + if (*ppos >=3D sizeof(dummy_string)) + return 0; + + /* Acquires read lock, allowing concurrent readers but blocks if write lo= ck is held */ + down_read(&dummy_rwsem); + + /* Sleeps here, potentially triggering hung task detection if lock is hel= d too long */ + msleep_interruptible(SLEEP_SECOND * 1000); + + up_read(&dummy_rwsem); + + return simple_read_from_buffer(user_buf, count, ppos, dummy_string, + sizeof(dummy_string)); +} + +/* Read-write semaphore write function */ +static ssize_t read_dummy_rwsem_write(struct file *file, char __user *user= _buf, + size_t count, loff_t *ppos) +{ + /* Check if data is already read */ + if (*ppos >=3D sizeof(dummy_string)) + return 0; + + /* Acquires exclusive write lock, blocking all other readers and writers = */ + down_write(&dummy_rwsem); + + /* Sleeps here, potentially triggering hung task detection if lock is hel= d too long */ + msleep_interruptible(SLEEP_SECOND * 1000); + + up_write(&dummy_rwsem); + + return simple_read_from_buffer(user_buf, count, ppos, dummy_string, + sizeof(dummy_string)); +} + /* File operations for mutex */ static const struct file_operations hung_task_mutex_fops =3D { .read =3D read_dummy_mutex, @@ -68,6 +121,16 @@ static const struct file_operations hung_task_sem_fops = =3D { .read =3D read_dummy_semaphore, }; =20 +/* File operations for rw_semaphore read */ +static const struct file_operations hung_task_rwsem_read_fops =3D { + .read =3D read_dummy_rwsem_read, +}; + +/* File operations for rw_semaphore write */ +static const struct file_operations hung_task_rwsem_write_fops =3D { + .read =3D read_dummy_rwsem_write, +}; + static int __init hung_task_tests_init(void) { hung_task_dir =3D debugfs_create_dir(HUNG_TASK_DIR, NULL); @@ -79,6 +142,10 @@ static int __init hung_task_tests_init(void) &hung_task_mutex_fops); debugfs_create_file(HUNG_TASK_SEM_FILE, 0400, hung_task_dir, NULL, &hung_task_sem_fops); + debugfs_create_file(HUNG_TASK_RWSEM_READ_FILE, 0400, hung_task_dir, NULL, + &hung_task_rwsem_read_fops); + debugfs_create_file(HUNG_TASK_RWSEM_WRITE_FILE, 0400, hung_task_dir, NULL, + &hung_task_rwsem_write_fops); =20 return 0; } --=20 2.49.0