Skip to content

Commit

Permalink
Merge branch 'intel-wired-lan-driver-updates-2025-01-06-igb-igc-ixgbe…
Browse files Browse the repository at this point in the history
…-ixgbevf-i40e-fm10k'

Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2025-01-06 (igb, igc, ixgbe, ixgbevf, i40e, fm10k)

For igb:

Sriram Yagnaraman and Kurt Kanzenbach add support for AF_XDP
zero-copy.

Original cover letter:
The first couple of patches adds helper functions to prepare for AF_XDP
zero-copy support which comes in the last couple of patches, one each
for Rx and TX paths.

As mentioned in v1 patchset [0], I don't have access to an actual IGB
device to provide correct performance numbers. I have used Intel 82576EB
emulator in QEMU [1] to test the changes to IGB driver.

The tests use one isolated vCPU for RX/TX and one isolated vCPU for the
xdp-sock application [2]. Hope these measurements provide at the least
some indication on the increase in performance when using ZC, especially
in the TX path. It would be awesome if someone with a real IGB NIC can
test the patch.

AF_XDP performance using 64 byte packets in Kpps.
Benchmark:	XDP-SKB		XDP-DRV		XDP-DRV(ZC)
rxdrop		220		235		350
txpush		1.000		1.000		410
l2fwd 		1.000		1.000		200

AF_XDP performance using 1500 byte packets in Kpps.
Benchmark:	XDP-SKB		XDP-DRV		XDP-DRV(ZC)
rxdrop		200		210		310
txpush		1.000		1.000		410
l2fwd 		0.900		1.000		160

[0]: https://lore.kernel.org/intel-wired-lan/[email protected]/
[1]: https://www.qemu.org/docs/master/system/devices/igb.html
[2]: https://github.com/xdp-project/bpf-examples/tree/master/AF_XDP-example

Subsequent changes and information can be found here:
https://lore.kernel.org/intel-wired-lan/[email protected]/

Yue Haibing converts use of ERR_PTR return to traditional error code
which resolves a smatch warning.

For igc:

Song Yoong Siang allows for the XDP program to be hot-swapped.

Yue Haibing converts use of ERR_PTR return to traditional error code
which resolves a smatch warning.

Joe Damato adds sets IRQ and queues to NAPI instances to allow for
reporting via netdev-genl API.

For ixgbe:

Yue Haibing converts use of ERR_PTR return to traditional error code
which resolves a smatch warning.

For ixgbevf:

Yue Haibing converts use of ERR_PTR return to traditional error code
which resolves a smatch warning.

For i40e:

Alex implements "mdd-auto-reset-vf" private flag to automatically reset
VFs when encountering an MDD event.

For fm10k:

Dr. David Alan Gilbert removes an unused function.
====================

Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
kuba-moo committed Jan 8, 2025
2 parents acafa84 + 6052373 commit 7bf1659
Show file tree
Hide file tree
Showing 18 changed files with 1,002 additions and 287 deletions.
12 changes: 12 additions & 0 deletions Documentation/networking/device_drivers/ethernet/intel/i40e.rst
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,18 @@ Use ethtool to view and set link-down-on-close, as follows::
ethtool --show-priv-flags ethX
ethtool --set-priv-flags ethX link-down-on-close [on|off]

Setting the mdd-auto-reset-vf Private Flag
------------------------------------------

When the mdd-auto-reset-vf private flag is set to "on", the problematic VF will
be automatically reset if a malformed descriptor is detected. If the flag is
set to "off", the problematic VF will be disabled.

Use ethtool to view and set mdd-auto-reset-vf, as follows::

ethtool --show-priv-flags ethX
ethtool --set-priv-flags ethX mdd-auto-reset-vf [on|off]

Viewing Link Messages
---------------------
Link messages will not be displayed to the console if the distribution is
Expand Down
120 changes: 0 additions & 120 deletions drivers/net/ethernet/intel/fm10k/fm10k_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1179,126 +1179,6 @@ s32 fm10k_iov_select_vid(struct fm10k_vf_info *vf_info, u16 vid)
return vid;
}

/**
* fm10k_iov_msg_mac_vlan_pf - Message handler for MAC/VLAN request from VF
* @hw: Pointer to hardware structure
* @results: Pointer array to message, results[0] is pointer to message
* @mbx: Pointer to mailbox information structure
*
* This function is a default handler for MAC/VLAN requests from the VF.
* The assumption is that in this case it is acceptable to just directly
* hand off the message from the VF to the underlying shared code.
**/
s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *hw, u32 **results,
struct fm10k_mbx_info *mbx)
{
struct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx;
u8 mac[ETH_ALEN];
u32 *result;
int err = 0;
bool set;
u16 vlan;
u32 vid;

/* we shouldn't be updating rules on a disabled interface */
if (!FM10K_VF_FLAG_ENABLED(vf_info))
err = FM10K_ERR_PARAM;

if (!err && !!results[FM10K_MAC_VLAN_MSG_VLAN]) {
result = results[FM10K_MAC_VLAN_MSG_VLAN];

/* record VLAN id requested */
err = fm10k_tlv_attr_get_u32(result, &vid);
if (err)
return err;

set = !(vid & FM10K_VLAN_CLEAR);
vid &= ~FM10K_VLAN_CLEAR;

/* if the length field has been set, this is a multi-bit
* update request. For multi-bit requests, simply disallow
* them when the pf_vid has been set. In this case, the PF
* should have already cleared the VLAN_TABLE, and if we
* allowed them, it could allow a rogue VF to receive traffic
* on a VLAN it was not assigned. In the single-bit case, we
* need to modify requests for VLAN 0 to use the default PF or
* SW vid when assigned.
*/

if (vid >> 16) {
/* prevent multi-bit requests when PF has
* administratively set the VLAN for this VF
*/
if (vf_info->pf_vid)
return FM10K_ERR_PARAM;
} else {
err = fm10k_iov_select_vid(vf_info, (u16)vid);
if (err < 0)
return err;

vid = err;
}

/* update VSI info for VF in regards to VLAN table */
err = hw->mac.ops.update_vlan(hw, vid, vf_info->vsi, set);
}

if (!err && !!results[FM10K_MAC_VLAN_MSG_MAC]) {
result = results[FM10K_MAC_VLAN_MSG_MAC];

/* record unicast MAC address requested */
err = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan);
if (err)
return err;

/* block attempts to set MAC for a locked device */
if (is_valid_ether_addr(vf_info->mac) &&
!ether_addr_equal(mac, vf_info->mac))
return FM10K_ERR_PARAM;

set = !(vlan & FM10K_VLAN_CLEAR);
vlan &= ~FM10K_VLAN_CLEAR;

err = fm10k_iov_select_vid(vf_info, vlan);
if (err < 0)
return err;

vlan = (u16)err;

/* notify switch of request for new unicast address */
err = hw->mac.ops.update_uc_addr(hw, vf_info->glort,
mac, vlan, set, 0);
}

if (!err && !!results[FM10K_MAC_VLAN_MSG_MULTICAST]) {
result = results[FM10K_MAC_VLAN_MSG_MULTICAST];

/* record multicast MAC address requested */
err = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan);
if (err)
return err;

/* verify that the VF is allowed to request multicast */
if (!(vf_info->vf_flags & FM10K_VF_FLAG_MULTI_ENABLED))
return FM10K_ERR_PARAM;

set = !(vlan & FM10K_VLAN_CLEAR);
vlan &= ~FM10K_VLAN_CLEAR;

err = fm10k_iov_select_vid(vf_info, vlan);
if (err < 0)
return err;

vlan = (u16)err;

/* notify switch of request for new multicast address */
err = hw->mac.ops.update_mc_addr(hw, vf_info->glort,
mac, vlan, set);
}

return err;
}

/**
* fm10k_iov_supported_xcast_mode_pf - Determine best match for xcast mode
* @vf_info: VF info structure containing capability flags
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/ethernet/intel/fm10k/fm10k_pf.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ extern const struct fm10k_tlv_attr fm10k_err_msg_attr[];

s32 fm10k_iov_select_vid(struct fm10k_vf_info *vf_info, u16 vid);
s32 fm10k_iov_msg_msix_pf(struct fm10k_hw *, u32 **, struct fm10k_mbx_info *);
s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *, u32 **,
struct fm10k_mbx_info *);
s32 fm10k_iov_msg_lport_state_pf(struct fm10k_hw *, u32 **,
struct fm10k_mbx_info *);

Expand Down
4 changes: 3 additions & 1 deletion drivers/net/ethernet/intel/i40e/i40e.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ enum i40e_state {
__I40E_SERVICE_SCHED,
__I40E_ADMINQ_EVENT_PENDING,
__I40E_MDD_EVENT_PENDING,
__I40E_MDD_VF_PRINT_PENDING,
__I40E_VFLR_EVENT_PENDING,
__I40E_RESET_RECOVERY_PENDING,
__I40E_TIMEOUT_RECOVERY_PENDING,
Expand Down Expand Up @@ -191,6 +192,7 @@ enum i40e_pf_flags {
*/
I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENA,
I40E_FLAG_VF_VLAN_PRUNING_ENA,
I40E_FLAG_MDD_AUTO_RESET_VF,
I40E_PF_FLAGS_NBITS, /* must be last */
};

Expand Down Expand Up @@ -572,7 +574,7 @@ struct i40e_pf {
int num_alloc_vfs; /* actual number of VFs allocated */
u32 vf_aq_requests;
u32 arq_overflows; /* Not fatal, possibly indicative of problems */

struct ratelimit_state mdd_message_rate_limit;
/* DCBx/DCBNL capability for PF that indicates
* whether DCBx is managed by firmware or host
* based agent (LLDPAD). Also, indicates what
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/i40e/i40e_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ static void i40e_dbg_dump_vf(struct i40e_pf *pf, int vf_id)
dev_info(&pf->pdev->dev, "vf %2d: VSI id=%d, seid=%d, qps=%d\n",
vf_id, vf->lan_vsi_id, vsi->seid, vf->num_queue_pairs);
dev_info(&pf->pdev->dev, " num MDD=%lld\n",
vf->num_mdd_events);
vf->mdd_tx_events.count + vf->mdd_rx_events.count);
} else {
dev_info(&pf->pdev->dev, "invalid VF id %d\n", vf_id);
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,8 @@ static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = {
I40E_PRIV_FLAG("base-r-fec", I40E_FLAG_BASE_R_FEC, 0),
I40E_PRIV_FLAG("vf-vlan-pruning",
I40E_FLAG_VF_VLAN_PRUNING_ENA, 0),
I40E_PRIV_FLAG("mdd-auto-reset-vf",
I40E_FLAG_MDD_AUTO_RESET_VF, 0),
};

#define I40E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gstrings_priv_flags)
Expand Down
107 changes: 94 additions & 13 deletions drivers/net/ethernet/intel/i40e/i40e_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -11179,6 +11179,67 @@ static void i40e_handle_reset_warning(struct i40e_pf *pf, bool lock_acquired)
i40e_reset_and_rebuild(pf, false, lock_acquired);
}

/**
* i40e_print_vf_mdd_event - print VF Tx/Rx malicious driver detect event
* @pf: board private structure
* @vf: pointer to the VF structure
* @is_tx: true - for Tx event, false - for Rx
*/
static void i40e_print_vf_mdd_event(struct i40e_pf *pf, struct i40e_vf *vf,
bool is_tx)
{
dev_err(&pf->pdev->dev, is_tx ?
"%lld Tx Malicious Driver Detection events detected on PF %d VF %d MAC %pm. mdd-auto-reset-vfs=%s\n" :
"%lld Rx Malicious Driver Detection events detected on PF %d VF %d MAC %pm. mdd-auto-reset-vfs=%s\n",
is_tx ? vf->mdd_tx_events.count : vf->mdd_rx_events.count,
pf->hw.pf_id,
vf->vf_id,
vf->default_lan_addr.addr,
str_on_off(test_bit(I40E_FLAG_MDD_AUTO_RESET_VF, pf->flags)));
}

/**
* i40e_print_vfs_mdd_events - print VFs malicious driver detect event
* @pf: pointer to the PF structure
*
* Called from i40e_handle_mdd_event to rate limit and print VFs MDD events.
*/
static void i40e_print_vfs_mdd_events(struct i40e_pf *pf)
{
unsigned int i;

/* check that there are pending MDD events to print */
if (!test_and_clear_bit(__I40E_MDD_VF_PRINT_PENDING, pf->state))
return;

if (!__ratelimit(&pf->mdd_message_rate_limit))
return;

for (i = 0; i < pf->num_alloc_vfs; i++) {
struct i40e_vf *vf = &pf->vf[i];
bool is_printed = false;

/* only print Rx MDD event message if there are new events */
if (vf->mdd_rx_events.count != vf->mdd_rx_events.last_printed) {
vf->mdd_rx_events.last_printed = vf->mdd_rx_events.count;
i40e_print_vf_mdd_event(pf, vf, false);
is_printed = true;
}

/* only print Tx MDD event message if there are new events */
if (vf->mdd_tx_events.count != vf->mdd_tx_events.last_printed) {
vf->mdd_tx_events.last_printed = vf->mdd_tx_events.count;
i40e_print_vf_mdd_event(pf, vf, true);
is_printed = true;
}

if (is_printed && !test_bit(I40E_FLAG_MDD_AUTO_RESET_VF, pf->flags))
dev_info(&pf->pdev->dev,
"Use PF Control I/F to re-enable the VF #%d\n",
i);
}
}

/**
* i40e_handle_mdd_event
* @pf: pointer to the PF structure
Expand All @@ -11193,8 +11254,13 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
u32 reg;
int i;

if (!test_bit(__I40E_MDD_EVENT_PENDING, pf->state))
if (!test_and_clear_bit(__I40E_MDD_EVENT_PENDING, pf->state)) {
/* Since the VF MDD event logging is rate limited, check if
* there are pending MDD events.
*/
i40e_print_vfs_mdd_events(pf);
return;
}

/* find what triggered the MDD event */
reg = rd32(hw, I40E_GL_MDET_TX);
Expand Down Expand Up @@ -11238,36 +11304,48 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)

/* see if one of the VFs needs its hand slapped */
for (i = 0; i < pf->num_alloc_vfs && mdd_detected; i++) {
bool is_mdd_on_tx = false;
bool is_mdd_on_rx = false;

vf = &(pf->vf[i]);
reg = rd32(hw, I40E_VP_MDET_TX(i));
if (reg & I40E_VP_MDET_TX_VALID_MASK) {
set_bit(__I40E_MDD_VF_PRINT_PENDING, pf->state);
wr32(hw, I40E_VP_MDET_TX(i), 0xFFFF);
vf->num_mdd_events++;
dev_info(&pf->pdev->dev, "TX driver issue detected on VF %d\n",
i);
dev_info(&pf->pdev->dev,
"Use PF Control I/F to re-enable the VF\n");
vf->mdd_tx_events.count++;
set_bit(I40E_VF_STATE_DISABLED, &vf->vf_states);
is_mdd_on_tx = true;
}

reg = rd32(hw, I40E_VP_MDET_RX(i));
if (reg & I40E_VP_MDET_RX_VALID_MASK) {
set_bit(__I40E_MDD_VF_PRINT_PENDING, pf->state);
wr32(hw, I40E_VP_MDET_RX(i), 0xFFFF);
vf->num_mdd_events++;
dev_info(&pf->pdev->dev, "RX driver issue detected on VF %d\n",
i);
dev_info(&pf->pdev->dev,
"Use PF Control I/F to re-enable the VF\n");
vf->mdd_rx_events.count++;
set_bit(I40E_VF_STATE_DISABLED, &vf->vf_states);
is_mdd_on_rx = true;
}

if ((is_mdd_on_tx || is_mdd_on_rx) &&
test_bit(I40E_FLAG_MDD_AUTO_RESET_VF, pf->flags)) {
/* VF MDD event counters will be cleared by
* reset, so print the event prior to reset.
*/
if (is_mdd_on_rx)
i40e_print_vf_mdd_event(pf, vf, false);
if (is_mdd_on_tx)
i40e_print_vf_mdd_event(pf, vf, true);

i40e_vc_reset_vf(vf, true);
}
}

/* re-enable mdd interrupt cause */
clear_bit(__I40E_MDD_EVENT_PENDING, pf->state);
reg = rd32(hw, I40E_PFINT_ICR0_ENA);
reg |= I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK;
wr32(hw, I40E_PFINT_ICR0_ENA, reg);
i40e_flush(hw);

i40e_print_vfs_mdd_events(pf);
}

/**
Expand Down Expand Up @@ -15878,6 +15956,9 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ERR_PTR(err),
i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));

/* VF MDD event logs are rate limited to one second intervals */
ratelimit_state_init(&pf->mdd_message_rate_limit, 1 * HZ, 1);

/* Reconfigure hardware for allowing smaller MSS in the case
* of TSO, so that we avoid the MDD being fired and causing
* a reset in the case of small MSS+TSO.
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf)
* @notify_vf: notify vf about reset or not
* Reset VF handler.
**/
static void i40e_vc_reset_vf(struct i40e_vf *vf, bool notify_vf)
void i40e_vc_reset_vf(struct i40e_vf *vf, bool notify_vf)
{
struct i40e_pf *pf = vf->pf;
int i;
Expand Down
11 changes: 10 additions & 1 deletion drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ struct i40evf_channel {
u64 max_tx_rate; /* bandwidth rate allocation for VSIs */
};

struct i40e_mdd_vf_events {
u64 count; /* total count of Rx|Tx events */
/* count number of the last printed event */
u64 last_printed;
};

/* VF information structure */
struct i40e_vf {
struct i40e_pf *pf;
Expand Down Expand Up @@ -92,7 +98,9 @@ struct i40e_vf {

u8 num_queue_pairs; /* num of qps assigned to VF vsis */
u8 num_req_queues; /* num of requested qps */
u64 num_mdd_events; /* num of mdd events detected */
/* num of mdd tx and rx events detected */
struct i40e_mdd_vf_events mdd_rx_events;
struct i40e_mdd_vf_events mdd_tx_events;

unsigned long vf_caps; /* vf's adv. capabilities */
unsigned long vf_states; /* vf's runtime states */
Expand Down Expand Up @@ -120,6 +128,7 @@ int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs);
int i40e_vc_process_vf_msg(struct i40e_pf *pf, s16 vf_id, u32 v_opcode,
u32 v_retval, u8 *msg, u16 msglen);
int i40e_vc_process_vflr_event(struct i40e_pf *pf);
void i40e_vc_reset_vf(struct i40e_vf *vf, bool notify_vf);
bool i40e_reset_vf(struct i40e_vf *vf, bool flr);
bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr);
void i40e_vc_notify_vf_reset(struct i40e_vf *vf);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/igb/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ obj-$(CONFIG_IGB) += igb.o

igb-y := igb_main.o igb_ethtool.o e1000_82575.o \
e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o \
e1000_i210.o igb_ptp.o igb_hwmon.o
e1000_i210.o igb_ptp.o igb_hwmon.o igb_xsk.o
Loading

0 comments on commit 7bf1659

Please sign in to comment.