mirror of
https://github.com/torvalds/linux.git
synced 2024-12-13 22:53:20 +00:00
ixgbe: protect ring accesses with READ- and WRITE_ONCE
READ_ONCE should be used when reading rings prior to accessing the statistics pointer. Introduce this as well as the corresponding WRITE_ONCE usage when allocating and freeing the rings, to ensure protected access. Signed-off-by: Ciara Loftus <ciara.loftus@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
0ad6f6e767
commit
f140ad9fe2
@ -921,7 +921,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
|
||||
ring->queue_index = txr_idx;
|
||||
|
||||
/* assign ring to adapter */
|
||||
adapter->tx_ring[txr_idx] = ring;
|
||||
WRITE_ONCE(adapter->tx_ring[txr_idx], ring);
|
||||
|
||||
/* update count and index */
|
||||
txr_count--;
|
||||
@ -948,7 +948,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
|
||||
set_ring_xdp(ring);
|
||||
|
||||
/* assign ring to adapter */
|
||||
adapter->xdp_ring[xdp_idx] = ring;
|
||||
WRITE_ONCE(adapter->xdp_ring[xdp_idx], ring);
|
||||
|
||||
/* update count and index */
|
||||
xdp_count--;
|
||||
@ -991,7 +991,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
|
||||
ring->queue_index = rxr_idx;
|
||||
|
||||
/* assign ring to adapter */
|
||||
adapter->rx_ring[rxr_idx] = ring;
|
||||
WRITE_ONCE(adapter->rx_ring[rxr_idx], ring);
|
||||
|
||||
/* update count and index */
|
||||
rxr_count--;
|
||||
@ -1020,13 +1020,13 @@ static void ixgbe_free_q_vector(struct ixgbe_adapter *adapter, int v_idx)
|
||||
|
||||
ixgbe_for_each_ring(ring, q_vector->tx) {
|
||||
if (ring_is_xdp(ring))
|
||||
adapter->xdp_ring[ring->queue_index] = NULL;
|
||||
WRITE_ONCE(adapter->xdp_ring[ring->queue_index], NULL);
|
||||
else
|
||||
adapter->tx_ring[ring->queue_index] = NULL;
|
||||
WRITE_ONCE(adapter->tx_ring[ring->queue_index], NULL);
|
||||
}
|
||||
|
||||
ixgbe_for_each_ring(ring, q_vector->rx)
|
||||
adapter->rx_ring[ring->queue_index] = NULL;
|
||||
WRITE_ONCE(adapter->rx_ring[ring->queue_index], NULL);
|
||||
|
||||
adapter->q_vector[v_idx] = NULL;
|
||||
napi_hash_del(&q_vector->napi);
|
||||
|
@ -7051,7 +7051,10 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
|
||||
}
|
||||
|
||||
for (i = 0; i < adapter->num_rx_queues; i++) {
|
||||
struct ixgbe_ring *rx_ring = adapter->rx_ring[i];
|
||||
struct ixgbe_ring *rx_ring = READ_ONCE(adapter->rx_ring[i]);
|
||||
|
||||
if (!rx_ring)
|
||||
continue;
|
||||
non_eop_descs += rx_ring->rx_stats.non_eop_descs;
|
||||
alloc_rx_page += rx_ring->rx_stats.alloc_rx_page;
|
||||
alloc_rx_page_failed += rx_ring->rx_stats.alloc_rx_page_failed;
|
||||
@ -7072,15 +7075,20 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
|
||||
packets = 0;
|
||||
/* gather some stats to the adapter struct that are per queue */
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
struct ixgbe_ring *tx_ring = adapter->tx_ring[i];
|
||||
struct ixgbe_ring *tx_ring = READ_ONCE(adapter->tx_ring[i]);
|
||||
|
||||
if (!tx_ring)
|
||||
continue;
|
||||
restart_queue += tx_ring->tx_stats.restart_queue;
|
||||
tx_busy += tx_ring->tx_stats.tx_busy;
|
||||
bytes += tx_ring->stats.bytes;
|
||||
packets += tx_ring->stats.packets;
|
||||
}
|
||||
for (i = 0; i < adapter->num_xdp_queues; i++) {
|
||||
struct ixgbe_ring *xdp_ring = adapter->xdp_ring[i];
|
||||
struct ixgbe_ring *xdp_ring = READ_ONCE(adapter->xdp_ring[i]);
|
||||
|
||||
if (!xdp_ring)
|
||||
continue;
|
||||
restart_queue += xdp_ring->tx_stats.restart_queue;
|
||||
tx_busy += xdp_ring->tx_stats.tx_busy;
|
||||
bytes += xdp_ring->stats.bytes;
|
||||
|
Loading…
Reference in New Issue
Block a user