Message ID | 1223745433-26440-4-git-send-email-ron.mercer@qlogic.com |
---|---|
State | Deferred, archived |
Delegated to: | David Miller |
Headers | show |
Ron Mercer <ron.mercer@qlogic.com> : [...] > diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c > index c257546..1788e5c 100755 > --- a/drivers/net/qlge/qlge_main.c > +++ b/drivers/net/qlge/qlge_main.c [...] > @@ -3471,14 +3449,29 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p) > static void qlge_tx_timeout(struct net_device *ndev) > { > struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); > - queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); > + ql_queue_asic_error(qdev); > } > > static void ql_asic_reset_work(struct work_struct *work) > { > struct ql_adapter *qdev = > container_of(work, struct ql_adapter, asic_reset_work.work); > - ql_cycle_adapter(qdev); > + int status; > + > + status = ql_adapter_down(qdev); > + if (status) > + goto error; > + > + status = ql_adapter_up(qdev); > + if (status) > + goto error; > + return; > +error: > + QPRINTK(qdev, IFUP, ALERT, > + "Driver up/down cycle failed, closing device\n"); > + rtnl_lock(); > + dev_close(qdev->ndev); > + rtnl_unlock(); ql_asic_reset_work -> dev_close -> qlge_close -> ql_adapter_down -> cancel_delayed_work_sync(&qdev->asic_reset_work); -> __cancel_work_timer -> wait_on_work -> wait_on_cpu_work -> wait_for_completion Imho it will wait forever.
On Sat, Oct 11, 2008 at 11:30:00PM +0200, Francois Romieu wrote: > Ron Mercer <ron.mercer@qlogic.com> : > [...] > > diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c > > index c257546..1788e5c 100755 > > --- a/drivers/net/qlge/qlge_main.c > > +++ b/drivers/net/qlge/qlge_main.c > [...] > > @@ -3471,14 +3449,29 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p) > > static void qlge_tx_timeout(struct net_device *ndev) > > { > > struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); > > - queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); > > + ql_queue_asic_error(qdev); > > } > > > > static void ql_asic_reset_work(struct work_struct *work) > > { > > struct ql_adapter *qdev = > > container_of(work, struct ql_adapter, asic_reset_work.work); > > - ql_cycle_adapter(qdev); > > + int status; > > + > > + status = ql_adapter_down(qdev); > > + if (status) > > + goto error; > > + > > + status = ql_adapter_up(qdev); > > + if (status) > > + goto error; > > + return; > > +error: > > + QPRINTK(qdev, IFUP, ALERT, > > + "Driver up/down cycle failed, closing device\n"); > > + rtnl_lock(); > > + dev_close(qdev->ndev); > > + rtnl_unlock(); > > ql_asic_reset_work > -> dev_close > -> qlge_close > -> ql_adapter_down > -> cancel_delayed_work_sync(&qdev->asic_reset_work); > -> __cancel_work_timer > -> wait_on_work > -> wait_on_cpu_work > -> wait_for_completion > > Imho it will wait forever. Francois, Thanks for your input. I think you are correct and believe I've fixed this though I need to test the scenario you've pointed out. Cheers, Ron > > -- > Ueimor -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index c257546..1788e5c 100755 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -3141,28 +3141,6 @@ err_init: return err; } -static int ql_cycle_adapter(struct ql_adapter *qdev) -{ - int status; - - status = ql_adapter_down(qdev); - if (status) - goto error; - - status = ql_adapter_up(qdev); - if (status) - goto error; - - return status; -error: - QPRINTK(qdev, IFUP, ALERT, - "Driver up/down cycle failed, closing device\n"); - rtnl_lock(); - dev_close(qdev->ndev); - rtnl_unlock(); - return status; -} - static void ql_release_adapter_resources(struct ql_adapter *qdev) { ql_free_mem_resources(qdev); @@ -3471,14 +3449,29 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p) static void qlge_tx_timeout(struct net_device *ndev) { struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); - queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); + ql_queue_asic_error(qdev); } static void ql_asic_reset_work(struct work_struct *work) { struct ql_adapter *qdev = container_of(work, struct ql_adapter, asic_reset_work.work); - ql_cycle_adapter(qdev); + int status; + + status = ql_adapter_down(qdev); + if (status) + goto error; + + status = ql_adapter_up(qdev); + if (status) + goto error; + return; +error: + QPRINTK(qdev, IFUP, ALERT, + "Driver up/down cycle failed, closing device\n"); + rtnl_lock(); + dev_close(qdev->ndev); + rtnl_unlock(); } static void ql_get_board_info(struct ql_adapter *qdev)
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com> --- drivers/net/qlge/qlge_main.c | 41 +++++++++++++++++------------------------ 1 files changed, 17 insertions(+), 24 deletions(-)