From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ot1-f71.google.com (mail-ot1-f71.google.com [209.85.210.71]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C85DA1EEA3C for ; Sun, 5 Apr 2026 04:41:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.71 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775364107; cv=none; b=bU02nxaP+wC5ZBRczt3+G7a07sBE2b9EtAITADSPQlgjyqAAXW0PWVm1WcDAHMKYKaUEvNCcJ+SztqWjheVIlFGzsZTmB0sDDHRWCoL4anfNco8cMcWGvgLYO7VErCJCdu2wLaQ87hAHjsp9SOr/VraXU17XVP7CPxTKwkIVWig= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775364107; c=relaxed/simple; bh=LCzhZW9mcRrqXg6ukR9u3f/mDq6IiZ+NesvzWAHpdgg=; h=MIME-Version:Date:In-Reply-To:Message-ID:Subject:From:To: Content-Type; b=FcaQvpghbpdG2W6DGyNC2MOCqhRnvAqPdA7XTcL+QCZUuqqY4mYMNEywOtnhG1Bz1hKTm7YCJjOJ/yPFXZH5Dh7tUK2rNfxim26hL2nN7WcpnRljqFlyPK72hguOpF5OTFzs7xVpDps5f9fqLmLuH5TVDQ9X/Ed89kgWwjmhBWU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=syzkaller.appspotmail.com; spf=pass smtp.mailfrom=M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com; arc=none smtp.client-ip=209.85.210.71 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=syzkaller.appspotmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com Received: by mail-ot1-f71.google.com with SMTP id 46e09a7af769-7d9d60f8e3aso6272729a34.3 for ; Sat, 04 Apr 2026 21:41:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775364105; x=1775968905; h=to:from:subject:message-id:in-reply-to:date:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nN3Mc+bvC4/UZs3H2BqUvFJn4c2GEvPiC4vq/6j5fQA=; b=Yso84b9QpQ7gDw3Yl2OZvILDjPHgoewLqc0EivUveWBe97AmF9GLIH7j7FlfgTypFq 8mcDe24QTxNoXXJMhjfktU3BeOmNoh2Myq+9JiYyduvcw1M1Ehy/PyVkLimm9PQnyaz6 6wOsK6gUZsqUNcL4AYVIIoLggSBuDXwWH8NHzHLEfaEAnDZZEHvemz3eslC1iWfBzfPW X61pakllSS6DDS67f0kYCp1fhtns3WiKXNNQTgVqudf02OeZZdrV1nRjsWDsuFVB0Xnb fsn7hc/3bdCcWPgkwYMLdELc52hGbjfUUzmtx2/5ll5tL/720o90MJgdUJp/FP7zGIJg ToQQ== X-Gm-Message-State: AOJu0YwfebN7RgXQ7gBMj8R0dVur7/2/3dtDBh5H2KrcDml5ttb+wKpK h/FNhKZ6fLB5NimJuelppprj5TNSzi4somQIfTzz3mXRryezANtEU/hoY5fh5aaN2ca0xE+ZJ+X j2y76Ib8e8V+ZOmGfhGkvtk2kyM9Rr+DyNuRcAodIS8Z0PwqCdTLrSJNmIIw= Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Received: by 2002:a05:6820:1686:b0:685:5300:f1ab with SMTP id 006d021491bc7-68553103d5dmr226286eaf.34.1775364104764; Sat, 04 Apr 2026 21:41:44 -0700 (PDT) Date: Sat, 04 Apr 2026 21:41:44 -0700 In-Reply-To: <69cffde1.050a0220.182279.0016.GAE@google.com> X-Google-Appengine-App-Id: s~syzkaller X-Google-Appengine-App-Id-Alias: syzkaller Message-ID: <69d1e808.a70a0220.a26f2.001a.GAE@google.com> Subject: Forwarded: [PATCH] ath9k: defer reg_in URB resubmission to workqueue to fix RCU stall From: syzbot To: linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com Content-Type: text/plain; charset="UTF-8" For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: [PATCH] ath9k: defer reg_in URB resubmission to workqueue to fix RCU stall Author: kartikey406@gmail.com #syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master ath9k_hif_usb_reg_in_cb() is a URB completion callback that runs in softirq context via dummy_hcd's hrtimer which is registered with HRTIMER_MODE_REL_SOFT. Calling usb_submit_urb() directly from this softirq context triggers a long synchronous chain: dummy_urb_enqueue() hrtimer_start(HRTIMER_MODE_REL_SOFT) dummy_timer() __usb_hcd_giveback_urb() ath9k_hif_usb_reg_in_cb() usb_submit_urb() <- back to start This keeps the CPU busy in softirq context indefinitely, starving the rcu_preempt kthread and causing an RCU stall: rcu: rcu_preempt kthread starved for 3053 jiffies! rcu: Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior. Fix this by introducing a small per-resubmission wrapper struct (reg_in_work) that is freshly allocated on each URB completion and carries its own work_struct. The resubmission is then deferred to the system workqueue via schedule_work(), allowing the softirq to exit quickly. Using a fresh wrapper per completion avoids races that would arise from reusing a single embedded work_struct: - INIT_WORK() is called on a newly allocated struct so there is no risk of reinitialising a work item that is still queued or running. - schedule_work() on a fresh work_struct always succeeds so no resubmission is ever silently dropped. - usb_get_urb() is called before schedule_work() and usb_put_urb() is called last in the worker after all URB accesses are complete, ensuring the URB remains valid for the entire lifetime of the work item. On resubmission failure in the worker the original error path is preserved: skb and rx_buf are freed and urb->context is set to NULL before dropping the URB reference, matching the behaviour of the original goto free_skb path. Reported-by: syzbot+9b95da55ba5146a60734@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=9b95da55ba5146a60734 Signed-off-by: Deepanshu Kartikey --- drivers/net/wireless/ath/ath9k/hif_usb.c | 53 ++++++++++++++++++++---- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 8533b88974b2..0f9536b2d0a2 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -731,12 +731,43 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb) kfree(rx_buf); } +struct reg_in_work { + struct urb *urb; + struct hif_device_usb *hif_dev; + struct work_struct work; +}; + +static void ath9k_hif_usb_reg_in_resubmit(struct work_struct *work) +{ + struct reg_in_work *rw = container_of(work, + struct reg_in_work, + work); + struct urb *urb = rw->urb; + struct rx_buf *rx_buf = urb->context; + + int ret; + + usb_anchor_urb(rw->urb, &rw->hif_dev->reg_in_submitted); + ret = usb_submit_urb(rw->urb, GFP_KERNEL); + + if (ret) { + usb_unanchor_urb(rw->urb); + if (rx_buf) { + kfree_skb(rx_buf->skb); + kfree(rx_buf); + urb->context = NULL; + } + } + + usb_put_urb(urb); + kfree(rw); +} + static void ath9k_hif_usb_reg_in_cb(struct urb *urb) { struct rx_buf *rx_buf = urb->context; struct hif_device_usb *hif_dev = rx_buf->hif_dev; struct sk_buff *skb = rx_buf->skb; - int ret; if (!skb) return; @@ -786,14 +817,20 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) } resubmit: - usb_anchor_urb(urb, &hif_dev->reg_in_submitted); - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret) { - usb_unanchor_urb(urb); - goto free_skb; + { + struct reg_in_work *rw; + + rw = kmalloc_obj(*rw, GFP_ATOMIC); + if (!rw) + goto free_skb; + + rw->urb = urb; + rw->hif_dev = hif_dev; + usb_get_urb(urb); + INIT_WORK(&rw->work, ath9k_hif_usb_reg_in_resubmit); + schedule_work(&rw->work); + return; } - - return; free_skb: kfree_skb(skb); free_rx_buf: -- 2.43.0