Skip to content

Commit 90cfde4

Browse files
Gerhard Uttenthalermarckleinebudde
authored andcommitted
can: ems_usb: Fix possible tx overflow
This patch fixes the problem that more CAN messages could be sent to the interface as could be send on the CAN bus. This was more likely for slow baud rates. The sleeping _start_xmit was woken up in the _write_bulk_callback. Under heavy TX load this produced another bulk transfer without checking the free_slots variable and hence caused the overflow in the interface. Signed-off-by: Gerhard Uttenthaler <[email protected]> Cc: linux-stable <[email protected]> Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent d07c027 commit 90cfde4

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

drivers/net/can/usb/ems_usb.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ MODULE_LICENSE("GPL v2");
117117
*/
118118
#define EMS_USB_ARM7_CLOCK 8000000
119119

120+
#define CPC_TX_QUEUE_TRIGGER_LOW 25
121+
#define CPC_TX_QUEUE_TRIGGER_HIGH 35
122+
120123
/*
121124
* CAN-Message representation in a CPC_MSG. Message object type is
122125
* CPC_MSG_TYPE_CAN_FRAME or CPC_MSG_TYPE_RTR_FRAME or
@@ -278,6 +281,11 @@ static void ems_usb_read_interrupt_callback(struct urb *urb)
278281
switch (urb->status) {
279282
case 0:
280283
dev->free_slots = dev->intr_in_buffer[1];
284+
if(dev->free_slots > CPC_TX_QUEUE_TRIGGER_HIGH){
285+
if (netif_queue_stopped(netdev)){
286+
netif_wake_queue(netdev);
287+
}
288+
}
281289
break;
282290

283291
case -ECONNRESET: /* unlink */
@@ -526,8 +534,6 @@ static void ems_usb_write_bulk_callback(struct urb *urb)
526534
/* Release context */
527535
context->echo_index = MAX_TX_URBS;
528536

529-
if (netif_queue_stopped(netdev))
530-
netif_wake_queue(netdev);
531537
}
532538

533539
/*
@@ -587,7 +593,7 @@ static int ems_usb_start(struct ems_usb *dev)
587593
int err, i;
588594

589595
dev->intr_in_buffer[0] = 0;
590-
dev->free_slots = 15; /* initial size */
596+
dev->free_slots = 50; /* initial size */
591597

592598
for (i = 0; i < MAX_RX_URBS; i++) {
593599
struct urb *urb = NULL;
@@ -835,7 +841,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
835841

836842
/* Slow down tx path */
837843
if (atomic_read(&dev->active_tx_urbs) >= MAX_TX_URBS ||
838-
dev->free_slots < 5) {
844+
dev->free_slots < CPC_TX_QUEUE_TRIGGER_LOW) {
839845
netif_stop_queue(netdev);
840846
}
841847
}

0 commit comments

Comments
 (0)