From patchwork Fri Nov 5 20:35:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Morton X-Patchwork-Id: 12605411 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8A7A4C433EF for ; Fri, 5 Nov 2021 20:35:53 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 4394A611C0 for ; Fri, 5 Nov 2021 20:35:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 4394A611C0 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=linux-foundation.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=kvack.org Received: by kanga.kvack.org (Postfix) id D3FDE940019; Fri, 5 Nov 2021 16:35:52 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id CEDB1940007; Fri, 5 Nov 2021 16:35:52 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id BB3C0940019; Fri, 5 Nov 2021 16:35:52 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0117.hostedemail.com [216.40.44.117]) by kanga.kvack.org (Postfix) with ESMTP id ADBAE940007 for ; Fri, 5 Nov 2021 16:35:52 -0400 (EDT) Received: from smtpin18.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with ESMTP id 6B0318249980 for ; Fri, 5 Nov 2021 20:35:52 +0000 (UTC) X-FDA: 78776032944.18.8E6C80B Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by imf28.hostedemail.com (Postfix) with ESMTP id F403C90000AF for ; Fri, 5 Nov 2021 20:35:51 +0000 (UTC) Received: by mail.kernel.org (Postfix) with ESMTPSA id A0F356125F; Fri, 5 Nov 2021 20:35:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linux-foundation.org; s=korg; t=1636144551; bh=6hwGJeuqg+C82l2O5CY/QOwkqZrGCqqopInDMa9RhMo=; h=Date:From:To:Subject:In-Reply-To:From; b=B1ePJecY1HVeXBNLPtbLMIantay4e/WF5zdF2xcgeqvgqVpE1tvxFjfnZvaWRL0t6 zUILTx9CJq/Mnct3M/iHnOH3wj4ncBPBtpeXwXFT9gB9Oc9XSAxN2AZebO78C1/s3q DD1J+Q9CCGApn0MAQwDUyNtd6aXVzy/x6lIiEkC0= Date: Fri, 05 Nov 2021 13:35:50 -0700 From: Andrew Morton To: akpm@linux-foundation.org, andreyknvl@gmail.com, bigeasy@linutronix.de, dvyukov@google.com, elver@google.com, glider@google.com, gustavoars@kernel.org, jiangshanlai@gmail.com, linux-mm@kvack.org, mm-commits@vger.kernel.org, ryabinin.a.a@gmail.com, skhan@linuxfoundation.org, tarasmadan@google.com, tglx@linutronix.de, tj@kernel.org, torvalds@linux-foundation.org, vinmenon@codeaurora.org, vjitta@codeaurora.org, walter-zh.wu@mediatek.com Subject: [patch 024/262] workqueue, kasan: avoid alloc_pages() when recording stack Message-ID: <20211105203550.82Ko3s-BI%akpm@linux-foundation.org> In-Reply-To: <20211105133408.cccbb98b71a77d5e8430aba1@linux-foundation.org> User-Agent: s-nail v14.8.16 X-Rspamd-Server: rspam03 X-Rspamd-Queue-Id: F403C90000AF X-Stat-Signature: rc6idtg5zfyb7pgnw9eby5n1hdxsqxpa Authentication-Results: imf28.hostedemail.com; dkim=pass header.d=linux-foundation.org header.s=korg header.b=B1ePJecY; spf=pass (imf28.hostedemail.com: domain of akpm@linux-foundation.org designates 198.145.29.99 as permitted sender) smtp.mailfrom=akpm@linux-foundation.org; dmarc=none X-HE-Tag: 1636144551-183641 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: From: Marco Elver Subject: workqueue, kasan: avoid alloc_pages() when recording stack Shuah Khan reported: | When CONFIG_PROVE_RAW_LOCK_NESTING=y and CONFIG_KASAN are enabled, | kasan_record_aux_stack() runs into "BUG: Invalid wait context" when | it tries to allocate memory attempting to acquire spinlock in page | allocation code while holding workqueue pool raw_spinlock. | | There are several instances of this problem when block layer tries | to __queue_work(). Call trace from one of these instances is below: | | kblockd_mod_delayed_work_on() | mod_delayed_work_on() | __queue_delayed_work() | __queue_work() (rcu_read_lock, raw_spin_lock pool->lock held) | insert_work() | kasan_record_aux_stack() | kasan_save_stack() | stack_depot_save() | alloc_pages() | __alloc_pages() | get_page_from_freelist() | rm_queue() | rm_queue_pcplist() | local_lock_irqsave(&pagesets.lock, flags); | [ BUG: Invalid wait context triggered ] The default kasan_record_aux_stack() calls stack_depot_save() with GFP_NOWAIT, which in turn can then call alloc_pages(GFP_NOWAIT, ...). In general, however, it is not even possible to use either GFP_ATOMIC nor GFP_NOWAIT in certain non-preemptive contexts, including raw_spin_locks (see gfp.h and ab00db216c9c7). Fix it by instructing stackdepot to not expand stack storage via alloc_pages() in case it runs out by using kasan_record_aux_stack_noalloc(). While there is an increased risk of failing to insert the stack trace, this is typically unlikely, especially if the same insertion had already succeeded previously (stack depot hit). For frequent calls from the same location, it therefore becomes extremely unlikely that kasan_record_aux_stack_noalloc() fails. Link: https://lkml.kernel.org/r/20210902200134.25603-1-skhan@linuxfoundation.org Link: https://lkml.kernel.org/r/20210913112609.2651084-7-elver@google.com Signed-off-by: Marco Elver Reported-by: Shuah Khan Tested-by: Shuah Khan Acked-by: Sebastian Andrzej Siewior Acked-by: Tejun Heo Reviewed-by: Andrey Konovalov Cc: Alexander Potapenko Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: "Gustavo A. R. Silva" Cc: Lai Jiangshan Cc: Taras Madan Cc: Thomas Gleixner Cc: Vijayanand Jitta Cc: Vinayak Menon Cc: Walter Wu Signed-off-by: Andrew Morton --- kernel/workqueue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/kernel/workqueue.c~workqueue-kasan-avoid-alloc_pages-when-recording-stack +++ a/kernel/workqueue.c @@ -1350,7 +1350,7 @@ static void insert_work(struct pool_work struct worker_pool *pool = pwq->pool; /* record the work call stack in order to print it in KASAN reports */ - kasan_record_aux_stack(work); + kasan_record_aux_stack_noalloc(work); /* we own @work, set data and link */ set_work_pwq(work, pwq, extra_flags);