From nobody Fri Oct 17 13:24:05 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9F79CC433FE for ; Wed, 19 Oct 2022 10:40:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231772AbiJSKk0 (ORCPT ); Wed, 19 Oct 2022 06:40:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53676 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230429AbiJSKj2 (ORCPT ); Wed, 19 Oct 2022 06:39:28 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 22AA36587; Wed, 19 Oct 2022 03:18:18 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 3E7E7B823B7; Wed, 19 Oct 2022 08:53:27 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id AB032C433D7; Wed, 19 Oct 2022 08:53:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1666169606; bh=TCo4by4CCbBMMGpHCxdYLBrGbgOCt+MtL6GXRYTS2bA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Cvapa5nimW2xavZQR9eQ9IzMhCGWpb0WVRCR1/D5MEqoDtGlKtxePEWfyhBl+zWvi 7m4ly8fS+TSXELAel6phdSq/zcnoJu9oCvs5yMnJppQfnKdqj8MKGviQNf9Buy4fji zOGxHWYWy7Hnzju5NeAlATdCjDgiaonDhvn0120A= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Duoming Zhou , Brian Norris , Kalle Valo , Sasha Levin Subject: [PATCH 6.0 306/862] mwifiex: fix sleep in atomic context bugs caused by dev_coredumpv Date: Wed, 19 Oct 2022 10:26:33 +0200 Message-Id: <20221019083303.537673194@linuxfoundation.org> X-Mailer: git-send-email 2.38.0 In-Reply-To: <20221019083249.951566199@linuxfoundation.org> References: <20221019083249.951566199@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Duoming Zhou [ Upstream commit 551e4745c7f218da7070b36a06318592913676ff ] There are sleep in atomic context bugs when uploading device dump data in mwifiex. The root cause is that dev_coredumpv could not be used in atomic contexts, because it calls dev_set_name which include operations that may sleep. The call tree shows execution paths that could lead to bugs: (Interrupt context) fw_dump_timer_fn mwifiex_upload_device_dump dev_coredumpv(..., GFP_KERNEL) dev_coredumpm() kzalloc(sizeof(*devcd), gfp); //may sleep dev_set_name kobject_set_name_vargs kvasprintf_const(GFP_KERNEL, ...); //may sleep kstrdup(s, GFP_KERNEL); //may sleep The corresponding fail log is shown below: [ 135.275938] usb 1-1: =3D=3D mwifiex dump information to /sys/class/devco= redump start [ 135.281029] BUG: sleeping function called from invalid context at includ= e/linux/sched/mm.h:265 ... [ 135.293613] Call Trace: [ 135.293613] [ 135.293613] dump_stack_lvl+0x57/0x7d [ 135.293613] __might_resched.cold+0x138/0x173 [ 135.293613] ? dev_coredumpm+0xca/0x2e0 [ 135.293613] kmem_cache_alloc_trace+0x189/0x1f0 [ 135.293613] ? devcd_match_failing+0x30/0x30 [ 135.293613] dev_coredumpm+0xca/0x2e0 [ 135.293613] ? devcd_freev+0x10/0x10 [ 135.293613] dev_coredumpv+0x1c/0x20 [ 135.293613] ? devcd_match_failing+0x30/0x30 [ 135.293613] mwifiex_upload_device_dump+0x65/0xb0 [ 135.293613] ? mwifiex_dnld_fw+0x1b0/0x1b0 [ 135.293613] call_timer_fn+0x122/0x3d0 [ 135.293613] ? msleep_interruptible+0xb0/0xb0 [ 135.293613] ? lock_downgrade+0x3c0/0x3c0 [ 135.293613] ? __next_timer_interrupt+0x13c/0x160 [ 135.293613] ? lockdep_hardirqs_on_prepare+0xe/0x220 [ 135.293613] ? mwifiex_dnld_fw+0x1b0/0x1b0 [ 135.293613] __run_timers.part.0+0x3f8/0x540 [ 135.293613] ? call_timer_fn+0x3d0/0x3d0 [ 135.293613] ? arch_restore_msi_irqs+0x10/0x10 [ 135.293613] ? lapic_next_event+0x31/0x40 [ 135.293613] run_timer_softirq+0x4f/0xb0 [ 135.293613] __do_softirq+0x1c2/0x651 ... [ 135.293613] RIP: 0010:default_idle+0xb/0x10 [ 135.293613] RSP: 0018:ffff888006317e68 EFLAGS: 00000246 [ 135.293613] RAX: ffffffff82ad8d10 RBX: ffff888006301cc0 RCX: ffffffff82a= c90e1 [ 135.293613] RDX: ffffed100d9ff1b4 RSI: ffffffff831ad140 RDI: ffffffff82a= d8f20 [ 135.293613] RBP: 0000000000000003 R08: 0000000000000000 R09: ffff88806cf= f8d9b [ 135.293613] R10: ffffed100d9ff1b3 R11: 0000000000000001 R12: ffffffff845= 93410 [ 135.293613] R13: 0000000000000000 R14: 0000000000000000 R15: 1ffff11000c= 62fd2 ... [ 135.389205] usb 1-1: =3D=3D mwifiex dump information to /sys/class/devco= redump end This patch uses delayed work to replace timer and moves the operations that may sleep into a delayed work in order to mitigate bugs, it was tested on Marvell 88W8801 chip whose port is usb and the firmware is usb8801_uapsta.bin. The following is the result after using delayed work to replace timer. [ 134.936453] usb 1-1: =3D=3D mwifiex dump information to /sys/class/devco= redump start [ 135.043344] usb 1-1: =3D=3D mwifiex dump information to /sys/class/devco= redump end As we can see, there is no bug now. Fixes: f5ecd02a8b20 ("mwifiex: device dump support for usb interface") Signed-off-by: Duoming Zhou Reviewed-by: Brian Norris Acked-by: Greg Kroah-Hartman Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/5cfa5c473ff6d069cb67760ffa04a2f84ef450a8.16= 61252818.git.duoming@zju.edu.cn Signed-off-by: Sasha Levin --- drivers/net/wireless/marvell/mwifiex/init.c | 9 +++++---- drivers/net/wireless/marvell/mwifiex/main.h | 3 ++- drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wire= less/marvell/mwifiex/init.c index fc77489cc511..7dddb4b5dea1 100644 --- a/drivers/net/wireless/marvell/mwifiex/init.c +++ b/drivers/net/wireless/marvell/mwifiex/init.c @@ -51,9 +51,10 @@ static void wakeup_timer_fn(struct timer_list *t) adapter->if_ops.card_reset(adapter); } =20 -static void fw_dump_timer_fn(struct timer_list *t) +static void fw_dump_work(struct work_struct *work) { - struct mwifiex_adapter *adapter =3D from_timer(adapter, t, devdump_timer); + struct mwifiex_adapter *adapter =3D + container_of(work, struct mwifiex_adapter, devdump_work.work); =20 mwifiex_upload_device_dump(adapter); } @@ -309,7 +310,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter= *adapter) adapter->active_scan_triggered =3D false; timer_setup(&adapter->wakeup_timer, wakeup_timer_fn, 0); adapter->devdump_len =3D 0; - timer_setup(&adapter->devdump_timer, fw_dump_timer_fn, 0); + INIT_DELAYED_WORK(&adapter->devdump_work, fw_dump_work); } =20 /* @@ -388,7 +389,7 @@ static void mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) { del_timer(&adapter->wakeup_timer); - del_timer_sync(&adapter->devdump_timer); + cancel_delayed_work_sync(&adapter->devdump_work); mwifiex_cancel_all_pending_cmd(adapter); wake_up_interruptible(&adapter->cmd_wait_q.wait); wake_up_interruptible(&adapter->hs_activate_wait_q); diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wire= less/marvell/mwifiex/main.h index 87729d251fed..63f861e6b28a 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -37,6 +37,7 @@ #include #include #include +#include =20 #include "decl.h" #include "ioctl.h" @@ -1043,7 +1044,7 @@ struct mwifiex_adapter { /* Device dump data/length */ void *devdump_data; int devdump_len; - struct timer_list devdump_timer; + struct delayed_work devdump_work; =20 bool ignore_btcoex_events; }; diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net= /wireless/marvell/mwifiex/sta_event.c index b95e90a7d124..e80e372cce8c 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_event.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c @@ -611,8 +611,8 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv, * transmission event get lost, in this cornel case, * user would still get partial of the dump. */ - mod_timer(&adapter->devdump_timer, - jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); + schedule_delayed_work(&adapter->devdump_work, + msecs_to_jiffies(MWIFIEX_TIMER_10S)); } =20 /* Overflow check */ @@ -631,7 +631,7 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv, return; =20 upload_dump: - del_timer_sync(&adapter->devdump_timer); + cancel_delayed_work_sync(&adapter->devdump_work); mwifiex_upload_device_dump(adapter); } =20 --=20 2.35.1