Skip to content

Commit b2f8ef0

Browse files
author
Paolo Abeni
committed
Merge branch 'fix-irq-vectors'
Jiawen Wu says: ==================== Fix IRQ vectors The interrupt vector order was adjusted by [1]commit 937d46e ("net: wangxun: add ethtool_ops for channel number") in Linux-6.8. Because at that time, the MISC interrupt acts as the parent interrupt in the GPIO IRQ chip. When the number of Rx/Tx ring changes, the last MISC interrupt must be reallocated. Then the GPIO interrupt controller would be corrupted. So the initial plan was to adjust the sequence of the interrupt vectors, let MISC interrupt to be the first one and do not free it. Later, irq_domain was introduced in [2]commit aefd013 ("net: txgbe: use irq_domain for interrupt controller") to avoid this problem. However, the vector sequence adjustment was not reverted. So there is still one problem that has been left unresolved. Due to hardware limitations of NGBE, queue IRQs can only be requested on vector 0 to 7. When the number of queues is set to the maximum 8, the PCI IRQ vectors are allocated from 0 to 8. The vector 0 is used by MISC interrupt, and althrough the vector 8 is used by queue interrupt, it is unable to receive packets. This will cause some packets to be dropped when RSS is enabled and they are assigned to queue 8. This patch set fix the above problems. [1] https://git.kernel.org/netdev/net-next/c/937d46ecc5f9 [2] https://git.kernel.org/netdev/net-next/c/aefd013624a1 ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents b0727b0 + 4174c0c commit b2f8ef0

File tree

8 files changed

+42
-31
lines changed

8 files changed

+42
-31
lines changed

drivers/net/ethernet/wangxun/libwx/wx_lib.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,7 +1747,7 @@ static void wx_set_num_queues(struct wx *wx)
17471747
*/
17481748
static int wx_acquire_msix_vectors(struct wx *wx)
17491749
{
1750-
struct irq_affinity affd = { .pre_vectors = 1 };
1750+
struct irq_affinity affd = { .post_vectors = 1 };
17511751
int nvecs, i;
17521752

17531753
/* We start by asking for one vector per queue pair */
@@ -1784,16 +1784,24 @@ static int wx_acquire_msix_vectors(struct wx *wx)
17841784
return nvecs;
17851785
}
17861786

1787-
wx->msix_entry->entry = 0;
1788-
wx->msix_entry->vector = pci_irq_vector(wx->pdev, 0);
17891787
nvecs -= 1;
17901788
for (i = 0; i < nvecs; i++) {
17911789
wx->msix_q_entries[i].entry = i;
1792-
wx->msix_q_entries[i].vector = pci_irq_vector(wx->pdev, i + 1);
1790+
wx->msix_q_entries[i].vector = pci_irq_vector(wx->pdev, i);
17931791
}
17941792

17951793
wx->num_q_vectors = nvecs;
17961794

1795+
wx->msix_entry->entry = nvecs;
1796+
wx->msix_entry->vector = pci_irq_vector(wx->pdev, nvecs);
1797+
1798+
if (test_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags)) {
1799+
wx->msix_entry->entry = 0;
1800+
wx->msix_entry->vector = pci_irq_vector(wx->pdev, 0);
1801+
wx->msix_q_entries[0].entry = 0;
1802+
wx->msix_q_entries[0].vector = pci_irq_vector(wx->pdev, 1);
1803+
}
1804+
17971805
return 0;
17981806
}
17991807

@@ -2292,6 +2300,8 @@ static void wx_set_ivar(struct wx *wx, s8 direction,
22922300

22932301
if (direction == -1) {
22942302
/* other causes */
2303+
if (test_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags))
2304+
msix_vector = 0;
22952305
msix_vector |= WX_PX_IVAR_ALLOC_VAL;
22962306
index = 0;
22972307
ivar = rd32(wx, WX_PX_MISC_IVAR);
@@ -2300,8 +2310,6 @@ static void wx_set_ivar(struct wx *wx, s8 direction,
23002310
wr32(wx, WX_PX_MISC_IVAR, ivar);
23012311
} else {
23022312
/* tx or rx causes */
2303-
if (!(wx->mac.type == wx_mac_em && wx->num_vfs == 7))
2304-
msix_vector += 1; /* offset for queue vectors */
23052313
msix_vector |= WX_PX_IVAR_ALLOC_VAL;
23062314
index = ((16 * (queue & 1)) + (8 * direction));
23072315
ivar = rd32(wx, WX_PX_IVAR(queue >> 1));
@@ -2340,7 +2348,7 @@ void wx_write_eitr(struct wx_q_vector *q_vector)
23402348

23412349
itr_reg |= WX_PX_ITR_CNT_WDIS;
23422350

2343-
wr32(wx, WX_PX_ITR(v_idx + 1), itr_reg);
2351+
wr32(wx, WX_PX_ITR(v_idx), itr_reg);
23442352
}
23452353

23462354
/**
@@ -2393,9 +2401,9 @@ void wx_configure_vectors(struct wx *wx)
23932401
wx_write_eitr(q_vector);
23942402
}
23952403

2396-
wx_set_ivar(wx, -1, 0, 0);
2404+
wx_set_ivar(wx, -1, 0, v_idx);
23972405
if (pdev->msix_enabled)
2398-
wr32(wx, WX_PX_ITR(0), 1950);
2406+
wr32(wx, WX_PX_ITR(v_idx), 1950);
23992407
}
24002408
EXPORT_SYMBOL(wx_configure_vectors);
24012409

drivers/net/ethernet/wangxun/libwx/wx_sriov.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ static void wx_sriov_clear_data(struct wx *wx)
6464
wr32m(wx, WX_PSR_VM_CTL, WX_PSR_VM_CTL_POOL_MASK, 0);
6565
wx->ring_feature[RING_F_VMDQ].offset = 0;
6666

67+
clear_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags);
6768
clear_bit(WX_FLAG_SRIOV_ENABLED, wx->flags);
6869
/* Disable VMDq flag so device will be set in NM mode */
6970
if (wx->ring_feature[RING_F_VMDQ].limit == 1)
@@ -78,6 +79,9 @@ static int __wx_enable_sriov(struct wx *wx, u8 num_vfs)
7879
set_bit(WX_FLAG_SRIOV_ENABLED, wx->flags);
7980
dev_info(&wx->pdev->dev, "SR-IOV enabled with %d VFs\n", num_vfs);
8081

82+
if (num_vfs == 7 && wx->mac.type == wx_mac_em)
83+
set_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags);
84+
8185
/* Enable VMDq flag so device will be set in VM mode */
8286
set_bit(WX_FLAG_VMDQ_ENABLED, wx->flags);
8387
if (!wx->ring_feature[RING_F_VMDQ].limit)

drivers/net/ethernet/wangxun/libwx/wx_type.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1191,6 +1191,7 @@ enum wx_pf_flags {
11911191
WX_FLAG_VMDQ_ENABLED,
11921192
WX_FLAG_VLAN_PROMISC,
11931193
WX_FLAG_SRIOV_ENABLED,
1194+
WX_FLAG_IRQ_VECTOR_SHARED,
11941195
WX_FLAG_FDIR_CAPABLE,
11951196
WX_FLAG_FDIR_HASH,
11961197
WX_FLAG_FDIR_PERFECT,
@@ -1343,7 +1344,7 @@ struct wx {
13431344
};
13441345

13451346
#define WX_INTR_ALL (~0ULL)
1346-
#define WX_INTR_Q(i) BIT((i) + 1)
1347+
#define WX_INTR_Q(i) BIT((i))
13471348

13481349
/* register operations */
13491350
#define wr32(a, reg, value) writel((value), ((a)->hw_addr + (reg)))

drivers/net/ethernet/wangxun/ngbe/ngbe_main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ static void ngbe_irq_enable(struct wx *wx, bool queues)
161161
if (queues)
162162
wx_intr_enable(wx, NGBE_INTR_ALL);
163163
else
164-
wx_intr_enable(wx, NGBE_INTR_MISC);
164+
wx_intr_enable(wx, NGBE_INTR_MISC(wx));
165165
}
166166

167167
/**
@@ -286,7 +286,7 @@ static int ngbe_request_msix_irqs(struct wx *wx)
286286
* for queue. But when num_vfs == 7, vector[1] is assigned to vf6.
287287
* Misc and queue should reuse interrupt vector[0].
288288
*/
289-
if (wx->num_vfs == 7)
289+
if (test_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags))
290290
err = request_irq(wx->msix_entry->vector,
291291
ngbe_misc_and_queue, 0, netdev->name, wx);
292292
else

drivers/net/ethernet/wangxun/ngbe/ngbe_type.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
#define NGBE_PX_MISC_IC_TIMESYNC BIT(11) /* time sync */
8888

8989
#define NGBE_INTR_ALL 0x1FF
90-
#define NGBE_INTR_MISC BIT(0)
90+
#define NGBE_INTR_MISC(A) BIT((A)->msix_entry->entry)
9191

9292
#define NGBE_PHY_CONFIG(reg_offset) (0x14000 + ((reg_offset) * 4))
9393
#define NGBE_CFG_LAN_SPEED 0x14440

drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ void txgbe_irq_enable(struct wx *wx, bool queues)
3131
wr32(wx, WX_PX_MISC_IEN, misc_ien);
3232

3333
/* unmask interrupt */
34-
wx_intr_enable(wx, TXGBE_INTR_MISC);
34+
wx_intr_enable(wx, TXGBE_INTR_MISC(wx));
3535
if (queues)
3636
wx_intr_enable(wx, TXGBE_INTR_QALL(wx));
3737
}
@@ -78,7 +78,6 @@ int txgbe_request_queue_irqs(struct wx *wx)
7878
free_irq(wx->msix_q_entries[vector].vector,
7979
wx->q_vector[vector]);
8080
}
81-
wx_reset_interrupt_capability(wx);
8281
return err;
8382
}
8483

@@ -132,7 +131,7 @@ static irqreturn_t txgbe_misc_irq_handle(int irq, void *data)
132131
txgbe->eicr = eicr;
133132
if (eicr & TXGBE_PX_MISC_IC_VF_MBOX) {
134133
wx_msg_task(txgbe->wx);
135-
wx_intr_enable(wx, TXGBE_INTR_MISC);
134+
wx_intr_enable(wx, TXGBE_INTR_MISC(wx));
136135
}
137136
return IRQ_WAKE_THREAD;
138137
}
@@ -184,7 +183,7 @@ static irqreturn_t txgbe_misc_irq_thread_fn(int irq, void *data)
184183
nhandled++;
185184
}
186185

187-
wx_intr_enable(wx, TXGBE_INTR_MISC);
186+
wx_intr_enable(wx, TXGBE_INTR_MISC(wx));
188187
return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
189188
}
190189

@@ -211,6 +210,7 @@ void txgbe_free_misc_irq(struct txgbe *txgbe)
211210
free_irq(txgbe->link_irq, txgbe);
212211
free_irq(txgbe->misc.irq, txgbe);
213212
txgbe_del_irq_domain(txgbe);
213+
txgbe->wx->misc_irq_domain = false;
214214
}
215215

216216
int txgbe_setup_misc_irq(struct txgbe *txgbe)

drivers/net/ethernet/wangxun/txgbe/txgbe_main.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -458,10 +458,14 @@ static int txgbe_open(struct net_device *netdev)
458458

459459
wx_configure(wx);
460460

461-
err = txgbe_request_queue_irqs(wx);
461+
err = txgbe_setup_misc_irq(wx->priv);
462462
if (err)
463463
goto err_free_resources;
464464

465+
err = txgbe_request_queue_irqs(wx);
466+
if (err)
467+
goto err_free_misc_irq;
468+
465469
/* Notify the stack of the actual queue counts. */
466470
err = netif_set_real_num_tx_queues(netdev, wx->num_tx_queues);
467471
if (err)
@@ -479,6 +483,9 @@ static int txgbe_open(struct net_device *netdev)
479483

480484
err_free_irq:
481485
wx_free_irq(wx);
486+
err_free_misc_irq:
487+
txgbe_free_misc_irq(wx->priv);
488+
wx_reset_interrupt_capability(wx);
482489
err_free_resources:
483490
wx_free_resources(wx);
484491
err_reset:
@@ -519,6 +526,7 @@ static int txgbe_close(struct net_device *netdev)
519526
wx_ptp_stop(wx);
520527
txgbe_down(wx);
521528
wx_free_irq(wx);
529+
txgbe_free_misc_irq(wx->priv);
522530
wx_free_resources(wx);
523531
txgbe_fdir_filter_exit(wx);
524532
wx_control_hw(wx, false);
@@ -564,7 +572,6 @@ static void txgbe_shutdown(struct pci_dev *pdev)
564572
int txgbe_setup_tc(struct net_device *dev, u8 tc)
565573
{
566574
struct wx *wx = netdev_priv(dev);
567-
struct txgbe *txgbe = wx->priv;
568575

569576
/* Hardware has to reinitialize queues and interrupts to
570577
* match packet buffer alignment. Unfortunately, the
@@ -575,7 +582,6 @@ int txgbe_setup_tc(struct net_device *dev, u8 tc)
575582
else
576583
txgbe_reset(wx);
577584

578-
txgbe_free_misc_irq(txgbe);
579585
wx_clear_interrupt_scheme(wx);
580586

581587
if (tc)
@@ -584,7 +590,6 @@ int txgbe_setup_tc(struct net_device *dev, u8 tc)
584590
netdev_reset_tc(dev);
585591

586592
wx_init_interrupt_scheme(wx);
587-
txgbe_setup_misc_irq(txgbe);
588593

589594
if (netif_running(dev))
590595
txgbe_open(dev);
@@ -882,13 +887,9 @@ static int txgbe_probe(struct pci_dev *pdev,
882887

883888
txgbe_init_fdir(txgbe);
884889

885-
err = txgbe_setup_misc_irq(txgbe);
886-
if (err)
887-
goto err_release_hw;
888-
889890
err = txgbe_init_phy(txgbe);
890891
if (err)
891-
goto err_free_misc_irq;
892+
goto err_release_hw;
892893

893894
err = register_netdev(netdev);
894895
if (err)
@@ -916,8 +917,6 @@ static int txgbe_probe(struct pci_dev *pdev,
916917

917918
err_remove_phy:
918919
txgbe_remove_phy(txgbe);
919-
err_free_misc_irq:
920-
txgbe_free_misc_irq(txgbe);
921920
err_release_hw:
922921
wx_clear_interrupt_scheme(wx);
923922
wx_control_hw(wx, false);
@@ -957,7 +956,6 @@ static void txgbe_remove(struct pci_dev *pdev)
957956
unregister_netdev(netdev);
958957

959958
txgbe_remove_phy(txgbe);
960-
txgbe_free_misc_irq(txgbe);
961959
wx_free_isb_resources(wx);
962960

963961
pci_release_selected_regions(pdev,

drivers/net/ethernet/wangxun/txgbe/txgbe_type.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,8 @@ struct txgbe_fdir_filter {
302302
#define TXGBE_DEFAULT_RX_WORK 128
303303
#endif
304304

305-
#define TXGBE_INTR_MISC BIT(0)
306-
#define TXGBE_INTR_QALL(A) GENMASK((A)->num_q_vectors, 1)
305+
#define TXGBE_INTR_MISC(A) BIT((A)->num_q_vectors)
306+
#define TXGBE_INTR_QALL(A) (TXGBE_INTR_MISC(A) - 1)
307307

308308
#define TXGBE_MAX_EITR GENMASK(11, 3)
309309

0 commit comments

Comments
 (0)