Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp189929ybb; Tue, 31 Mar 2020 20:44:51 -0700 (PDT) X-Google-Smtp-Source: APiQypKCGG09lkMvFFtTwM5/D15V9l8q+NWIyu+7zOJiRSg2iX5CzLJsjcaWtrB0um0GgovbVzNS X-Received: by 2002:a05:6808:64c:: with SMTP id z12mr1418194oih.146.1585712691121; Tue, 31 Mar 2020 20:44:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1585712691; cv=none; d=google.com; s=arc-20160816; b=RlO2NTEuFoe/EDW/T4T/Ut+XT3787shy02rXTaWNKAUw+ABASSd3rt/k1NjVYDXeiw pt46y1W/p7+8kF8vZeljo4YF9n/adfM3FOLElCYhyP3jPN9DX+gyyhQtA3CqmEtJwCGE Qyjg+aRXA/rzKiTxRkgCVY7dNwdwxF4yUrZeVXSv4wR3jzEGb7oC/yVB5vUbrL1iOdJc yCVR7E9kH/LbD3yh8PJuyU42jL61jZQYNr9/Mw9u+KU9O9ZmCbKHd2TGalvjgYcT8BQD pCuPjdxpXMrtFegG39MtusUR/54brFDn+X5Fe/YXxoIq8UNPVVr9DE8ZQjeX/fQr4wmR W49A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=s7yCmS5K0oztAnIXmBq3PEcJj21ASIC7ccrZJ2uAxs8=; b=m11rvgJb0h1oJiQpi0setpZ2r5H94kNoOG7gu2FzhQ9IAjz31gAUcJHM+jpCf4UUvr IZu7oKF3bQ77xy+N6vODUN2Io9M0awWIwmiQVX8cHMaedpFQ6xxWz+Zqn54EaAewz3k+ 6ZDMm/ZLyk3mYBlP7gBWd/RCx0uC+kqU2NCS7SnRpP8VPdRW7viFfumDh3pwFM+r91CI QYa0LALlqCkGUgi+VtxXg0CLY+kXZIF7k29CYAaFzWvQS4HMsxNbh/Ieb5GWO06Nn2WV cte+qWu+z9p5ZT5Bs+fOP8o0kk0A0u9J0A0xlNfq/dt6lGRczRDb2qy3ZcK4M4VhLAQP KPoA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=tlGtzEA+; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z24si231927ool.40.2020.03.31.20.44.36; Tue, 31 Mar 2020 20:44:51 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=tlGtzEA+; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731655AbgDADoT (ORCPT + 99 others); Tue, 31 Mar 2020 23:44:19 -0400 Received: from mail-il1-f194.google.com ([209.85.166.194]:34882 "EHLO mail-il1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731611AbgDADoS (ORCPT ); Tue, 31 Mar 2020 23:44:18 -0400 Received: by mail-il1-f194.google.com with SMTP id 7so21690291ill.2 for ; Tue, 31 Mar 2020 20:44:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=s7yCmS5K0oztAnIXmBq3PEcJj21ASIC7ccrZJ2uAxs8=; b=tlGtzEA+EJvsQHQUXRdA089vCiFQGOd53UfNseILR3D2hfdCZzRpjZSS/OdAjPsrT3 JzQpyfe7dMS+7vOD9yRTEzreMcXHQNSYD2myqxZ3I9q2xgUikNE3No814tE+sG0bHJQn je+xI3La8eB0+Ef744JmJeeuS1s4yt+LWRJslvtJHnNzYb4HnVNN93Y9/aDguTcA4NMO 18qN4vBrwcanZKXhz3WRTwPEI8a9mdccO6d/CgiqLV9cHBzxogBrV2RjewkxfIJzmcDS xyjRrg5Umvv/9NZlU5S5mRXvUnVS9AB8mb0sXjyvg0U6IrA4M6OVJ9Z5H6w+IwcO+na1 ifJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=s7yCmS5K0oztAnIXmBq3PEcJj21ASIC7ccrZJ2uAxs8=; b=X/tMtk1kpJUbLRjw7rXVZ2BMttzggUDpjGcpjpgnrKIo9/OwVp4OOJx6pBemXb0Dd6 r+yHl5kw5ffKRO/QOWILcBXB+Yh7ATDTtbxkYGplf3rgIEOMnEUDg31w2at4h3oQqlq8 CImutdImsyQe+wvO1G0/M0pn7tHA4Cn0fcYkUXlwIXYnanV4Mb0nG4XqhumMzrFSrBg9 d8bfR+120wC/RDUPhGounU8S5YP6ebKb4zZz7tkkk4EoBzfvirq3MsKIlr/8xPrXQe9z pxZ/3hMXNPVrXy/i7CG3ifiBU8xARisgYWfh0RuNj7zqbAQQKNGR+bpnzrgZeZhafo+P HbLw== X-Gm-Message-State: ANhLgQ3p2CTTRYXuVCemgela5rPjYKmTG5aT0VLVkD99QDVVFooTdLn8 Tm+FjXN5r8Os0wLC51hcwcrGnWn/CMg4G8Qblgk= X-Received: by 2002:a92:aa0e:: with SMTP id j14mr20199108ili.52.1585712657613; Tue, 31 Mar 2020 20:44:17 -0700 (PDT) MIME-Version: 1.0 References: <20200327074308.GY11705@shao2-debian> <20200327175350.rw5gex6cwum3ohnu@linutronix.de> In-Reply-To: From: Lai Jiangshan Date: Wed, 1 Apr 2020 11:44:06 +0800 Message-ID: Subject: Re: [PATCH] workqueue: Don't double assign worker->sleeping To: Sebastian Andrzej Siewior Cc: kernel test robot , Thomas Gleixner , Ingo Molnar , "Peter Zijlstra (Intel)" , LKML , LKP , Tejun Heo Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Apr 1, 2020 at 11:22 AM Lai Jiangshan wrote: > > Hello > > If I don't miss all the issues you have listed, it is a good and straightforward > fix, but I have concern that cmpxchg_local() might have performance impact > on some non-x86 arch. > > The two issues as you have listed: > 1) WARN_ON_ONCE() on valid condition when interrupted(async-page-faulted) > 2) wq_worker_running() can be interrupted(async-page-faulted in virtual machine) > and nr_running would be decreased twice. would be *increased* twice I just saw the V2 patch, this issue is not listed, but need to be fixed too. > > For fixing issue one, we can just remove WARN_ON_ONCE() as this patch. > For fixing issue two, ->sleeping in wq_worker_running() can be checked&modified > under irq-disabled. (we can't use preempt-disabled context here) > > thanks, > Lai > > On Sat, Mar 28, 2020 at 1:53 AM Sebastian Andrzej Siewior > wrote: > > > > The kernel test robot triggered a warning with the following race: > > task-ctx interrupt-ctx > > worker > > -> process_one_work() > > -> work_item() > > -> schedule(); > > -> sched_submit_work() > > -> wq_worker_sleeping() > > -> ->sleeping = 1 > > atomic_dec_and_test(nr_running) > > __schedule(); *interrupt* > > async_page_fault() > > -> local_irq_enable(); > > -> schedule(); > > -> sched_submit_work() > > -> wq_worker_sleeping() > > -> if (WARN_ON(->sleeping)) return > > -> __schedule() > > -> sched_update_worker() > > -> wq_worker_running() > > -> atomic_inc(nr_running); > > -> ->sleeping = 0; > > > > -> sched_update_worker() > > -> wq_worker_running() > > if (!->sleeping) return > > > > In this context the warning is pointless everything is fine. > > > > However, if the interrupt occurs in wq_worker_sleeping() between reading and > > setting `sleeping' i.e. > > > > | if (WARN_ON_ONCE(worker->sleeping)) > > | return; > > *interrupt* > > | worker->sleeping = 1; > > > > then pool->nr_running will be decremented twice in wq_worker_sleeping() > > but it will be incremented only once in wq_worker_running(). > > > > Replace the assignment of `sleeping' with a cmpxchg_local() to ensure > > that there is no double assignment of the variable. The variable is only > > accessed from the local CPU. Remove the WARN statement because this > > condition can be valid. > > > > An alternative would be to move `->sleeping' to `->flags' as a new bit > > but this would require to acquire the pool->lock in wq_worker_running(). > > > > Fixes: 6d25be5782e48 ("sched/core, workqueues: Distangle worker accounting from rq lock") > > Link: https://lkml.kernel.org/r/20200327074308.GY11705@shao2-debian > > Reported-by: kernel test robot > > Signed-off-by: Sebastian Andrzej Siewior > > --- > > kernel/workqueue.c | 6 ++---- > > 1 file changed, 2 insertions(+), 4 deletions(-) > > > > diff --git a/kernel/workqueue.c b/kernel/workqueue.c > > index 4e01c448b4b48..dc477a2a3ce30 100644 > > --- a/kernel/workqueue.c > > +++ b/kernel/workqueue.c > > @@ -846,11 +846,10 @@ void wq_worker_running(struct task_struct *task) > > { > > struct worker *worker = kthread_data(task); > > > > - if (!worker->sleeping) > > + if (cmpxchg_local(&worker->sleeping, 1, 0) == 0) > > return; > > if (!(worker->flags & WORKER_NOT_RUNNING)) > > atomic_inc(&worker->pool->nr_running); > > - worker->sleeping = 0; > > } > > > > /** > > @@ -875,10 +874,9 @@ void wq_worker_sleeping(struct task_struct *task) > > > > pool = worker->pool; > > > > - if (WARN_ON_ONCE(worker->sleeping)) > > + if (cmpxchg_local(&worker->sleeping, 0, 1) == 1) > > return; > > > > - worker->sleeping = 1; > > spin_lock_irq(&pool->lock); > > > > /* > > -- > > 2.26.0 > >