From patchwork Mon Mar 18 07:53:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guoyong Wang X-Patchwork-Id: 13595066 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EA1DDC54E5D for ; Mon, 18 Mar 2024 07:54:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:MIME-Version: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=s40GUT5ZuecGd7Cuw5EoS2wMEPC2EMup1dr+n16UjQA=; b=zpaUO5w26c9C2ze3JUUpireDo7 E+Jw+3GITkAUZW6Av/vshG8u2Lvz4OO2qg65HS26rYcJs7YPCiITB5hzmreUKhyyqPjhmm37gheXm v1EiWEAbe/3/1KWMq1HUNxFosF+xGRZH9p0ZWUVhTOY7uR+yguuCu1bYIEEGs+sewilHz0W18nRwo 7cfkOKLcfto0fdApWOztKoQ4kEtaY/+SX1Bk0IYT3PDiLZsGQ/PlNUOSFuE3a0OikPVLEyMCK6Css NNdBhGyvGkRGD1puS2TKsEA2y9iBzk91+kZKnoeQ8tDVEUWLzzFcUFpe7czuLFbUJNk5dilhVX/mE GQteOkiA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rm7pi-00000007flX-216r; Mon, 18 Mar 2024 07:54:58 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rm7pf-00000007fkc-1YNi; Mon, 18 Mar 2024 07:54:57 +0000 X-UUID: cb63cc00e4fc11ee9aa9374d6d45775a-20240318 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:Message-ID:Date:Subject:CC:To:From; bh=s40GUT5ZuecGd7Cuw5EoS2wMEPC2EMup1dr+n16UjQA=; b=efyapZeTMezYjToAleSHqUnGONntmOgGxDnjUEBzVsGV0VBHae55mLkhTx1cKm6YFzrYXjr3nEwfGy1ZWmg7aXJ258ojGINHh1Zhz07kXlpiq4nR3zljZbFGp+06xARk4W9zLUX+Hgsk09MbMo4HKIaAgVOcMy7dvdUjxIv0TFU=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.37,REQID:01ce422a-6c02-40d3-b0f2-07570100302f,IP:0,U RL:0,TC:0,Content:0,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION: release,TS:0 X-CID-META: VersionHash:6f543d0,CLOUDID:48ff1f85-8d4f-477b-89d2-1e3bdbef96d1,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:11|1,File:nil,RT:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES :1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0 X-CID-BVR: 0 X-CID-BAS: 0,_,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR,TF_CID_SPAM_ULN X-UUID: cb63cc00e4fc11ee9aa9374d6d45775a-20240318 Received: from mtkmbs13n2.mediatek.inc [(172.21.101.108)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 930835529; Mon, 18 Mar 2024 00:54:49 -0700 Received: from mtkmbs13n2.mediatek.inc (172.21.101.108) by mtkmbs10n2.mediatek.inc (172.21.101.183) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Mon, 18 Mar 2024 15:54:13 +0800 Received: from mbjsdccf07.gcn.mediatek.inc (10.15.20.246) by mtkmbs13n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Mon, 18 Mar 2024 15:54:12 +0800 From: Guoyong Wang To: Theodore Ts'o , "Jason A . Donenfeld" , Tejun Heo , Lai Jiangshan , "Matthias Brugger" , AngeloGioacchino Del Regno CC: , , , , "Guoyong Wang" Subject: [PATCH] random: Fix the issue of '_might_sleep' function running in an atomic contex Date: Mon, 18 Mar 2024 15:53:27 +0800 Message-ID: <20240318075327.26318-1-guoyong.wang@mediatek.com> X-Mailer: git-send-email 2.18.0 MIME-Version: 1.0 X-TM-AS-Product-Ver: SMEX-14.0.0.3152-9.1.1006-23728.005 X-TM-AS-Result: No-10--3.305300-8.000000 X-TMASE-MatchedRID: GSiycdxM5vtW/DiEtl1O86wxbZnudyr7reJWlnSW7AzFJnEpmt9OEwef 5FoKtUGzyEeGCxgB/y0u5ed2FW2K2WA2IAXETeuKI0cHLI6lhgLt/okBLaEo+C3FY27PpHmsrW4 1+BBqq+/5NLTowdvTKMhRl2j/G5EDdejbiw/Um0KEryjhqiyzyitovaaHxlUrXFNHTRKzg/pm+j 6YVbX2YOmpHB3eYmnZsvQLAMZPkyUGSS/0WwytR4+YSzwl92XTu4ICdvW94WGAZpvTq6Jh4cS4G +2ecnOxNgHYUSdPXp2+LT/N9L0eANL8YenPOW5EPey2g5E3u1vJAXSoafphsVdwRHrgRcbqWmrY r8SaWTXFvFNUfOxLYhIlVYCqhV5OHxPMjOKY7A9t1O49r1VEa8RB0bsfrpPI0PU0TdJoUte6AOO V0y1r/Y9WMC5C2SBsqQcdrSfVFJ8mPBzXYStCYO4nGk5zzAi/lq6sb0EeGWq1Khzt1zZu8G2Ynp iHC6gVvqJlNl3XQXCOh+wyNBrFXDJiNuKohDcKzKSG3JdyKAPqtV2AGMNPavWdclq8lU1q X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No X-TMASE-Result: 10--3.305300-8.000000 X-TMASE-Version: SMEX-14.0.0.3152-9.1.1006-23728.005 X-TM-SNTS-SMTP: 2290C989DD72737292ADF789F77AAC644350473F9635B32C6ACEF6B4E6F677C52000:8 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240318_005455_624512_3CB3B47E X-CRM114-Status: GOOD ( 15.39 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org 'input_handle_event' runs in an atomic context (spinlock). In rare instances, it may call the '_might_sleep' function, which could trigger a kernel exception. Backtrace: [] die+0xa8/0x2fc [] bug_handler+0x44/0xec [] brk_handler+0x90/0x144 [] do_debug_exception+0xa0/0x148 [] el1_dbg+0x60/0x7c [] el1h_64_sync_handler+0x38/0x90 [] el1h_64_sync+0x64/0x6c [] __might_resched+0x1fc/0x2e8 [] __might_sleep+0x44/0x7c [] cpus_read_lock+0x1c/0xec [] static_key_enable+0x14/0x38 [] crng_set_ready+0x14/0x28 [] execute_in_process_context+0xb8/0xf8 [] _credit_init_bits+0x118/0x1dc [] add_timer_randomness+0x264/0x270 [] add_input_randomness+0x38/0x48 [] input_handle_event+0x2b8/0x490 [] input_event+0x6c/0x98 Signed-off-by: Guoyong Wang --- drivers/char/random.c | 2 +- include/linux/workqueue.h | 1 + kernel/workqueue.c | 26 ++++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 456be28ba67c..00be9426a6fc 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -719,7 +719,7 @@ static void __cold _credit_init_bits(size_t bits) if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) { crng_reseed(NULL); /* Sets crng_init to CRNG_READY under base_crng.lock. */ if (static_key_initialized) - execute_in_process_context(crng_set_ready, &set_ready); + execute_in_non_atomic_context(crng_set_ready, &set_ready); atomic_notifier_call_chain(&random_ready_notifier, 0, NULL); wake_up_interruptible(&crng_init_wait); kill_fasync(&fasync, SIGIO, POLL_IN); diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 158784dd189a..eb17c62d23aa 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -550,6 +550,7 @@ extern void drain_workqueue(struct workqueue_struct *wq); extern int schedule_on_each_cpu(work_func_t func); int execute_in_process_context(work_func_t fn, struct execute_work *); +int execute_in_non_atomic_context(work_func_t fn, struct execute_work *ew); extern bool flush_work(struct work_struct *work); extern bool cancel_work(struct work_struct *work); diff --git a/kernel/workqueue.c b/kernel/workqueue.c index bf2bdac46843..8f212346da7a 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -4449,6 +4449,32 @@ int execute_in_process_context(work_func_t fn, struct execute_work *ew) } EXPORT_SYMBOL_GPL(execute_in_process_context); +/** + * execute_in_non_atomic_context - reliably execute the routine with user context + * @fn: the function to execute + * @ew: guaranteed storage for the execute work structure (must + * be available when the work executes) + * + * Schedules the function for delayed execution if atomic context is available, + * otherwise executes the function immediately . + * + * Return: 0 - function was executed + * 1 - function was scheduled for execution + */ +int execute_in_non_atomic_context(work_func_t fn, struct execute_work *ew) +{ + if (!in_atomic()) { + fn(&ew->work); + return 0; + } + + INIT_WORK(&ew->work, fn); + schedule_work(&ew->work); + + return 1; +} +EXPORT_SYMBOL_GPL(execute_in_non_atomic_context); + /** * free_workqueue_attrs - free a workqueue_attrs * @attrs: workqueue_attrs to free