From 4da79504b2b41410dd56e9268c9ad403aa65e89c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 19 Aug 2010 08:52:44 +0000 Subject: qlge: pull NULL check ahead of dereference There was a dereference before NULL check issue introduced in 1e213303d "qlge: Add tx multiqueue support." I've pulled the NULL check of "net_rsp" forward a couple lines to avoid that. Also Ron Mercer says that the early exit should be above the index write. ql_write_cq_idx(rx_ring); Signed-off-by: Dan Carpenter Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net/qlge/qlge_main.c') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 8d63f69b27d9..c9f9754f0784 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -2222,10 +2222,11 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) ql_update_cq(rx_ring); prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); } + if (!net_rsp) + return 0; ql_write_cq_idx(rx_ring); tx_ring = &qdev->tx_ring[net_rsp->txq_idx]; - if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id) && - net_rsp != NULL) { + if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id)) { if (atomic_read(&tx_ring->queue_stopped) && (atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4))) /* -- cgit v1.2.3 From c5dadddb8c9d310bc263f671f19fe3ba90b329fe Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Tue, 24 Aug 2010 12:50:40 +0000 Subject: qlge: Fix a deadlock when the interface is going down Currently qlge can deadlock when the interface is going down, and the mpi_port_cfg_work() is executing on another processor. It happens because unregister_netdev() holds the rtnl lock, and the mpi_port_cfg_work() also request this lock. Since unregiter_netdev() may wait mpi_port_cfg_work(), who also request the holding lock, it can cause an deadlock, displaying the following error: "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. rmmod D 00000080c6c1d190 0 3993 2081 0x00008080 Call Trace: [c000000975f56ee0] [c0000000000152a0] .__switch_to+0x100/0x1d0 [c000000975f56f70] [c0000000005781b4] .schedule+0x3a4/0x8c0 [c000000975f570c0] [c000000000578e8c] .schedule_timeout+0x24c/0x350 [c000000975f571e0] [c000000000578a88] .wait_for_common+0x198/0x210 [c000000975f572c0] [c0000000000abbb4] .__cancel_work_timer+0x2c4/0x2e0 [c000000975f57400] [d0000000078e7a20] .ql_adapter_down+0x80/0x260 [qlge] [c000000975f574b0] [d0000000078e7d80] .qlge_close+0x70/0x130 [qlge] [c000000975f57540] [c000000000497ef8] .__dev_close+0x98/0xf0 [c000000975f575d0] [c000000000497f74] .dev_close+0x24/0x60 [c000000975f57650] [c000000000498080] .rollback_registered_many+0xd0/0x2b0 [c000000975f576f0] [c000000000498338] .rollback_registered+0x38/0x50 [c000000975f57780] [c0000000004983d8] .unregister_netdevice_queue+0x88/0xe0 [c000000975f57810] [c000000000498574] .unregister_netdev+0x24/0x40 [c000000975f57890] [d0000000078f6f38] .qlge_remove+0x3c/0x78 [qlge] [c000000975f57920] [c0000000002d9298] .pci_device_remove+0x48/0x90 [c000000975f579a0] [c000000000372850] .__device_release_driver+0xa0/0x130 [c000000975f57a30] [c000000000372a08] .driver_detach+0x128/0x150 [c000000975f57ad0] [c000000000371134] .bus_remove_driver+0xc4/0x1a0 [c000000975f57b70] [c00000000037357c] .driver_unregister+0x8c/0xd0 [c000000975f57c00] [c0000000002d968c] .pci_unregister_driver+0x5c/0x110 [c000000975f57ca0] [d0000000078f6ee4] .qlge_exit+0x1c/0x34 [qlge] Signed-off-by: Breno Leitao Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers/net/qlge/qlge_main.c') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index c9f9754f0784..5a245211fc53 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -3889,11 +3889,8 @@ int ql_wol(struct ql_adapter *qdev) return status; } -static int ql_adapter_down(struct ql_adapter *qdev) +static void ql_cancel_all_work_sync(struct ql_adapter *qdev) { - int i, status = 0; - - ql_link_off(qdev); /* Don't kill the reset worker thread if we * are in the process of recovery. @@ -3905,6 +3902,15 @@ static int ql_adapter_down(struct ql_adapter *qdev) cancel_delayed_work_sync(&qdev->mpi_idc_work); cancel_delayed_work_sync(&qdev->mpi_core_to_log); cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); +} + +static int ql_adapter_down(struct ql_adapter *qdev) +{ + int i, status = 0; + + ql_link_off(qdev); + + ql_cancel_all_work_sync(qdev); for (i = 0; i < qdev->rss_ring_count; i++) napi_disable(&qdev->rx_ring[i].napi); @@ -4727,6 +4733,7 @@ static void __devexit qlge_remove(struct pci_dev *pdev) struct net_device *ndev = pci_get_drvdata(pdev); struct ql_adapter *qdev = netdev_priv(ndev); del_timer_sync(&qdev->timer); + ql_cancel_all_work_sync(qdev); unregister_netdev(ndev); ql_release_all(pdev); pci_disable_device(pdev); @@ -4746,13 +4753,7 @@ static void ql_eeh_close(struct net_device *ndev) /* Disabling the timer */ del_timer_sync(&qdev->timer); - if (test_bit(QL_ADAPTER_UP, &qdev->flags)) - cancel_delayed_work_sync(&qdev->asic_reset_work); - cancel_delayed_work_sync(&qdev->mpi_reset_work); - cancel_delayed_work_sync(&qdev->mpi_work); - cancel_delayed_work_sync(&qdev->mpi_idc_work); - cancel_delayed_work_sync(&qdev->mpi_core_to_log); - cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); + ql_cancel_all_work_sync(qdev); for (i = 0; i < qdev->rss_ring_count; i++) netif_napi_del(&qdev->rx_ring[i].napi); -- cgit v1.2.3 From bc8acf2c8c3e43fcc192762a9f964b3e9a17748b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 2 Sep 2010 13:07:41 -0700 Subject: drivers/net: avoid some skb->ip_summed initializations fresh skbs have ip_summed set to CHECKSUM_NONE (0) We can avoid setting again skb->ip_summed to CHECKSUM_NONE in drivers. Introduce skb_checksum_none_assert() helper so that we keep this assertion documented in driver sources. Change most occurrences of : skb->ip_summed = CHECKSUM_NONE; by : skb_checksum_none_assert(skb); Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net/qlge/qlge_main.c') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 5a245211fc53..e2d0e108b9aa 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -1566,7 +1566,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, rx_ring->rx_packets++; rx_ring->rx_bytes += skb->len; skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (qdev->rx_csum && !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { @@ -1676,7 +1676,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev, rx_ring->rx_packets++; rx_ring->rx_bytes += skb->len; skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* If rx checksum is on, and there are no * csum or frame errors. @@ -1996,7 +1996,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev, } skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* If rx checksum is on, and there are no * csum or frame errors. -- cgit v1.2.3 From eab6d18d20fc5b5ba04a7e7fcd6f357197870e51 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 20 Oct 2010 13:56:03 +0000 Subject: vlan: Don't check for vlan group before vlan_tx_tag_present. Many (but not all) drivers check to see whether there is a vlan group configured before using a tag stored in the skb. There's not much point in this check since it just throws away data that should only be present in the expected circumstances. However, it will soon be legal and expected to get a vlan tag when no vlan group is configured, so remove this check from all drivers to avoid dropping the tags. Signed-off-by: Jesse Gross Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/qlge/qlge_main.c') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 4ffebe83d883..ba0053d8515e 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -2572,7 +2572,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev) mac_iocb_ptr->frame_len = cpu_to_le16((u16) skb->len); - if (qdev->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev, "Adding a vlan tag %d.\n", vlan_tx_tag_get(skb)); mac_iocb_ptr->flags3 |= OB_MAC_IOCB_V; -- cgit v1.2.3