From patchwork Thu Apr 10 15:23:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frederic Weisbecker X-Patchwork-Id: 14046694 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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 86F59C3601E for ; Thu, 10 Apr 2025 15:23:42 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 1EBA328010F; Thu, 10 Apr 2025 11:23:41 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 172EF28010C; Thu, 10 Apr 2025 11:23:41 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id F07D628010F; Thu, 10 Apr 2025 11:23:40 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id D17CD28010C for ; Thu, 10 Apr 2025 11:23:40 -0400 (EDT) Received: from smtpin01.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 81293C0F40 for ; Thu, 10 Apr 2025 15:23:41 +0000 (UTC) X-FDA: 83318503842.01.9FF566A Received: from nyc.source.kernel.org (nyc.source.kernel.org [147.75.193.91]) by imf19.hostedemail.com (Postfix) with ESMTP id E76821A000D for ; Thu, 10 Apr 2025 15:23:39 +0000 (UTC) Authentication-Results: imf19.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=VcFd9rDr; dmarc=pass (policy=quarantine) header.from=kernel.org; spf=pass (imf19.hostedemail.com: domain of frederic@kernel.org designates 147.75.193.91 as permitted sender) smtp.mailfrom=frederic@kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744298619; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=Rl5/uVz/HjhE0vZ1NDcvj37JosczotIBWV1ceWwYCS0=; b=0hbPuojjVfiWd3ZszENkr8wbhsDak/Pd6Q0d6+fMDXlBlN6Akz1FM76PQ9xKMTMbWEMmuW uTlU9RALWRp+rAqu/raVOAR+T1v/Hulxrn9HfmRlbXYp0NzK/9oGjdPskOLGIm5Su/nHhf qMK9LUUwzB/+eDVWn1+kEXpoYn7MzLs= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744298619; a=rsa-sha256; cv=none; b=a00iBFAh0xMuJaWNfoXWlWyl6RNl2WNxOaUqPulmwGc+AvYHue7rR9a78sjzJ43gC61+01 /n1pfGKXcYDPcRqQ2Ie8VMTBdniAP00S/3D9Q4edIKEPetpO7FZioC/+AUBzbpcqq0BIng JXPX/qTSqT+CxccdjzVr1NzFc5+3e3c= ARC-Authentication-Results: i=1; imf19.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=VcFd9rDr; dmarc=pass (policy=quarantine) header.from=kernel.org; spf=pass (imf19.hostedemail.com: domain of frederic@kernel.org designates 147.75.193.91 as permitted sender) smtp.mailfrom=frederic@kernel.org Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by nyc.source.kernel.org (Postfix) with ESMTP id 741E1A4A922; Thu, 10 Apr 2025 15:18:10 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 39DE7C4CEEA; Thu, 10 Apr 2025 15:23:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1744298618; bh=KEyxKF7bbPMo0JctDd19rU2CfoDK6otXeM0XfrzjtAM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VcFd9rDrZtAUzAuQM3q9opD0OHZq2LCU9tenwim6J0K/lltLBnIDeFGVU8YfHDh7A Hm7aPwIj4k/xM3CPD4enYLOZx3UZQ7YGlxCX1k2PRf+9fLHukIH0SxUSTXVyMFkh5d nwJGQYr2CFJ5ujH6eOD59BzLkiZZCfyNXlll2+F/3/DBdjspbzr2oHVoeKN+pFtXRk kggUN5dYSJqUZ+dEUXYtL7buoPUSGhrqnmV22Ws0sYtugj5lCEMsbIt6dVZPV1BDCR DcpCXRb4zNA27PVsgGUeBQq9Jk3VTxd6cpzaYLOWQ5eZCYvZFsRXd0ktc78Lnqw6OX gkSrGlZLP1guA== From: Frederic Weisbecker To: LKML Cc: Frederic Weisbecker , Andrew Morton , Ingo Molnar , Marcelo Tosatti , Michal Hocko , Oleg Nesterov , Peter Zijlstra , Thomas Gleixner , Valentin Schneider , Vlastimil Babka , linux-mm@kvack.org Subject: [PATCH 1/6] task_work: Provide means to check if a work is queued Date: Thu, 10 Apr 2025 17:23:22 +0200 Message-ID: <20250410152327.24504-2-frederic@kernel.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250410152327.24504-1-frederic@kernel.org> References: <20250410152327.24504-1-frederic@kernel.org> MIME-Version: 1.0 X-Rspamd-Server: rspam07 X-Rspamd-Queue-Id: E76821A000D X-Stat-Signature: kj6xwgy37y9wgrpe8sby7gh9gu73dtq8 X-Rspam-User: X-HE-Tag: 1744298619-273724 X-HE-Meta: U2FsdGVkX1+y4bWKFmjVAqPE4Aph3RSmOKKWetkh8eMMejm9NnYXiqLgvxL9KHTMiXGh/9o+wES1dnIsVrz30rXGogTqO4yMlntbAKnYXNtDhRavM6UNO2RyCVNAU+I1oWa9H+5Q73Pu4MJs63rV5+WX0bmHcHL47AR2+ZbNppgB66TcjGXunF9npnu7yB2gjNjAkzGw4s12PDsgyKndwzIizz6v2eYser1agi55RfgIwsZyFB+iDUtFK6+eT086RxxYdMAK7oreIbytxuHGgSLsLuJ0PGVVWLDnJouMCA90/n0LLajY8WYtOzcLFQqEsNm3MDZl86a3FQElMjknPVDBQu4tX/YSe8YXkjbyQeohkp7c0PN51RdmAgSOsUz6UYWl2qqZgiB7qne5+CSryYvW6FtTyd8gjR3YzYX7KcuqdoYV3G92sMv5zXnTL53a4BrRq6lgKRzW+WAzQGKPuyLVvxmu98oDrB8XZpX4Xs/Dh0GdTzHqdrFs0fgRwQlbPwTci6BfDb4uZlBFSsLuL1RU/XUhdi3g1ba6z3gMml1GeWx/h4EOtf5Z68hNZHRBSdluls7Gxh6KaYNL6Gb0mlKqap+LkjXJq+gdVTvNlp1tNrnLEPsyv4VldfF0gAYqLWmgF6Bqoqck3CeiwgstbuZNiZH6pFfJp+N9ek9HQB7Kqp/MAGVe32TcjA0r66hhE3yPm8O/jyqt+Qv/dFRxbmiJ8YLogKLgw2yxNcsjT2DgqbSVrlgMpArFszAC6s4hCYcIf0YG4VRU+Zc5WEoSkVmxSm6tJzxtEvbr9t0PDQ6uR4H/VVbMZ/FIgzvclfODXTqUV8mdFi9nb2YRKlqN2kUGOWyBobivJRrN8U2iN39J/i1V46buk2B9CpHyeR7yXZdZt4mI1PPFRVltFOGGnilBqHYX8/+IlVo9cTUCys3ZhFkv5HgYKp1a8pzSwBHPgD152YlWs+mGv/Z7TSH uQ6XOTqS f3fL9pnLVJxhfzga63CFyiXfdaaxcU9k2+RA87WJ59Ac4/2QS8z4uYgw4YHGXfQw9tiJeQqY8wPCnvzfCvobQnvbp6ppnGJk0AxzzFYPu3KAiJEd/DkXJlDe5093YNqSR0wY/EBBWosCHD+QuyBHje136C0MT4X7KtQWxLuIu0vlH6bmW2h9EJd95gKNrLnv+4ppoxnK+sCdyBP+5g/WDaSiiWSeKN7/dOeixwresMCkuPOwEA1C7iWccGU8YJ/crE0OuPjR6qgJCGKR4eMHCimkb9vTYJi2q32+2uEV0oQbNxZXzifZE7P8ZlofzqKrEk6TXLZfwTaDMhRY= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Some task work users implement their own ways to know if a callback is already queued on the current task while fiddling with the callback head internals. Provide instead a consolidated API to serve this very purpose. Reviewed-by: Oleg Nesterov Reviewed-by: Valentin Schneider Signed-off-by: Frederic Weisbecker --- include/linux/task_work.h | 12 ++++++++++++ kernel/task_work.c | 9 +++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/linux/task_work.h b/include/linux/task_work.h index 0646804860ff..31caf12c1313 100644 --- a/include/linux/task_work.h +++ b/include/linux/task_work.h @@ -5,12 +5,15 @@ #include #include +#define TASK_WORK_DEQUEUED ((void *) -1UL) + typedef void (*task_work_func_t)(struct callback_head *); static inline void init_task_work(struct callback_head *twork, task_work_func_t func) { twork->func = func; + twork->next = TASK_WORK_DEQUEUED; } enum task_work_notify_mode { @@ -26,6 +29,15 @@ static inline bool task_work_pending(struct task_struct *task) return READ_ONCE(task->task_works); } +/* + * Check if a work is queued. Beware: this is inherently racy if the work can + * be queued elsewhere than the current task. + */ +static inline bool task_work_queued(struct callback_head *twork) +{ + return twork->next != TASK_WORK_DEQUEUED; +} + int task_work_add(struct task_struct *task, struct callback_head *twork, enum task_work_notify_mode mode); diff --git a/kernel/task_work.c b/kernel/task_work.c index d1efec571a4a..56718cb824d9 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c @@ -67,8 +67,10 @@ int task_work_add(struct task_struct *task, struct callback_head *work, head = READ_ONCE(task->task_works); do { - if (unlikely(head == &work_exited)) + if (unlikely(head == &work_exited)) { + work->next = TASK_WORK_DEQUEUED; return -ESRCH; + } work->next = head; } while (!try_cmpxchg(&task->task_works, &head, work)); @@ -129,8 +131,10 @@ task_work_cancel_match(struct task_struct *task, if (!match(work, data)) { pprev = &work->next; work = READ_ONCE(*pprev); - } else if (try_cmpxchg(pprev, &work, work->next)) + } else if (try_cmpxchg(pprev, &work, work->next)) { + work->next = TASK_WORK_DEQUEUED; break; + } } raw_spin_unlock_irqrestore(&task->pi_lock, flags); @@ -224,6 +228,7 @@ void task_work_run(void) do { next = work->next; + work->next = TASK_WORK_DEQUEUED; work->func(work); work = next; cond_resched();