aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_main.c
diff options
context:
space:
mode:
authorAmit Kumar Salecha <amit@qlogic.com>2009-08-13 03:03:00 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-13 19:33:03 -0400
commite424fa9d6a0add1a9b812b07e3607daaa5b9e53d (patch)
tree3c29efe8d877845647c32d60a9b20f3fa4950093 /drivers/net/netxen/netxen_nic_main.c
parent237057ad3fe5644fa471be474a160de2fc2e5870 (diff)
netxen: remove netxen workqueue
o Remove private workqueue in the driver, move all scheduled tasks to keventd workqueues. This makes ports (interfaces) of same / different NIC boards independent, in terms of their link watchdog and reset tasks. o Move quick checks for link status and temperature in timer callback, schedule watchdog task only if link status changed or temperature reached critical threshold. This also fixes deadlock when thermal panic occurs, watchdog work was flushing workqueue that it was sitting on. Signed-off-by: Amit Kumar Salecha <amit@qlogic.com> Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r--drivers/net/netxen/netxen_nic_main.c69
1 files changed, 41 insertions, 28 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 70c05c4c0cab..d24e1cb93a26 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -94,10 +94,6 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
94 94
95MODULE_DEVICE_TABLE(pci, netxen_pci_tbl); 95MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
96 96
97static struct workqueue_struct *netxen_workq;
98#define SCHEDULE_WORK(tp) queue_work(netxen_workq, tp)
99#define FLUSH_SCHEDULED_WORK() flush_workqueue(netxen_workq)
100
101static void netxen_watchdog(unsigned long); 97static void netxen_watchdog(unsigned long);
102 98
103static uint32_t crb_cmd_producer[4] = { 99static uint32_t crb_cmd_producer[4] = {
@@ -880,7 +876,6 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
880 spin_unlock(&adapter->tx_clean_lock); 876 spin_unlock(&adapter->tx_clean_lock);
881 877
882 del_timer_sync(&adapter->watchdog_timer); 878 del_timer_sync(&adapter->watchdog_timer);
883 FLUSH_SCHEDULED_WORK();
884} 879}
885 880
886 881
@@ -1177,6 +1172,9 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
1177 1172
1178 unregister_netdev(netdev); 1173 unregister_netdev(netdev);
1179 1174
1175 cancel_work_sync(&adapter->watchdog_task);
1176 cancel_work_sync(&adapter->tx_timeout_task);
1177
1180 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { 1178 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
1181 netxen_nic_detach(adapter); 1179 netxen_nic_detach(adapter);
1182 } 1180 }
@@ -1211,6 +1209,9 @@ netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
1211 if (netif_running(netdev)) 1209 if (netif_running(netdev))
1212 netxen_nic_down(adapter, netdev); 1210 netxen_nic_down(adapter, netdev);
1213 1211
1212 cancel_work_sync(&adapter->watchdog_task);
1213 cancel_work_sync(&adapter->tx_timeout_task);
1214
1214 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) 1215 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
1215 netxen_nic_detach(adapter); 1216 netxen_nic_detach(adapter);
1216 1217
@@ -1549,11 +1550,6 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter)
1549 "%s: Device temperature %d degrees C exceeds" 1550 "%s: Device temperature %d degrees C exceeds"
1550 " maximum allowed. Hardware has been shut down.\n", 1551 " maximum allowed. Hardware has been shut down.\n",
1551 netdev->name, temp_val); 1552 netdev->name, temp_val);
1552
1553 netif_device_detach(netdev);
1554 netxen_nic_down(adapter, netdev);
1555 netxen_nic_detach(adapter);
1556
1557 rv = 1; 1553 rv = 1;
1558 } else if (temp_state == NX_TEMP_WARN) { 1554 } else if (temp_state == NX_TEMP_WARN) {
1559 if (adapter->temp == NX_TEMP_NORMAL) { 1555 if (adapter->temp == NX_TEMP_NORMAL) {
@@ -1587,10 +1583,7 @@ void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup)
1587 netif_carrier_off(netdev); 1583 netif_carrier_off(netdev);
1588 netif_stop_queue(netdev); 1584 netif_stop_queue(netdev);
1589 } 1585 }
1590 1586 adapter->link_changed = !adapter->has_link_events;
1591 if (!adapter->has_link_events)
1592 netxen_nic_set_link_parameters(adapter);
1593
1594 } else if (!adapter->ahw.linkup && linkup) { 1587 } else if (!adapter->ahw.linkup && linkup) {
1595 printk(KERN_INFO "%s: %s NIC Link is up\n", 1588 printk(KERN_INFO "%s: %s NIC Link is up\n",
1596 netxen_nic_driver_name, netdev->name); 1589 netxen_nic_driver_name, netdev->name);
@@ -1599,9 +1592,7 @@ void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup)
1599 netif_carrier_on(netdev); 1592 netif_carrier_on(netdev);
1600 netif_wake_queue(netdev); 1593 netif_wake_queue(netdev);
1601 } 1594 }
1602 1595 adapter->link_changed = !adapter->has_link_events;
1603 if (!adapter->has_link_events)
1604 netxen_nic_set_link_parameters(adapter);
1605 } 1596 }
1606} 1597}
1607 1598
@@ -1628,11 +1619,36 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
1628 netxen_advert_link_change(adapter, linkup); 1619 netxen_advert_link_change(adapter, linkup);
1629} 1620}
1630 1621
1622static void netxen_nic_thermal_shutdown(struct netxen_adapter *adapter)
1623{
1624 struct net_device *netdev = adapter->netdev;
1625
1626 netif_device_detach(netdev);
1627 netxen_nic_down(adapter, netdev);
1628 netxen_nic_detach(adapter);
1629}
1630
1631static void netxen_watchdog(unsigned long v) 1631static void netxen_watchdog(unsigned long v)
1632{ 1632{
1633 struct netxen_adapter *adapter = (struct netxen_adapter *)v; 1633 struct netxen_adapter *adapter = (struct netxen_adapter *)v;
1634 1634
1635 SCHEDULE_WORK(&adapter->watchdog_task); 1635 if (netxen_nic_check_temp(adapter))
1636 goto do_sched;
1637
1638 if (!adapter->has_link_events) {
1639 netxen_nic_handle_phy_intr(adapter);
1640
1641 if (adapter->link_changed)
1642 goto do_sched;
1643 }
1644
1645 if (netif_running(adapter->netdev))
1646 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
1647
1648 return;
1649
1650do_sched:
1651 schedule_work(&adapter->watchdog_task);
1636} 1652}
1637 1653
1638void netxen_watchdog_task(struct work_struct *work) 1654void netxen_watchdog_task(struct work_struct *work)
@@ -1640,11 +1656,13 @@ void netxen_watchdog_task(struct work_struct *work)
1640 struct netxen_adapter *adapter = 1656 struct netxen_adapter *adapter =
1641 container_of(work, struct netxen_adapter, watchdog_task); 1657 container_of(work, struct netxen_adapter, watchdog_task);
1642 1658
1643 if (netxen_nic_check_temp(adapter)) 1659 if (adapter->temp == NX_TEMP_PANIC) {
1660 netxen_nic_thermal_shutdown(adapter);
1644 return; 1661 return;
1662 }
1645 1663
1646 if (!adapter->has_link_events) 1664 if (adapter->link_changed)
1647 netxen_nic_handle_phy_intr(adapter); 1665 netxen_nic_set_link_parameters(adapter);
1648 1666
1649 if (netif_running(adapter->netdev)) 1667 if (netif_running(adapter->netdev))
1650 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); 1668 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
@@ -1652,9 +1670,8 @@ void netxen_watchdog_task(struct work_struct *work)
1652 1670
1653static void netxen_tx_timeout(struct net_device *netdev) 1671static void netxen_tx_timeout(struct net_device *netdev)
1654{ 1672{
1655 struct netxen_adapter *adapter = (struct netxen_adapter *) 1673 struct netxen_adapter *adapter = netdev_priv(netdev);
1656 netdev_priv(netdev); 1674 schedule_work(&adapter->tx_timeout_task);
1657 SCHEDULE_WORK(&adapter->tx_timeout_task);
1658} 1675}
1659 1676
1660static void netxen_tx_timeout_task(struct work_struct *work) 1677static void netxen_tx_timeout_task(struct work_struct *work)
@@ -1811,9 +1828,6 @@ static int __init netxen_init_module(void)
1811{ 1828{
1812 printk(KERN_INFO "%s\n", netxen_nic_driver_string); 1829 printk(KERN_INFO "%s\n", netxen_nic_driver_string);
1813 1830
1814 if ((netxen_workq = create_singlethread_workqueue("netxen")) == NULL)
1815 return -ENOMEM;
1816
1817 return pci_register_driver(&netxen_driver); 1831 return pci_register_driver(&netxen_driver);
1818} 1832}
1819 1833
@@ -1822,7 +1836,6 @@ module_init(netxen_init_module);
1822static void __exit netxen_exit_module(void) 1836static void __exit netxen_exit_module(void)
1823{ 1837{
1824 pci_unregister_driver(&netxen_driver); 1838 pci_unregister_driver(&netxen_driver);
1825 destroy_workqueue(netxen_workq);
1826} 1839}
1827 1840
1828module_exit(netxen_exit_module); 1841module_exit(netxen_exit_module);