98 lines
3.1 KiB
Diff
98 lines
3.1 KiB
Diff
From: Thomas Gleixner <tglx@linutronix.de>
|
|
Date: Thu, 23 Nov 2017 16:39:16 +0100
|
|
Subject: [PATCH 35/36] usb/gadget/NCM: Replace tasklet with softirq hrtimer
|
|
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.14/older/patches-4.14.1-rt3.tar.xz
|
|
|
|
The tx_tasklet tasklet is used in invoke the hrtimer (task_timer) in
|
|
softirq context. This can be also achieved without the tasklet but
|
|
with HRTIMER_MODE_SOFT as hrtimer mode.
|
|
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
|
|
Cc: Felipe Balbi <balbi@kernel.org>
|
|
Cc: linux-usb@vger.kernel.org
|
|
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
---
|
|
drivers/usb/gadget/function/f_ncm.c | 30 +++++++-----------------------
|
|
1 file changed, 7 insertions(+), 23 deletions(-)
|
|
|
|
--- a/drivers/usb/gadget/function/f_ncm.c
|
|
+++ b/drivers/usb/gadget/function/f_ncm.c
|
|
@@ -77,9 +77,7 @@ struct f_ncm {
|
|
struct sk_buff *skb_tx_ndp;
|
|
u16 ndp_dgram_count;
|
|
bool timer_force_tx;
|
|
- struct tasklet_struct tx_tasklet;
|
|
struct hrtimer task_timer;
|
|
-
|
|
bool timer_stopping;
|
|
};
|
|
|
|
@@ -1108,7 +1106,7 @@ static struct sk_buff *ncm_wrap_ntb(stru
|
|
|
|
/* Delay the timer. */
|
|
hrtimer_start(&ncm->task_timer, TX_TIMEOUT_NSECS,
|
|
- HRTIMER_MODE_REL);
|
|
+ HRTIMER_MODE_REL_SOFT);
|
|
|
|
/* Add the datagram position entries */
|
|
ntb_ndp = skb_put_zero(ncm->skb_tx_ndp, dgram_idx_len);
|
|
@@ -1152,17 +1150,15 @@ static struct sk_buff *ncm_wrap_ntb(stru
|
|
}
|
|
|
|
/*
|
|
- * This transmits the NTB if there are frames waiting.
|
|
+ * The transmit should only be run if no skb data has been sent
|
|
+ * for a certain duration.
|
|
*/
|
|
-static void ncm_tx_tasklet(unsigned long data)
|
|
+static enum hrtimer_restart ncm_tx_timeout(struct hrtimer *data)
|
|
{
|
|
- struct f_ncm *ncm = (void *)data;
|
|
-
|
|
- if (ncm->timer_stopping)
|
|
- return;
|
|
+ struct f_ncm *ncm = container_of(data, struct f_ncm, task_timer);
|
|
|
|
/* Only send if data is available. */
|
|
- if (ncm->skb_tx_data) {
|
|
+ if (!ncm->timer_stopping && ncm->skb_tx_data) {
|
|
ncm->timer_force_tx = true;
|
|
|
|
/* XXX This allowance of a NULL skb argument to ndo_start_xmit
|
|
@@ -1175,16 +1171,6 @@ static void ncm_tx_tasklet(unsigned long
|
|
|
|
ncm->timer_force_tx = false;
|
|
}
|
|
-}
|
|
-
|
|
-/*
|
|
- * The transmit should only be run if no skb data has been sent
|
|
- * for a certain duration.
|
|
- */
|
|
-static enum hrtimer_restart ncm_tx_timeout(struct hrtimer *data)
|
|
-{
|
|
- struct f_ncm *ncm = container_of(data, struct f_ncm, task_timer);
|
|
- tasklet_schedule(&ncm->tx_tasklet);
|
|
return HRTIMER_NORESTART;
|
|
}
|
|
|
|
@@ -1517,8 +1503,7 @@ static int ncm_bind(struct usb_configura
|
|
ncm->port.open = ncm_open;
|
|
ncm->port.close = ncm_close;
|
|
|
|
- tasklet_init(&ncm->tx_tasklet, ncm_tx_tasklet, (unsigned long) ncm);
|
|
- hrtimer_init(&ncm->task_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
|
+ hrtimer_init(&ncm->task_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT);
|
|
ncm->task_timer.function = ncm_tx_timeout;
|
|
|
|
DBG(cdev, "CDC Network: %s speed IN/%s OUT/%s NOTIFY/%s\n",
|
|
@@ -1627,7 +1612,6 @@ static void ncm_unbind(struct usb_config
|
|
DBG(c->cdev, "ncm unbind\n");
|
|
|
|
hrtimer_cancel(&ncm->task_timer);
|
|
- tasklet_kill(&ncm->tx_tasklet);
|
|
|
|
ncm_string_defs[0].id = 0;
|
|
usb_free_all_descriptors(f);
|