[PATCH] 2.6.3 pcnet32.c transmit hang fix
The transmit routine will stop interrupting and hang, causing the tx_timeout routine to attempt to restart the device when the 32-bit cur_tx counter wraps below dirty_tx. If the device had called netif_stop_queue it will never call netif_wake_queue in the interrupt routine (at least on an IA32 system) due to 32-bit wrap around arithmetic. On my IA32 system 'dirty_tx > lp->cur_tx - TX_RING_SIZE + 2' would always evaluate to false when dirty and cur_tx were less than 15, preventing netif_wake_queue to be called. By starting dirty_tx and cur_tx at 0xfffffff0 (to reduce test time) I found that once cur_tx wrapped to zero, that transmitted buffers would never be unmapped or freed because 'while (dirty_tx < lp->cur_tx) {' was not true. cur_tx would keep incrementing (in start_xmit) but dirty_tx would not (in pcnet32_interrupt), thus leaking skb's and pci map entries. On PPC machines, the system would quickly run out of pci maps. Fix tested on PPC and IA32.
Showing
Please register or sign in to comment