Skip to content

Commit efe3d3c

Browse files
Alexander DuyckJeff Kirsher
authored andcommitted
ixgbe: convert rings from q_vector bit indexed array to linked list
This change converts the current bit array into a linked list so that the q_vectors can simply go through ring by ring and locate each ring needing to be cleaned. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
1 parent 30065e6 commit efe3d3c

File tree

2 files changed

+60
-139
lines changed

2 files changed

+60
-139
lines changed

drivers/net/ethernet/intel/ixgbe/ixgbe.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ enum ixbge_ring_state_t {
209209
#define clear_ring_rsc_enabled(ring) \
210210
clear_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state)
211211
struct ixgbe_ring {
212+
struct ixgbe_ring *next; /* pointer to next ring in q_vector */
212213
void *desc; /* descriptor ring memory */
213214
struct device *dev; /* device for DMA mapping */
214215
struct net_device *netdev; /* netdev ring belongs to */
@@ -277,11 +278,7 @@ struct ixgbe_ring_feature {
277278
} ____cacheline_internodealigned_in_smp;
278279

279280
struct ixgbe_ring_container {
280-
#if MAX_RX_QUEUES > MAX_TX_QUEUES
281-
DECLARE_BITMAP(idx, MAX_RX_QUEUES);
282-
#else
283-
DECLARE_BITMAP(idx, MAX_TX_QUEUES);
284-
#endif
281+
struct ixgbe_ring *ring; /* pointer to linked list of rings */
285282
unsigned int total_bytes; /* total bytes processed this int */
286283
unsigned int total_packets; /* total packets processed this int */
287284
u16 work_limit; /* total work allowed per interrupt */

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

Lines changed: 58 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -974,26 +974,17 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
974974
static void ixgbe_update_dca(struct ixgbe_q_vector *q_vector)
975975
{
976976
struct ixgbe_adapter *adapter = q_vector->adapter;
977+
struct ixgbe_ring *ring;
977978
int cpu = get_cpu();
978-
long r_idx;
979-
int i;
980979

981980
if (q_vector->cpu == cpu)
982981
goto out_no_update;
983982

984-
r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues);
985-
for (i = 0; i < q_vector->tx.count; i++) {
986-
ixgbe_update_tx_dca(adapter, adapter->tx_ring[r_idx], cpu);
987-
r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues,
988-
r_idx + 1);
989-
}
983+
for (ring = q_vector->tx.ring; ring != NULL; ring = ring->next)
984+
ixgbe_update_tx_dca(adapter, ring, cpu);
990985

991-
r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues);
992-
for (i = 0; i < q_vector->rx.count; i++) {
993-
ixgbe_update_rx_dca(adapter, adapter->rx_ring[r_idx], cpu);
994-
r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues,
995-
r_idx + 1);
996-
}
986+
for (ring = q_vector->rx.ring; ring != NULL; ring = ring->next)
987+
ixgbe_update_rx_dca(adapter, ring, cpu);
997988

