mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-06 19:07:52 +00:00
ixgbe: protect ring accesses with READ- and WRITE_ONCE
[ Upstream commit f140ad9fe2
]
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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
ea608f709f
commit
6e2af3fbac
2 changed files with 17 additions and 9 deletions
|
@ -917,7 +917,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--;
|
||||
|
@ -944,7 +944,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);
|
||||
|
|
|
@ -6842,7 +6842,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_failed += rx_ring->rx_stats.alloc_rx_page_failed;
|
||||
alloc_rx_buff_failed += rx_ring->rx_stats.alloc_rx_buff_failed;
|
||||
|
@ -6861,15 +6864,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 a new issue