mirror of
https://github.com/torvalds/linux.git
synced 2024-12-14 07:02:23 +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;
|
ring->queue_index = txr_idx;
|
||||||
|
|
||||||
/* assign ring to adapter */
|
/* assign ring to adapter */
|
||||||
adapter->tx_ring[txr_idx] = ring;
|
WRITE_ONCE(adapter->tx_ring[txr_idx], ring);
|
||||||
|
|
||||||
/* update count and index */
|
/* update count and index */
|
||||||
txr_count--;
|
txr_count--;
|
||||||
@ -948,7 +948,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
|
|||||||
set_ring_xdp(ring);
|
set_ring_xdp(ring);
|
||||||
|
|
||||||
/* assign ring to adapter */
|
/* assign ring to adapter */
|
||||||
adapter->xdp_ring[xdp_idx] = ring;
|
WRITE_ONCE(adapter->xdp_ring[xdp_idx], ring);
|
||||||
|
|
||||||
/* update count and index */
|
/* update count and index */
|
||||||
xdp_count--;
|
xdp_count--;
|
||||||
@ -991,7 +991,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
|
|||||||
ring->queue_index = rxr_idx;
|
ring->queue_index = rxr_idx;
|
||||||
|
|
||||||
/* assign ring to adapter */
|
/* assign ring to adapter */
|
||||||
adapter->rx_ring[rxr_idx] = ring;
|
WRITE_ONCE(adapter->rx_ring[rxr_idx], ring);
|
||||||
|
|
||||||
/* update count and index */
|
/* update count and index */
|
||||||
rxr_count--;
|
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) {
|
ixgbe_for_each_ring(ring, q_vector->tx) {
|
||||||
if (ring_is_xdp(ring))
|
if (ring_is_xdp(ring))
|
||||||
adapter->xdp_ring[ring->queue_index] = NULL;
|
WRITE_ONCE(adapter->xdp_ring[ring->queue_index], NULL);
|
||||||
else
|
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)
|
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;
|
adapter->q_vector[v_idx] = NULL;
|
||||||
napi_hash_del(&q_vector->napi);
|
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++) {
|
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;
|
non_eop_descs += rx_ring->rx_stats.non_eop_descs;
|
||||||
alloc_rx_page += rx_ring->rx_stats.alloc_rx_page;
|
alloc_rx_page += rx_ring->rx_stats.alloc_rx_page;
|
||||||
alloc_rx_page_failed += rx_ring->rx_stats.alloc_rx_page_failed;
|
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;
|
packets = 0;
|
||||||
/* gather some stats to the adapter struct that are per queue */
|
/* gather some stats to the adapter struct that are per queue */
|
||||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
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;
|
restart_queue += tx_ring->tx_stats.restart_queue;
|
||||||
tx_busy += tx_ring->tx_stats.tx_busy;
|
tx_busy += tx_ring->tx_stats.tx_busy;
|
||||||
bytes += tx_ring->stats.bytes;
|
bytes += tx_ring->stats.bytes;
|
||||||
packets += tx_ring->stats.packets;
|
packets += tx_ring->stats.packets;
|
||||||
}
|
}
|
||||||
for (i = 0; i < adapter->num_xdp_queues; i++) {
|
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;
|
restart_queue += xdp_ring->tx_stats.restart_queue;
|
||||||
tx_busy += xdp_ring->tx_stats.tx_busy;
|
tx_busy += xdp_ring->tx_stats.tx_busy;
|
||||||
bytes += xdp_ring->stats.bytes;
|
bytes += xdp_ring->stats.bytes;
|
||||||
|
Loading…
Reference in New Issue
Block a user