USB CDC NCM: tx_fixup() race condition fix
- tx_fixup() can be called from either timer callback or from xmit() in usbnet, so spinlock is added to avoid concurrency-related problem. - minor correction due to checkpatch warning for some line over 80 chars after previous patch was applied. Signed-off-by: Alexey Orishko <alexey.orishko@stericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1956cc52e7
commit
f742aa8acb
|
@ -54,7 +54,7 @@
|
|||
#include <linux/usb/usbnet.h>
|
||||
#include <linux/usb/cdc.h>
|
||||
|
||||
#define DRIVER_VERSION "30-Nov-2010"
|
||||
#define DRIVER_VERSION "17-Jan-2011"
|
||||
|
||||
/* CDC NCM subclass 3.2.1 */
|
||||
#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10
|
||||
|
@ -868,15 +868,19 @@ static void cdc_ncm_tx_timeout(unsigned long arg)
|
|||
if (ctx->tx_timer_pending != 0) {
|
||||
ctx->tx_timer_pending--;
|
||||
restart = 1;
|
||||
} else
|
||||
} else {
|
||||
restart = 0;
|
||||
}
|
||||
|
||||
spin_unlock(&ctx->mtx);
|
||||
|
||||
if (restart)
|
||||
if (restart) {
|
||||
spin_lock(&ctx->mtx);
|
||||
cdc_ncm_tx_timeout_start(ctx);
|
||||
else if (ctx->netdev != NULL)
|
||||
spin_unlock(&ctx->mtx);
|
||||
} else if (ctx->netdev != NULL) {
|
||||
usbnet_start_xmit(NULL, ctx->netdev);
|
||||
}
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
|
@ -900,7 +904,6 @@ cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
|
|||
skb_out = cdc_ncm_fill_tx_frame(ctx, skb);
|
||||
if (ctx->tx_curr_skb != NULL)
|
||||
need_timer = 1;
|
||||
spin_unlock(&ctx->mtx);
|
||||
|
||||
/* Start timer, if there is a remaining skb */
|
||||
if (need_timer)
|
||||
|
@ -908,6 +911,8 @@ cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
|
|||
|
||||
if (skb_out)
|
||||
dev->net->stats.tx_packets += ctx->tx_curr_frame_num;
|
||||
|
||||
spin_unlock(&ctx->mtx);
|
||||
return skb_out;
|
||||
|
||||
error:
|
||||
|
@ -1020,8 +1025,8 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
|
|||
if (((offset + temp) > actlen) ||
|
||||
(temp > CDC_NCM_MAX_DATAGRAM_SIZE) || (temp < ETH_HLEN)) {
|
||||
pr_debug("invalid frame detected (ignored)"
|
||||
"offset[%u]=%u, length=%u, skb=%p\n",
|
||||
x, offset, temp, skb_in);
|
||||
"offset[%u]=%u, length=%u, skb=%p\n",
|
||||
x, offset, temp, skb_in);
|
||||
if (!x)
|
||||
goto error;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue