diff options
Diffstat (limited to 'drivers/net/ethernet/intel/i40e/i40e_main.c')
| -rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_main.c | 29 | 
1 files changed, 19 insertions, 10 deletions
| diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 5d807c8004f8..56ecd6c3f236 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -439,11 +439,15 @@ static void i40e_get_netdev_stats_struct(struct net_device *netdev,  		i40e_get_netdev_stats_struct_tx(ring, stats);  		if (i40e_enabled_xdp_vsi(vsi)) { -			ring++; +			ring = READ_ONCE(vsi->xdp_rings[i]); +			if (!ring) +				continue;  			i40e_get_netdev_stats_struct_tx(ring, stats);  		} -		ring++; +		ring = READ_ONCE(vsi->rx_rings[i]); +		if (!ring) +			continue;  		do {  			start   = u64_stats_fetch_begin_irq(&ring->syncp);  			packets = ring->stats.packets; @@ -787,6 +791,8 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)  	for (q = 0; q < vsi->num_queue_pairs; q++) {  		/* locate Tx ring */  		p = READ_ONCE(vsi->tx_rings[q]); +		if (!p) +			continue;  		do {  			start = u64_stats_fetch_begin_irq(&p->syncp); @@ -800,8 +806,11 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)  		tx_linearize += p->tx_stats.tx_linearize;  		tx_force_wb += p->tx_stats.tx_force_wb; -		/* Rx queue is part of the same block as Tx queue */ -		p = &p[1]; +		/* locate Rx ring */ +		p = READ_ONCE(vsi->rx_rings[q]); +		if (!p) +			continue; +  		do {  			start = u64_stats_fetch_begin_irq(&p->syncp);  			packets = p->stats.packets; @@ -10824,10 +10833,10 @@ static void i40e_vsi_clear_rings(struct i40e_vsi *vsi)  	if (vsi->tx_rings && vsi->tx_rings[0]) {  		for (i = 0; i < vsi->alloc_queue_pairs; i++) {  			kfree_rcu(vsi->tx_rings[i], rcu); -			vsi->tx_rings[i] = NULL; -			vsi->rx_rings[i] = NULL; +			WRITE_ONCE(vsi->tx_rings[i], NULL); +			WRITE_ONCE(vsi->rx_rings[i], NULL);  			if (vsi->xdp_rings) -				vsi->xdp_rings[i] = NULL; +				WRITE_ONCE(vsi->xdp_rings[i], NULL);  		}  	}  } @@ -10861,7 +10870,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)  		if (vsi->back->hw_features & I40E_HW_WB_ON_ITR_CAPABLE)  			ring->flags = I40E_TXR_FLAGS_WB_ON_ITR;  		ring->itr_setting = pf->tx_itr_default; -		vsi->tx_rings[i] = ring++; +		WRITE_ONCE(vsi->tx_rings[i], ring++);  		if (!i40e_enabled_xdp_vsi(vsi))  			goto setup_rx; @@ -10879,7 +10888,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)  			ring->flags = I40E_TXR_FLAGS_WB_ON_ITR;  		set_ring_xdp(ring);  		ring->itr_setting = pf->tx_itr_default; -		vsi->xdp_rings[i] = ring++; +		WRITE_ONCE(vsi->xdp_rings[i], ring++);  setup_rx:  		ring->queue_index = i; @@ -10892,7 +10901,7 @@ setup_rx:  		ring->size = 0;  		ring->dcb_tc = 0;  		ring->itr_setting = pf->rx_itr_default; -		vsi->rx_rings[i] = ring; +		WRITE_ONCE(vsi->rx_rings[i], ring);  	}  	return 0; |