net-amd-mvme147-fix-probe-banner-message.patch
nfs-remove-revoked-delegation-from-server-s-delegati.patch
misc-sgi-gru-don-t-disable-preemption-in-gru-driver.patch
+usb-gadget-dummy_hcd-switch-to-hrtimer-transfer-sche.patch
+usb-gadget-dummy_hcd-set-transfer-interval-to-1-micr.patch
+usb-gadget-dummy_hcd-execute-hrtimer-callback-in-sof.patch
+usb-gadget-dummy-hcd-fix-task-hung-problem.patch
--- /dev/null
+From 85f088c658432975d8da3a9e795e4232918db101 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Oct 2024 11:44:45 -0400
+Subject: USB: gadget: dummy-hcd: Fix "task hung" problem
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+[ Upstream commit 5189df7b8088268012882c220d6aca4e64981348 ]
+
+The syzbot fuzzer has been encountering "task hung" problems ever
+since the dummy-hcd driver was changed to use hrtimers instead of
+regular timers. It turns out that the problems are caused by a subtle
+difference between the timer_pending() and hrtimer_active() APIs.
+
+The changeover blindly replaced the first by the second. However,
+timer_pending() returns True when the timer is queued but not when its
+callback is running, whereas hrtimer_active() returns True when the
+hrtimer is queued _or_ its callback is running. This difference
+occasionally caused dummy_urb_enqueue() to think that the callback
+routine had not yet started when in fact it was almost finished. As a
+result the hrtimer was not restarted, which made it impossible for the
+driver to dequeue later the URB that was just enqueued. This caused
+usb_kill_urb() to hang, and things got worse from there.
+
+Since hrtimers have no API for telling when they are queued and the
+callback isn't running, the driver must keep track of this for itself.
+That's what this patch does, adding a new "timer_pending" flag and
+setting or clearing it at the appropriate times.
+
+Reported-by: syzbot+f342ea16c9d06d80b585@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/linux-usb/6709234e.050a0220.3e960.0011.GAE@google.com/
+Tested-by: syzbot+f342ea16c9d06d80b585@syzkaller.appspotmail.com
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Fixes: a7f3813e589f ("usb: gadget: dummy_hcd: Switch to hrtimer transfer scheduler")
+Cc: Marcello Sylvester Bauer <sylv@sylv.io>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/2dab644e-ef87-4de8-ac9a-26f100b2c609@rowland.harvard.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/dummy_hcd.c | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
+index 019e8f3007c94..6e18e8e76e8b9 100644
+--- a/drivers/usb/gadget/udc/dummy_hcd.c
++++ b/drivers/usb/gadget/udc/dummy_hcd.c
+@@ -254,6 +254,7 @@ struct dummy_hcd {
+ u32 stream_en_ep;
+ u8 num_stream[30 / 2];
+
++ unsigned timer_pending:1;
+ unsigned active:1;
+ unsigned old_active:1;
+ unsigned resuming:1;
+@@ -1304,9 +1305,11 @@ static int dummy_urb_enqueue(
+ urb->error_count = 1; /* mark as a new urb */
+
+ /* kick the scheduler, it'll do the rest */
+- if (!hrtimer_active(&dum_hcd->timer))
++ if (!dum_hcd->timer_pending) {
++ dum_hcd->timer_pending = 1;
+ hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS),
+ HRTIMER_MODE_REL_SOFT);
++ }
+
+ done:
+ spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
+@@ -1325,9 +1328,10 @@ static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+ spin_lock_irqsave(&dum_hcd->dum->lock, flags);
+
+ rc = usb_hcd_check_unlink_urb(hcd, urb, status);
+- if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING &&
+- !list_empty(&dum_hcd->urbp_list))
++ if (rc == 0 && !dum_hcd->timer_pending) {
++ dum_hcd->timer_pending = 1;
+ hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT);
++ }
+
+ spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
+ return rc;
+@@ -1814,6 +1818,7 @@ static enum hrtimer_restart dummy_timer(struct hrtimer *t)
+
+ /* look at each urb queued by the host side driver */
+ spin_lock_irqsave(&dum->lock, flags);
++ dum_hcd->timer_pending = 0;
+
+ if (!dum_hcd->udev) {
+ dev_err(dummy_dev(dum_hcd),
+@@ -1995,8 +2000,10 @@ static enum hrtimer_restart dummy_timer(struct hrtimer *t)
+ if (list_empty(&dum_hcd->urbp_list)) {
+ usb_put_dev(dum_hcd->udev);
+ dum_hcd->udev = NULL;
+- } else if (dum_hcd->rh_state == DUMMY_RH_RUNNING) {
++ } else if (!dum_hcd->timer_pending &&
++ dum_hcd->rh_state == DUMMY_RH_RUNNING) {
+ /* want a 1 msec delay here */
++ dum_hcd->timer_pending = 1;
+ hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS),
+ HRTIMER_MODE_REL_SOFT);
+ }
+@@ -2391,8 +2398,10 @@ static int dummy_bus_resume(struct usb_hcd *hcd)
+ } else {
+ dum_hcd->rh_state = DUMMY_RH_RUNNING;
+ set_link_state(dum_hcd);
+- if (!list_empty(&dum_hcd->urbp_list))
++ if (!list_empty(&dum_hcd->urbp_list)) {
++ dum_hcd->timer_pending = 1;
+ hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT);
++ }
+ hcd->state = HC_STATE_RUNNING;
+ }
+ spin_unlock_irq(&dum_hcd->dum->lock);
+@@ -2523,6 +2532,7 @@ static void dummy_stop(struct usb_hcd *hcd)
+ struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd);
+
+ hrtimer_cancel(&dum_hcd->timer);
++ dum_hcd->timer_pending = 0;
+ device_remove_file(dummy_dev(dum_hcd), &dev_attr_urbs);
+ dev_info(dummy_dev(dum_hcd), "stopped\n");
+ }
+--
+2.43.0
+
--- /dev/null
+From ea6a80c9cfa890428434f75cdbc8f729c8f34b76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Sep 2024 03:30:51 +0200
+Subject: usb: gadget: dummy_hcd: execute hrtimer callback in softirq context
+
+From: Andrey Konovalov <andreyknvl@gmail.com>
+
+[ Upstream commit 9313d139aa25e572d860f6f673b73a20f32d7f93 ]
+
+Commit a7f3813e589f ("usb: gadget: dummy_hcd: Switch to hrtimer transfer
+scheduler") switched dummy_hcd to use hrtimer and made the timer's
+callback be executed in the hardirq context.
+
+With that change, __usb_hcd_giveback_urb now gets executed in the hardirq
+context, which causes problems for KCOV and KMSAN.
+
+One problem is that KCOV now is unable to collect coverage from
+the USB code that gets executed from the dummy_hcd's timer callback,
+as KCOV cannot collect coverage in the hardirq context.
+
+Another problem is that the dummy_hcd hrtimer might get triggered in the
+middle of a softirq with KCOV remote coverage collection enabled, and that
+causes a WARNING in KCOV, as reported by syzbot. (I sent a separate patch
+to shut down this WARNING, but that doesn't fix the other two issues.)
+
+Finally, KMSAN appears to ignore tracking memory copying operations
+that happen in the hardirq context, which causes false positive
+kernel-infoleaks, as reported by syzbot.
+
+Change the hrtimer in dummy_hcd to execute the callback in the softirq
+context.
+
+Reported-by: syzbot+2388cdaeb6b10f0c13ac@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=2388cdaeb6b10f0c13ac
+Reported-by: syzbot+17ca2339e34a1d863aad@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=17ca2339e34a1d863aad
+Reported-by: syzbot+c793a7eca38803212c61@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=c793a7eca38803212c61
+Reported-by: syzbot+1e6e0b916b211bee1bd6@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=1e6e0b916b211bee1bd6
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Closes: https://lore.kernel.org/oe-lkp/202406141323.413a90d2-lkp@intel.com
+Fixes: a7f3813e589f ("usb: gadget: dummy_hcd: Switch to hrtimer transfer scheduler")
+Cc: stable@vger.kernel.org
+Acked-by: Marcello Sylvester Bauer <sylv@sylv.io>
+Signed-off-by: Andrey Konovalov <andreyknvl@gmail.com>
+Reported-by: syzbot+edd9fe0d3a65b14588d5@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=edd9fe0d3a65b14588d5
+Link: https://lore.kernel.org/r/20240904013051.4409-1-andrey.konovalov@linux.dev
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/dummy_hcd.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
+index 32a03de215d37..019e8f3007c94 100644
+--- a/drivers/usb/gadget/udc/dummy_hcd.c
++++ b/drivers/usb/gadget/udc/dummy_hcd.c
+@@ -1305,7 +1305,8 @@ static int dummy_urb_enqueue(
+
+ /* kick the scheduler, it'll do the rest */
+ if (!hrtimer_active(&dum_hcd->timer))
+- hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), HRTIMER_MODE_REL);
++ hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS),
++ HRTIMER_MODE_REL_SOFT);
+
+ done:
+ spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
+@@ -1326,7 +1327,7 @@ static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+ rc = usb_hcd_check_unlink_urb(hcd, urb, status);
+ if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING &&
+ !list_empty(&dum_hcd->urbp_list))
+- hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL);
++ hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT);
+
+ spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
+ return rc;
+@@ -1996,7 +1997,8 @@ static enum hrtimer_restart dummy_timer(struct hrtimer *t)
+ dum_hcd->udev = NULL;
+ } else if (dum_hcd->rh_state == DUMMY_RH_RUNNING) {
+ /* want a 1 msec delay here */
+- hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), HRTIMER_MODE_REL);
++ hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS),
++ HRTIMER_MODE_REL_SOFT);
+ }
+
+ spin_unlock_irqrestore(&dum->lock, flags);
+@@ -2390,7 +2392,7 @@ static int dummy_bus_resume(struct usb_hcd *hcd)
+ dum_hcd->rh_state = DUMMY_RH_RUNNING;
+ set_link_state(dum_hcd);
+ if (!list_empty(&dum_hcd->urbp_list))
+- hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL);
++ hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT);
+ hcd->state = HC_STATE_RUNNING;
+ }
+ spin_unlock_irq(&dum_hcd->dum->lock);
+@@ -2468,7 +2470,7 @@ static DEVICE_ATTR_RO(urbs);
+
+ static int dummy_start_ss(struct dummy_hcd *dum_hcd)
+ {
+- hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
++ hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT);
+ dum_hcd->timer.function = dummy_timer;
+ dum_hcd->rh_state = DUMMY_RH_RUNNING;
+ dum_hcd->stream_en_ep = 0;
+@@ -2498,7 +2500,7 @@ static int dummy_start(struct usb_hcd *hcd)
+ return dummy_start_ss(dum_hcd);
+
+ spin_lock_init(&dum_hcd->dum->lock);
+- hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
++ hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT);
+ dum_hcd->timer.function = dummy_timer;
+ dum_hcd->rh_state = DUMMY_RH_RUNNING;
+
+--
+2.43.0
+
--- /dev/null
+From 9d514adef89e7deb2adf6b0fd4b5c8f05b9101c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 17:22:11 +0200
+Subject: usb: gadget: dummy_hcd: Set transfer interval to 1 microframe
+
+From: Marcello Sylvester Bauer <sylv@sylv.io>
+
+[ Upstream commit 0a723ed3baa941ca4f51d87bab00661f41142835 ]
+
+Currently, the transfer polling interval is set to 1ms, which is the
+frame rate of full-speed and low-speed USB. The USB 2.0 specification
+introduces microframes (125 microseconds) to improve the timing
+precision of data transfers.
+
+Reducing the transfer interval to 1 microframe increases data throughput
+for high-speed and super-speed USB communication
+
+Signed-off-by: Marcello Sylvester Bauer <marcello.bauer@9elements.com>
+Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io>
+Link: https://lore.kernel.org/r/6295dbb84ca76884551df9eb157cce569377a22c.1712843963.git.sylv@sylv.io
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/dummy_hcd.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
+index 4f9c6e86456fe..32a03de215d37 100644
+--- a/drivers/usb/gadget/udc/dummy_hcd.c
++++ b/drivers/usb/gadget/udc/dummy_hcd.c
+@@ -50,6 +50,8 @@
+ #define POWER_BUDGET 500 /* in mA; use 8 for low-power port testing */
+ #define POWER_BUDGET_3 900 /* in mA */
+
++#define DUMMY_TIMER_INT_NSECS 125000 /* 1 microframe */
++
+ static const char driver_name[] = "dummy_hcd";
+ static const char driver_desc[] = "USB Host+Gadget Emulator";
+
+@@ -1303,7 +1305,7 @@ static int dummy_urb_enqueue(
+
+ /* kick the scheduler, it'll do the rest */
+ if (!hrtimer_active(&dum_hcd->timer))
+- hrtimer_start(&dum_hcd->timer, ms_to_ktime(1), HRTIMER_MODE_REL);
++ hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), HRTIMER_MODE_REL);
+
+ done:
+ spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
+@@ -1994,7 +1996,7 @@ static enum hrtimer_restart dummy_timer(struct hrtimer *t)
+ dum_hcd->udev = NULL;
+ } else if (dum_hcd->rh_state == DUMMY_RH_RUNNING) {
+ /* want a 1 msec delay here */
+- hrtimer_start(&dum_hcd->timer, ms_to_ktime(1), HRTIMER_MODE_REL);
++ hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), HRTIMER_MODE_REL);
+ }
+
+ spin_unlock_irqrestore(&dum->lock, flags);
+--
+2.43.0
+
--- /dev/null
+From 25489ee7043a92e4d8a17b04ce1f86f22ea047b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Apr 2024 16:51:28 +0200
+Subject: usb: gadget: dummy_hcd: Switch to hrtimer transfer scheduler
+
+From: Marcello Sylvester Bauer <sylv@sylv.io>
+
+[ Upstream commit a7f3813e589fd8e2834720829a47b5eb914a9afe ]
+
+The dummy_hcd transfer scheduler assumes that the internal kernel timer
+frequency is set to 1000Hz to give a polling interval of 1ms. Reducing
+the timer frequency will result in an anti-proportional reduction in
+transfer performance. Switch to a hrtimer to decouple this association.
+
+Signed-off-by: Marcello Sylvester Bauer <marcello.bauer@9elements.com>
+Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/57a1c2180ff74661600e010c234d1dbaba1d0d46.1712843963.git.sylv@sylv.io
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/dummy_hcd.c | 35 +++++++++++++++++-------------
+ 1 file changed, 20 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
+index 899ac9f9c2796..4f9c6e86456fe 100644
+--- a/drivers/usb/gadget/udc/dummy_hcd.c
++++ b/drivers/usb/gadget/udc/dummy_hcd.c
+@@ -30,7 +30,7 @@
+ #include <linux/slab.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+-#include <linux/timer.h>
++#include <linux/hrtimer.h>
+ #include <linux/list.h>
+ #include <linux/interrupt.h>
+ #include <linux/platform_device.h>
+@@ -240,7 +240,7 @@ enum dummy_rh_state {
+ struct dummy_hcd {
+ struct dummy *dum;
+ enum dummy_rh_state rh_state;
+- struct timer_list timer;
++ struct hrtimer timer;
+ u32 port_status;
+ u32 old_status;
+ unsigned long re_timeout;
+@@ -1302,8 +1302,8 @@ static int dummy_urb_enqueue(
+ urb->error_count = 1; /* mark as a new urb */
+
+ /* kick the scheduler, it'll do the rest */
+- if (!timer_pending(&dum_hcd->timer))
+- mod_timer(&dum_hcd->timer, jiffies + 1);
++ if (!hrtimer_active(&dum_hcd->timer))
++ hrtimer_start(&dum_hcd->timer, ms_to_ktime(1), HRTIMER_MODE_REL);
+
+ done:
+ spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
+@@ -1324,7 +1324,7 @@ static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+ rc = usb_hcd_check_unlink_urb(hcd, urb, status);
+ if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING &&
+ !list_empty(&dum_hcd->urbp_list))
+- mod_timer(&dum_hcd->timer, jiffies);
++ hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL);
+
+ spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
+ return rc;
+@@ -1778,7 +1778,7 @@ static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb,
+ * drivers except that the callbacks are invoked from soft interrupt
+ * context.
+ */
+-static void dummy_timer(struct timer_list *t)
++static enum hrtimer_restart dummy_timer(struct hrtimer *t)
+ {
+ struct dummy_hcd *dum_hcd = from_timer(dum_hcd, t, timer);
+ struct dummy *dum = dum_hcd->dum;
+@@ -1809,8 +1809,6 @@ static void dummy_timer(struct timer_list *t)
+ break;
+ }
+
+- /* FIXME if HZ != 1000 this will probably misbehave ... */
+-
+ /* look at each urb queued by the host side driver */
+ spin_lock_irqsave(&dum->lock, flags);
+
+@@ -1818,7 +1816,7 @@ static void dummy_timer(struct timer_list *t)
+ dev_err(dummy_dev(dum_hcd),
+ "timer fired with no URBs pending?\n");
+ spin_unlock_irqrestore(&dum->lock, flags);
+- return;
++ return HRTIMER_NORESTART;
+ }
+ dum_hcd->next_frame_urbp = NULL;
+
+@@ -1996,10 +1994,12 @@ static void dummy_timer(struct timer_list *t)
+ dum_hcd->udev = NULL;
+ } else if (dum_hcd->rh_state == DUMMY_RH_RUNNING) {
+ /* want a 1 msec delay here */
+- mod_timer(&dum_hcd->timer, jiffies + msecs_to_jiffies(1));
++ hrtimer_start(&dum_hcd->timer, ms_to_ktime(1), HRTIMER_MODE_REL);
+ }
+
+ spin_unlock_irqrestore(&dum->lock, flags);
++
++ return HRTIMER_NORESTART;
+ }
+
+ /*-------------------------------------------------------------------------*/
+@@ -2388,7 +2388,7 @@ static int dummy_bus_resume(struct usb_hcd *hcd)
+ dum_hcd->rh_state = DUMMY_RH_RUNNING;
+ set_link_state(dum_hcd);
+ if (!list_empty(&dum_hcd->urbp_list))
+- mod_timer(&dum_hcd->timer, jiffies);
++ hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL);
+ hcd->state = HC_STATE_RUNNING;
+ }
+ spin_unlock_irq(&dum_hcd->dum->lock);
+@@ -2466,7 +2466,8 @@ static DEVICE_ATTR_RO(urbs);
+
+ static int dummy_start_ss(struct dummy_hcd *dum_hcd)
+ {
+- timer_setup(&dum_hcd->timer, dummy_timer, 0);
++ hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
++ dum_hcd->timer.function = dummy_timer;
+ dum_hcd->rh_state = DUMMY_RH_RUNNING;
+ dum_hcd->stream_en_ep = 0;
+ INIT_LIST_HEAD(&dum_hcd->urbp_list);
+@@ -2495,7 +2496,8 @@ static int dummy_start(struct usb_hcd *hcd)
+ return dummy_start_ss(dum_hcd);
+
+ spin_lock_init(&dum_hcd->dum->lock);
+- timer_setup(&dum_hcd->timer, dummy_timer, 0);
++ hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
++ dum_hcd->timer.function = dummy_timer;
+ dum_hcd->rh_state = DUMMY_RH_RUNNING;
+
+ INIT_LIST_HEAD(&dum_hcd->urbp_list);
+@@ -2514,8 +2516,11 @@ static int dummy_start(struct usb_hcd *hcd)
+
+ static void dummy_stop(struct usb_hcd *hcd)
+ {
+- device_remove_file(dummy_dev(hcd_to_dummy_hcd(hcd)), &dev_attr_urbs);
+- dev_info(dummy_dev(hcd_to_dummy_hcd(hcd)), "stopped\n");
++ struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd);
++
++ hrtimer_cancel(&dum_hcd->timer);
++ device_remove_file(dummy_dev(dum_hcd), &dev_attr_urbs);
++ dev_info(dummy_dev(dum_hcd), "stopped\n");
+ }
+
+ /*-------------------------------------------------------------------------*/
+--
+2.43.0
+