Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp2707709pxv; Sun, 11 Jul 2021 23:22:26 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzcTLzGByAtZHo3RXHkZwICw0yMf9mGEnSAYYYj+XuBNEqefMkDtS8iM/BmV/rmrq0fe9a/ X-Received: by 2002:a50:9b06:: with SMTP id o6mr64379986edi.284.1626070946240; Sun, 11 Jul 2021 23:22:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626070946; cv=none; d=google.com; s=arc-20160816; b=rsCVJLSzLAW9HPTlVLI9L3OSg5zmJtbdA8EVW5AQ3ARmauIjSS2RHVJbJHl4VDddIZ wNo5HMccQGxLzwit1yQXo5KURGnTuKRY3HCzmJDdZpHKOEzZlIpmSdQdRdrE+aylaF9w AHyhFy99SSX1NTL376NpDalgK+94dtyNR7+7HkzL6NMd/XxkKRVFUsIsJfOZBRvwra2l QBaALX2Vwfe7I5wvvFrlSe2eMHPihlZliV7oUbfDZqHpIELYKTP64BTeS0SsiIoB9s7x kWKZsNm3g1Qrz0aOdGMbG+7+V/3/BIiEkBLKuXAM7q8aNQHYa0tcMsXzKbNcf/Pbgmp5 ExJA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=LrbfEEdigi3+AT3Q3kK0h3Ti4OvSQCpsEHGaQDYBcU0=; b=M3KH9qvghnhm2QR6FtrMwEvtEHukaqRiVaIN/jBYzNzcwl7BR7MmEF+1Y7pcRs9srO SsHHagwP2qfRtC3RBY3irVOKxpE5Ba1Rz8VkM8qCRBjqbK/060FShd45pgwQNqmZDF5F JRKRzm6vkSsYl6w9GLpW9Yo8LTd5FCeoXWVC3CGnQ1dc7BVdZwCamGlHOKvVZI7EBFUH IgLp9GAepxzLjo4Ah1cFVMaWDT3TIoGDYoDW9XTkhfivV4lGHNRBE7poyL5r4DPXWana 9xLRaKXzCbqCKkZhsQcNaT8l+COdbr1fASPM+81w1Ww94c0ZO/oZv5LVyJpDxAeNSVvZ G5bw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=hdOJiCOh; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bz24si8597511ejc.249.2021.07.11.23.22.03; Sun, 11 Jul 2021 23:22:26 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=hdOJiCOh; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233888AbhGLGX6 (ORCPT + 99 others); Mon, 12 Jul 2021 02:23:58 -0400 Received: from mail.kernel.org ([198.145.29.99]:37526 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234596AbhGLGWp (ORCPT ); Mon, 12 Jul 2021 02:22:45 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 5E0DC61166; Mon, 12 Jul 2021 06:19:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1626070775; bh=Ims1rXSAGRxN6QiBEy5sg3G9fANKxXysNCIqQN6rQ8k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hdOJiCOharzZZYFIVRpcSZV2DnkJyr0purlkxLpIATfCIjKVhPYipAmCACI7snB5M 07Lpi9QiA+cQTWpjHitETlj32q50xNqjRKFrfE1qWv6RwI/1G2FhHuuLeCSBKEyJEK dJbrWhaSp6yjcj/ShVaWnnRTIut2UXmBVZs/sBhQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Petr Mladek , Oleg Nesterov , Nathan Chancellor , Nick Desaulniers , Tejun Heo , Minchan Kim , jenhaochen@google.com, Martin Liu , Andrew Morton , Linus Torvalds , Sasha Levin Subject: [PATCH 5.4 135/348] kthread_worker: fix return value when kthread_mod_delayed_work() races with kthread_cancel_delayed_work_sync() Date: Mon, 12 Jul 2021 08:08:39 +0200 Message-Id: <20210712060719.162188932@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210712060659.886176320@linuxfoundation.org> References: <20210712060659.886176320@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Petr Mladek [ Upstream commit d71ba1649fa3c464c51ec7163e4b817345bff2c7 ] kthread_mod_delayed_work() might race with kthread_cancel_delayed_work_sync() or another kthread_mod_delayed_work() call. The function lets the other operation win when it sees work->canceling counter set. And it returns @false. But it should return @true as it is done by the related workqueue API, see mod_delayed_work_on(). The reason is that the return value might be used for reference counting. It has to distinguish the case when the number of queued works has changed or stayed the same. The change is safe. kthread_mod_delayed_work() return value is not checked anywhere at the moment. Link: https://lore.kernel.org/r/20210521163526.GA17916@redhat.com Link: https://lkml.kernel.org/r/20210610133051.15337-4-pmladek@suse.com Signed-off-by: Petr Mladek Reported-by: Oleg Nesterov Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: Tejun Heo Cc: Minchan Kim Cc: Cc: Martin Liu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- kernel/kthread.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/kernel/kthread.c b/kernel/kthread.c index 2eb8d7550324..b2bac5d929d2 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -1083,14 +1083,14 @@ static bool __kthread_cancel_work(struct kthread_work *work) * modify @dwork's timer so that it expires after @delay. If @delay is zero, * @work is guaranteed to be queued immediately. * - * Return: %true if @dwork was pending and its timer was modified, - * %false otherwise. + * Return: %false if @dwork was idle and queued, %true otherwise. * * A special case is when the work is being canceled in parallel. * It might be caused either by the real kthread_cancel_delayed_work_sync() * or yet another kthread_mod_delayed_work() call. We let the other command - * win and return %false here. The caller is supposed to synchronize these - * operations a reasonable way. + * win and return %true here. The return value can be used for reference + * counting and the number of queued works stays the same. Anyway, the caller + * is supposed to synchronize these operations a reasonable way. * * This function is safe to call from any context including IRQ handler. * See __kthread_cancel_work() and kthread_delayed_work_timer_fn() @@ -1102,13 +1102,15 @@ bool kthread_mod_delayed_work(struct kthread_worker *worker, { struct kthread_work *work = &dwork->work; unsigned long flags; - int ret = false; + int ret; raw_spin_lock_irqsave(&worker->lock, flags); /* Do not bother with canceling when never queued. */ - if (!work->worker) + if (!work->worker) { + ret = false; goto fast_queue; + } /* Work must not be used with >1 worker, see kthread_queue_work() */ WARN_ON_ONCE(work->worker != worker); @@ -1126,8 +1128,11 @@ bool kthread_mod_delayed_work(struct kthread_worker *worker, * be used for reference counting. */ kthread_cancel_delayed_work_timer(work, &flags); - if (work->canceling) + if (work->canceling) { + /* The number of works in the queue does not change. */ + ret = true; goto out; + } ret = __kthread_cancel_work(work); fast_queue: -- 2.30.2