updated patch with throttling
Roman Kagan
rkagan at mail.ru
Fri Mar 25 09:38:06 EST 2005
On Fri, Mar 25, 2005 at 04:39:00PM +0300, Roman Kagan wrote:
> Then I would add a limit counter. If we get this number of consecutive
> usb errors (either on submission or on completion) then we just barf and
> tell the user to wipe it out. I guess it shouldn't influence overall
> design too much.
How about this? (This is an incremental patch, I'll send a complete one
against current CVS in another mail).
Roman.
diff -u usbatm.h usbatm.h
--- usbatm.h 25 Mar 2005 11:02:17 -0000
+++ usbatm.h 25 Mar 2005 14:34:12 -0000
@@ -161,6 +161,8 @@
struct sk_buff_head sndqueue;
struct sk_buff *current_skb; /* being emptied */
+
+ atomic_t num_allowed_errors;
};
#endif /* _USBATM_H_ */
diff -u usbatm.c usbatm.c
--- usbatm.c 25 Mar 2005 11:02:18 -0000
+++ usbatm.c 25 Mar 2005 14:34:12 -0000
@@ -108,6 +108,7 @@
#define UDSL_NUM_CELLS(x) (((x) + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD)
#define THROTTLE_MSECS 5 /* delay to recover processing after urb submission fails */
+#define USBATM_MAX_ERRORS 1024 /* number of consecutive usb errors to tolerate */
/* receive */
@@ -223,6 +224,23 @@
return init;
}
+/* error limit */
+static void usbatm_check_usb_errcode(struct usbatm_data* instance, int errcode)
+{
+ if (likely(!errcode)) {
+ /* reset allowed errors counter */
+ atomic_set(&instance->num_allowed_errors, USBATM_MAX_ERRORS);
+ return;
+ }
+
+ if (atomic_dec_and_test(&instance->num_allowed_errors)) {
+ dev_err(&instance->usb_intf->dev,
+ "too many consecutive usb errors, aborting.\n");
+ tasklet_disable(&instance->rx_tasklet);
+ tasklet_disable(&instance->tx_tasklet);
+ }
+}
+
/* buffer management */
static inline struct usbatm_transceiver *usbatm_pop_transceiver(struct list_head *trx_list,
spinlock_t *lock)
@@ -265,6 +283,9 @@
if (ret)
dbg("usbatm_submit: trx 0x%p (#%d) urb 0x%p submission failed (%d)!",
trx, trx - instance->transceivers, trx->urb, ret);
+
+ usbatm_check_usb_errcode(instance, ret);
+
return ret;
}
@@ -278,6 +299,8 @@
rx->filled_cells = urb->status ? 0 : urb->actual_length / (ATM_CELL_SIZE + instance->rx_padding);
+ usbatm_check_usb_errcode(instance, urb->status);
+
vdbg("usbatm_rx_complete: urb 0x%p, status %d, actual_length %d, filled_cells %u, rx 0x%p",
urb, urb->status, urb->actual_length, rx->filled_cells, rx);
@@ -297,6 +320,8 @@
struct usbatm_data *instance = tx->instance;
unsigned long flags;
+ usbatm_check_usb_errcode(instance, urb->status);
+
vdbg("usbatm_tx_complete: urb 0x%p, status %d, tx 0x%p",
urb, urb->status, tx);
@@ -1150,6 +1175,8 @@
instance->tx_delay.data = (unsigned long) &instance->tx_tasklet;
init_timer(&instance->tx_delay);
+ atomic_set(&instance->num_allowed_errors, USBATM_MAX_ERRORS);
+
skb_queue_head_init(&instance->sndqueue);
instance->transceivers = kmalloc(sizeof(*instance->transceivers) * (num_rcv_urbs + num_snd_urbs),
More information about the Usbatm
mailing list