igb: Added rcu_lock to avoid race
authorAkeem G Abodunrin <akeem.g.abodunrin@intel.com>
Thu, 27 Jun 2013 09:10:23 +0000 (09:10 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Thu, 22 Aug 2013 09:25:29 +0000 (02:25 -0700)
This patch adds rcu_lock to avoid possible race condition with igb_update_stats
function accessing the rings in free_ q_vector.

CC: Eric Dumazet <edumazet@google.com>
Signed-off-by: Akeem G Abodunrin <akeem.g.abodunrin@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/igb/igb_main.c

index 090ee56a9fc9e1b6f4295880d39b4662271bdf07..8e7c1b83da19c821cf7dd186a8f6239ac4ab06f5 100644 (file)
@@ -1013,7 +1013,7 @@ static void igb_free_q_vector(struct igb_adapter *adapter, int v_idx)
        adapter->q_vector[v_idx] = NULL;
        netif_napi_del(&q_vector->napi);
 
-       /* ixgbe_get_stats64() might access the rings on this vector,
+       /* igb_get_stats64() might access the rings on this vector,
         * we must wait a grace period before freeing it.
         */
        kfree_rcu(q_vector, rcu);
@@ -4859,6 +4859,8 @@ void igb_update_stats(struct igb_adapter *adapter,
 
        bytes = 0;
        packets = 0;
+
+       rcu_read_lock();
        for (i = 0; i < adapter->num_rx_queues; i++) {
                u32 rqdpc = rd32(E1000_RQDPC(i));
                struct igb_ring *ring = adapter->rx_ring[i];
@@ -4894,6 +4896,7 @@ void igb_update_stats(struct igb_adapter *adapter,
        }
        net_stats->tx_bytes = bytes;
        net_stats->tx_packets = packets;
+       rcu_read_unlock();
 
        /* read stats registers */
        adapter->stats.crcerrs += rd32(E1000_CRCERRS);