public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: syzbot <syzbot+9b95da55ba5146a60734@syzkaller.appspotmail.com>
To: linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com
Subject: Forwarded: [PATCH] ath9k: defer reg_in URB resubmission to workqueue to fix RCU stall
Date: Sat, 04 Apr 2026 21:41:44 -0700	[thread overview]
Message-ID: <69d1e808.a70a0220.a26f2.001a.GAE@google.com> (raw)
In-Reply-To: <69cffde1.050a0220.182279.0016.GAE@google.com>

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 <kartikey406@gmail.com>
---
 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


  parent reply	other threads:[~2026-04-05  4:41 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-03 17:50 [syzbot] [kernel?] INFO: rcu detected stall in kill syzbot
2026-04-05  1:21 ` Forwarded: [PATCH] ath9k: defer reg_in URB resubmission to workqueue syzbot
2026-04-05  2:19 ` Forwarded: [PATCH] ath9k: defer reg_in URB resubmission to workqueue to fix RCU stall syzbot
2026-04-05  4:41 ` syzbot [this message]
2026-04-05  5:18 ` syzbot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=69d1e808.a70a0220.a26f2.001a.GAE@google.com \
    --to=syzbot+9b95da55ba5146a60734@syzkaller.appspotmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=syzkaller-bugs@googlegroups.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox