Commit b2f8ef03 authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'fix-irq-vectors'

Jiawen Wu says:

====================
Fix IRQ vectors

The interrupt vector order was adjusted by [1]commit 937d46ec ("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 aefd0136 ("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/20250701063030.59340-1-jiawenwu@trustnetic.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents b0727b0c 4174c0c3
Loading
Loading
Loading
Loading
+17 −9
Original line number Diff line number Diff line
@@ -1747,7 +1747,7 @@ static void wx_set_num_queues(struct wx *wx)
 */
static int wx_acquire_msix_vectors(struct wx *wx)
{
	struct irq_affinity affd = { .pre_vectors = 1 };
	struct irq_affinity affd = { .post_vectors = 1 };
	int nvecs, i;

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

	wx->msix_entry->entry = 0;
	wx->msix_entry->vector = pci_irq_vector(wx->pdev, 0);
	nvecs -= 1;
	for (i = 0; i < nvecs; i++) {
		wx->msix_q_entries[i].entry = i;
		wx->msix_q_entries[i].vector = pci_irq_vector(wx->pdev, i + 1);
		wx->msix_q_entries[i].vector = pci_irq_vector(wx->pdev, i);
	}

	wx->num_q_vectors = nvecs;

	wx->msix_entry->entry = nvecs;
	wx->msix_entry->vector = pci_irq_vector(wx->pdev, nvecs);

	if (test_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags)) {
		wx->msix_entry->entry = 0;
		wx->msix_entry->vector = pci_irq_vector(wx->pdev, 0);
		wx->msix_q_entries[0].entry = 0;
		wx->msix_q_entries[0].vector = pci_irq_vector(wx->pdev, 1);
	}

	return 0;
}

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

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

	itr_reg |= WX_PX_ITR_CNT_WDIS;

	wr32(wx, WX_PX_ITR(v_idx + 1), itr_reg);
	wr32(wx, WX_PX_ITR(v_idx), itr_reg);
}

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

	wx_set_ivar(wx, -1, 0, 0);
	wx_set_ivar(wx, -1, 0, v_idx);
	if (pdev->msix_enabled)
		wr32(wx, WX_PX_ITR(0), 1950);
		wr32(wx, WX_PX_ITR(v_idx), 1950);
}
EXPORT_SYMBOL(wx_configure_vectors);

+4 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ static void wx_sriov_clear_data(struct wx *wx)
	wr32m(wx, WX_PSR_VM_CTL, WX_PSR_VM_CTL_POOL_MASK, 0);
	wx->ring_feature[RING_F_VMDQ].offset = 0;

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

	if (num_vfs == 7 && wx->mac.type == wx_mac_em)
		set_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags);

	/* Enable VMDq flag so device will be set in VM mode */
	set_bit(WX_FLAG_VMDQ_ENABLED, wx->flags);
	if (!wx->ring_feature[RING_F_VMDQ].limit)
+2 −1
Original line number Diff line number Diff line
@@ -1191,6 +1191,7 @@ enum wx_pf_flags {
	WX_FLAG_VMDQ_ENABLED,
	WX_FLAG_VLAN_PROMISC,
	WX_FLAG_SRIOV_ENABLED,
	WX_FLAG_IRQ_VECTOR_SHARED,
	WX_FLAG_FDIR_CAPABLE,
	WX_FLAG_FDIR_HASH,
	WX_FLAG_FDIR_PERFECT,
@@ -1343,7 +1344,7 @@ struct wx {
};

#define WX_INTR_ALL (~0ULL)
#define WX_INTR_Q(i) BIT((i) + 1)
#define WX_INTR_Q(i) BIT((i))

/* register operations */
#define wr32(a, reg, value)	writel((value), ((a)->hw_addr + (reg)))
+2 −2
Original line number Diff line number Diff line
@@ -161,7 +161,7 @@ static void ngbe_irq_enable(struct wx *wx, bool queues)
	if (queues)
		wx_intr_enable(wx, NGBE_INTR_ALL);
	else
		wx_intr_enable(wx, NGBE_INTR_MISC);
		wx_intr_enable(wx, NGBE_INTR_MISC(wx));
}

/**
@@ -286,7 +286,7 @@ static int ngbe_request_msix_irqs(struct wx *wx)
	 * for queue. But when num_vfs == 7, vector[1] is assigned to vf6.
	 * Misc and queue should reuse interrupt vector[0].
	 */
	if (wx->num_vfs == 7)
	if (test_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags))
		err = request_irq(wx->msix_entry->vector,
				  ngbe_misc_and_queue, 0, netdev->name, wx);
	else
+1 −1
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@
#define NGBE_PX_MISC_IC_TIMESYNC		BIT(11) /* time sync */

#define NGBE_INTR_ALL				0x1FF
#define NGBE_INTR_MISC				BIT(0)
#define NGBE_INTR_MISC(A)			BIT((A)->msix_entry->entry)

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