998989
q_vector->cpu = cpu;
999990
out_no_update:
@@ -1546,7 +1537,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *, int);
15461537
static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
15471538
{
15481539
struct ixgbe_q_vector *q_vector;
1549-
int i, q_vectors, v_idx, r_idx;
1540+
int q_vectors, v_idx;
15501541
u32 mask;
15511542

15521543
q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
@@ -1556,33 +1547,19 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
15561547
* corresponding register.
15571548
*/
15581549
for (v_idx = 0; v_idx < q_vectors; v_idx++) {
1550+
struct ixgbe_ring *ring;
15591551
q_vector = adapter->q_vector[v_idx];
1560-
/* XXX for_each_set_bit(...) */
1561-
r_idx = find_first_bit(q_vector->rx.idx,
1562-
adapter->num_rx_queues);
1563-
1564-
for (i = 0; i < q_vector->rx.count; i++) {
1565-
u8 reg_idx = adapter->rx_ring[r_idx]->reg_idx;
1566-
ixgbe_set_ivar(adapter, 0, reg_idx, v_idx);
1567-
r_idx = find_next_bit(q_vector->rx.idx,
1568-
adapter->num_rx_queues,
1569-
r_idx + 1);
1570-
}
1571-
r_idx = find_first_bit(q_vector->tx.idx,
1572-
adapter->num_tx_queues);
1573-
1574-
for (i = 0; i < q_vector->tx.count; i++) {
1575-
u8 reg_idx = adapter->tx_ring[r_idx]->reg_idx;
1576-
ixgbe_set_ivar(adapter, 1, reg_idx, v_idx);
1577-
r_idx = find_next_bit(q_vector->tx.idx,
1578-
adapter->num_tx_queues,
1579-
r_idx + 1);
1580-
}
15811552

1582-
if (q_vector->tx.count && !q_vector->rx.count)
1553+
for (ring = q_vector->rx.ring; ring != NULL; ring = ring->next)
1554+
ixgbe_set_ivar(adapter, 0, ring->reg_idx, v_idx);
1555+
1556+
for (ring = q_vector->tx.ring; ring != NULL; ring = ring->next)
1557+
ixgbe_set_ivar(adapter, 1, ring->reg_idx, v_idx);
1558+
1559+
if (q_vector->tx.ring && !q_vector->rx.ring)
15831560
/* tx only */
15841561
q_vector->eitr = adapter->tx_eitr_param;
1585-
else if (q_vector->rx.count)
1562+
else if (q_vector->rx.ring)
15861563
/* rx or mixed */
15871564
q_vector->eitr = adapter->rx_eitr_param;
15881565

@@ -2006,20 +1983,10 @@ static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter,
20061983
static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
20071984
{
20081985
struct ixgbe_q_vector *q_vector = data;
2009-
struct ixgbe_adapter *adapter = q_vector->adapter;
2010-
struct ixgbe_ring *tx_ring;
2011-
int i, r_idx;
20121986

20131987
if (!q_vector->tx.count)
20141988
return IRQ_HANDLED;
20151989

2016-
r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues);
2017-
for (i = 0; i < q_vector->tx.count; i++) {
2018-
tx_ring = adapter->tx_ring[r_idx];
2019-
r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues,
2020-
r_idx + 1);
2021-
}
2022-
20231990
/* EIAM disabled interrupts (on this vector) for us */
20241991
napi_schedule(&q_vector->napi);
20251992

@@ -2034,22 +2001,6 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
20342001
static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
20352002
{
20362003
struct ixgbe_q_vector *q_vector = data;
2037-
struct ixgbe_adapter *adapter = q_vector->adapter;
2038-
struct ixgbe_ring *rx_ring;
2039-
int r_idx;
2040-
int i;
2041-
2042-
#ifdef CONFIG_IXGBE_DCA
2043-
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
2044-
ixgbe_update_dca(q_vector);
2045-
#endif
2046-
2047-
r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues);
2048-
for (i = 0; i < q_vector->rx.count; i++) {
2049-
rx_ring = adapter->rx_ring[r_idx];
2050-
r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues,
2051-
r_idx + 1);
2052-
}
20532004

20542005
if (!q_vector->rx.count)
20552006
return IRQ_HANDLED;
@@ -2063,28 +2014,10 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
20632014
static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
20642015
{
20652016
struct ixgbe_q_vector *q_vector = data;
2066-
struct ixgbe_adapter *adapter = q_vector->adapter;
2067-
struct ixgbe_ring *ring;
2068-
int r_idx;
2069-
int i;
20702017

20712018
if (!q_vector->tx.count && !q_vector->rx.count)
20722019
return IRQ_HANDLED;
20732020

2074-
r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues);
2075-
for (i = 0; i < q_vector->tx.count; i++) {
2076-
ring = adapter->tx_ring[r_idx];
2077-
r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues,
2078-
r_idx + 1);
2079-
}
2080-
2081-
r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues);
2082-
for (i = 0; i < q_vector->rx.count; i++) {
2083-
ring = adapter->rx_ring[r_idx];
2084-
r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues,
2085-
r_idx + 1);
2086-
}
2087-
20882021
/* EIAM disabled interrupts (on this vector) for us */
20892022
napi_schedule(&q_vector->napi);
20902023

@@ -2104,19 +2037,14 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
21042037
struct ixgbe_q_vector *q_vector =
21052038
container_of(napi, struct ixgbe_q_vector, napi);
21062039
struct ixgbe_adapter *adapter = q_vector->adapter;
2107-
struct ixgbe_ring *rx_ring = NULL;
21082040
int work_done = 0;
2109-
long r_idx;
21102041

21112042
#ifdef CONFIG_IXGBE_DCA
21122043
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
21132044
ixgbe_update_dca(q_vector);
21142045
#endif
21152046

2116-
r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues);
2117-
rx_ring = adapter->rx_ring[r_idx];
2118-
2119-
ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
2047+
ixgbe_clean_rx_irq(q_vector, q_vector->rx.ring, &work_done, budget);
21202048

21212049
/* If all Rx work done, exit the polling mode */
21222050
if (work_done < budget) {
@@ -2144,38 +2072,29 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
21442072
struct ixgbe_q_vector *q_vector =
21452073
container_of(napi, struct ixgbe_q_vector, napi);
21462074
struct ixgbe_adapter *adapter = q_vector->adapter;
2147-
struct ixgbe_ring *ring = NULL;
2148-
int work_done = 0, i;
2149-
long r_idx;
2150-
bool tx_clean_complete = true;
2075+
struct ixgbe_ring *ring;
2076+
int work_done = 0;
2077+
bool clean_complete = true;
21512078

21522079
#ifdef CONFIG_IXGBE_DCA
21532080
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
21542081
ixgbe_update_dca(q_vector);
21552082
#endif
21562083

2157-
r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues);
2158-
for (i = 0; i < q_vector->tx.count; i++) {
2159-
ring = adapter->tx_ring[r_idx];
2160-
tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring);
2161-
r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues,
2162-
r_idx + 1);
2163-
}
2084+
for (ring = q_vector->tx.ring; ring != NULL; ring = ring->next)
2085+
clean_complete &= ixgbe_clean_tx_irq(q_vector, ring);
21642086

21652087
/* attempt to distribute budget to each queue fairly, but don't allow
21662088
* the budget to go below 1 because we'll exit polling */
21672089
budget /= (q_vector->rx.count ?: 1);
21682090
budget = max(budget, 1);
2169-
r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues);
2170-
for (i = 0; i < q_vector->rx.count; i++) {
2171-
ring = adapter->rx_ring[r_idx];
2091+
2092+
for (ring = q_vector->rx.ring; ring != NULL; ring = ring->next)
21722093
ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget);
2173-
r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues,
2174-
r_idx + 1);
2175-
}
21762094

2177-
r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues);
2178-
ring = adapter->rx_ring[r_idx];
2095+
if (!clean_complete)
2096+
work_done = budget;
2097+
21792098
/* If all Rx work done, exit the polling mode */
21802099
if (work_done < budget) {
21812100
napi_complete(napi);
@@ -2203,32 +2122,23 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget)
22032122
struct ixgbe_q_vector *q_vector =
22042123
container_of(napi, struct ixgbe_q_vector, napi);
22052124
struct ixgbe_adapter *adapter = q_vector->adapter;
2206-
struct ixgbe_ring *tx_ring = NULL;
2207-
int work_done = 0;
2208-
long r_idx;
22092125

22102126
#ifdef CONFIG_IXGBE_DCA
22112127
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
22122128
ixgbe_update_dca(q_vector);
22132129
#endif
22142130

2215-
r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues);
2216-
tx_ring = adapter->tx_ring[r_idx];
2217-
2218-
if (!ixgbe_clean_tx_irq(q_vector, tx_ring))
2219-
work_done = budget;
2131+
if (!ixgbe_clean_tx_irq(q_vector, q_vector->tx.ring))
2132+
return budget;
22202133

22212134
/* If all Tx work done, exit the polling mode */
2222-
if (work_done < budget) {
2223-
napi_complete(napi);
2224-
if (adapter->tx_itr_setting & 1)
2225-
ixgbe_set_itr(q_vector);
2226-
if (!test_bit(__IXGBE_DOWN, &adapter->state))
2227-
ixgbe_irq_enable_queues(adapter,
2228-
((u64)1 << q_vector->v_idx));
2229-
}
2135+
napi_complete(napi);
2136+
if (adapter->tx_itr_setting & 1)
2137+
ixgbe_set_itr(q_vector);
2138+
if (!test_bit(__IXGBE_DOWN, &adapter->state))
2139+
ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx));
22302140

2231-
return work_done;
2141+
return 0;
22322142
}
22332143

22342144
static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
@@ -2237,9 +2147,10 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
22372147
struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
22382148
struct ixgbe_ring *rx_ring = a->rx_ring[r_idx];
22392149

2240-
set_bit(r_idx, q_vector->rx.idx);
2241-
q_vector->rx.count++;
22422150
rx_ring->q_vector = q_vector;
2151+
rx_ring->next = q_vector->rx.ring;
2152+
q_vector->rx.ring = rx_ring;
2153+
q_vector->rx.count++;
22432154
}
22442155

22452156
static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
@@ -2248,9 +2159,10 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
22482159
struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
22492160
struct ixgbe_ring *tx_ring = a->tx_ring[t_idx];
22502161

2251-
set_bit(t_idx, q_vector->tx.idx);
2252-
q_vector->tx.count++;
22532162
tx_ring->q_vector = q_vector;
2163+
tx_ring->next = q_vector->tx.ring;
2164+
q_vector->tx.ring = tx_ring;
2165+
q_vector->tx.count++;
22542166
q_vector->tx.work_limit = a->tx_work_limit;
22552167
}
22562168

@@ -2508,14 +2420,26 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
25082420

25092421
static inline void ixgbe_reset_q_vectors(struct ixgbe_adapter *adapter)
25102422
{
2511-
int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
2423+
int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
2424+
int i;
2425+
2426+
/* legacy and MSI only use one vector */
2427+
if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED))
2428+
q_vectors = 1;
2429+
2430+
for (i = 0; i < adapter->num_rx_queues; i++) {
2431+
adapter->rx_ring[i]->q_vector = NULL;
2432+
adapter->rx_ring[i]->next = NULL;
2433+
}
2434+
for (i = 0; i < adapter->num_tx_queues; i++) {
2435+
adapter->tx_ring[i]->q_vector = NULL;
2436+
adapter->tx_ring[i]->next = NULL;
2437+
}
25122438

25132439
for (i = 0; i < q_vectors; i++) {
25142440
struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
2515-
bitmap_zero(q_vector->rx.idx, MAX_RX_QUEUES);
2516-
bitmap_zero(q_vector->tx.idx, MAX_TX_QUEUES);
2517-
q_vector->rx.count = 0;
2518-
q_vector->tx.count = 0;
2441+
memset(&q_vector->rx, 0, sizeof(struct ixgbe_ring_container));
2442+
memset(&q_vector->tx, 0, sizeof(struct ixgbe_ring_container));
25192443
}
25202444
}
25212445

@@ -5923,7 +5847,7 @@ static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter)
59235847
/* get one bit for every active tx/rx interrupt vector */
59245848
for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
59255849
struct ixgbe_q_vector *qv = adapter->q_vector[i];
5926-
if (qv->rx.count || qv->tx.count)
5850+
if (qv->rx.ring || qv->tx.ring)
59275851
eics |= ((u64)1 << i);
59285852
}
59295853
}

0 commit comments

Comments
 (0)