Commit 78aee79d authored by Santiago Leon's avatar Santiago Leon Committed by Linus Torvalds

[PATCH] fix buffer starvation race in ibmveth

There's a chance that the receive buffers are being consumed at the same
rate as they are being replenished in ibmveth_replenish_task()... 
Meanwhile, the calls to schedule_replenishing() from ibmveth_poll() won't
schedule another replenishing cycle (because the not_replenishing flag is
zero), starving the buffers and making the adapter unable to receive
packets unless the module is reloaded...  Here's a small patch that will
fix it by scheduling another replenishing task after toggling the
not_replenishing flag.
Signed-Off-By: default avatarSantiago Leon <santil@us.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 4d92f902
...@@ -96,6 +96,7 @@ static void ibmveth_proc_unregister_driver(void); ...@@ -96,6 +96,7 @@ static void ibmveth_proc_unregister_driver(void);
static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter); static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter);
static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter); static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter);
static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter*);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
#define IBMVETH_PROC_DIR "ibmveth" #define IBMVETH_PROC_DIR "ibmveth"
...@@ -104,7 +105,7 @@ static struct proc_dir_entry *ibmveth_proc_dir; ...@@ -104,7 +105,7 @@ static struct proc_dir_entry *ibmveth_proc_dir;
static const char ibmveth_driver_name[] = "ibmveth"; static const char ibmveth_driver_name[] = "ibmveth";
static const char ibmveth_driver_string[] = "IBM i/pSeries Virtual Ethernet Driver"; static const char ibmveth_driver_string[] = "IBM i/pSeries Virtual Ethernet Driver";
#define ibmveth_driver_version "1.02" #define ibmveth_driver_version "1.03"
MODULE_AUTHOR("Santiago Leon <santil@us.ibm.com>"); MODULE_AUTHOR("Santiago Leon <santil@us.ibm.com>");
MODULE_DESCRIPTION("IBM i/pSeries Virtual Ethernet Driver"); MODULE_DESCRIPTION("IBM i/pSeries Virtual Ethernet Driver");
...@@ -271,6 +272,8 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) ...@@ -271,6 +272,8 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter)
adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8); adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8);
atomic_inc(&adapter->not_replenishing); atomic_inc(&adapter->not_replenishing);
ibmveth_schedule_replenishing(adapter);
} }
/* kick the replenish tasklet if we need replenishing and it isn't already running */ /* kick the replenish tasklet if we need replenishing and it isn't already running */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment