Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: gadget: dummy_hcd: Switch to hrtimer transfer scheduler

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>

authored by

Marcello Sylvester Bauer and committed by
Greg Kroah-Hartman
a7f3813e 920e7522

+20 -15
+20 -15
drivers/usb/gadget/udc/dummy_hcd.c
··· 30 30 #include <linux/slab.h> 31 31 #include <linux/errno.h> 32 32 #include <linux/init.h> 33 - #include <linux/timer.h> 33 + #include <linux/hrtimer.h> 34 34 #include <linux/list.h> 35 35 #include <linux/interrupt.h> 36 36 #include <linux/platform_device.h> ··· 240 240 struct dummy_hcd { 241 241 struct dummy *dum; 242 242 enum dummy_rh_state rh_state; 243 - struct timer_list timer; 243 + struct hrtimer timer; 244 244 u32 port_status; 245 245 u32 old_status; 246 246 unsigned long re_timeout; ··· 1301 1301 urb->error_count = 1; /* mark as a new urb */ 1302 1302 1303 1303 /* kick the scheduler, it'll do the rest */ 1304 - if (!timer_pending(&dum_hcd->timer)) 1305 - mod_timer(&dum_hcd->timer, jiffies + 1); 1304 + if (!hrtimer_active(&dum_hcd->timer)) 1305 + hrtimer_start(&dum_hcd->timer, ms_to_ktime(1), HRTIMER_MODE_REL); 1306 1306 1307 1307 done: 1308 1308 spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); ··· 1323 1323 rc = usb_hcd_check_unlink_urb(hcd, urb, status); 1324 1324 if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING && 1325 1325 !list_empty(&dum_hcd->urbp_list)) 1326 - mod_timer(&dum_hcd->timer, jiffies); 1326 + hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL); 1327 1327 1328 1328 spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); 1329 1329 return rc; ··· 1777 1777 * drivers except that the callbacks are invoked from soft interrupt 1778 1778 * context. 1779 1779 */ 1780 - static void dummy_timer(struct timer_list *t) 1780 + static enum hrtimer_restart dummy_timer(struct hrtimer *t) 1781 1781 { 1782 1782 struct dummy_hcd *dum_hcd = from_timer(dum_hcd, t, timer); 1783 1783 struct dummy *dum = dum_hcd->dum; ··· 1808 1808 break; 1809 1809 } 1810 1810 1811 - /* FIXME if HZ != 1000 this will probably misbehave ... */ 1812 - 1813 1811 /* look at each urb queued by the host side driver */ 1814 1812 spin_lock_irqsave(&dum->lock, flags); 1815 1813 ··· 1815 1817 dev_err(dummy_dev(dum_hcd), 1816 1818 "timer fired with no URBs pending?\n"); 1817 1819 spin_unlock_irqrestore(&dum->lock, flags); 1818 - return; 1820 + return HRTIMER_NORESTART; 1819 1821 } 1820 1822 dum_hcd->next_frame_urbp = NULL; 1821 1823 ··· 1993 1995 dum_hcd->udev = NULL; 1994 1996 } else if (dum_hcd->rh_state == DUMMY_RH_RUNNING) { 1995 1997 /* want a 1 msec delay here */ 1996 - mod_timer(&dum_hcd->timer, jiffies + msecs_to_jiffies(1)); 1998 + hrtimer_start(&dum_hcd->timer, ms_to_ktime(1), HRTIMER_MODE_REL); 1997 1999 } 1998 2000 1999 2001 spin_unlock_irqrestore(&dum->lock, flags); 2002 + 2003 + return HRTIMER_NORESTART; 2000 2004 } 2001 2005 2002 2006 /*-------------------------------------------------------------------------*/ ··· 2387 2387 dum_hcd->rh_state = DUMMY_RH_RUNNING; 2388 2388 set_link_state(dum_hcd); 2389 2389 if (!list_empty(&dum_hcd->urbp_list)) 2390 - mod_timer(&dum_hcd->timer, jiffies); 2390 + hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL); 2391 2391 hcd->state = HC_STATE_RUNNING; 2392 2392 } 2393 2393 spin_unlock_irq(&dum_hcd->dum->lock); ··· 2465 2465 2466 2466 static int dummy_start_ss(struct dummy_hcd *dum_hcd) 2467 2467 { 2468 - timer_setup(&dum_hcd->timer, dummy_timer, 0); 2468 + hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 2469 + dum_hcd->timer.function = dummy_timer; 2469 2470 dum_hcd->rh_state = DUMMY_RH_RUNNING; 2470 2471 dum_hcd->stream_en_ep = 0; 2471 2472 INIT_LIST_HEAD(&dum_hcd->urbp_list); ··· 2495 2494 return dummy_start_ss(dum_hcd); 2496 2495 2497 2496 spin_lock_init(&dum_hcd->dum->lock); 2498 - timer_setup(&dum_hcd->timer, dummy_timer, 0); 2497 + hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 2498 + dum_hcd->timer.function = dummy_timer; 2499 2499 dum_hcd->rh_state = DUMMY_RH_RUNNING; 2500 2500 2501 2501 INIT_LIST_HEAD(&dum_hcd->urbp_list); ··· 2515 2513 2516 2514 static void dummy_stop(struct usb_hcd *hcd) 2517 2515 { 2518 - device_remove_file(dummy_dev(hcd_to_dummy_hcd(hcd)), &dev_attr_urbs); 2519 - dev_info(dummy_dev(hcd_to_dummy_hcd(hcd)), "stopped\n"); 2516 + struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); 2517 + 2518 + hrtimer_cancel(&dum_hcd->timer); 2519 + device_remove_file(dummy_dev(dum_hcd), &dev_attr_urbs); 2520 + dev_info(dummy_dev(dum_hcd), "stopped\n"); 2520 2521 } 2521 2522 2522 2523 /*-------------------------------------------------------------------------*/