Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue

Tony Nguyen says:

====================
For ice:
Michal corrects call to alloc_etherdev_mqs() to provide maximum number
of queues supported rather than currently allocated number of queues.

Petr Oros fixes issues related to some ethtool operations in switchdev
mode.

For iavf:
Kohei Enju corrects number of reported queues for ethtool statistics to
absolute max as using current number could race and cause out-of-bounds
issues.

For idpf:
Josh NULLs cdev_info pointer after freeing to prevent possible subsequent
improper access. He also defers setting of refillqs value until after
allocation to prevent possible NULL pointer dereference.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue:
  idpf: only assign num refillqs if allocation was successful
  idpf: clear stale cdev_info ptr
  iavf: fix out-of-bounds writes in iavf_get_ethtool_stats()
  ice: use ice_update_eth_stats() for representor stats
  ice: fix inverted ready check for VF representors
  ice: set max queues in alloc_etherdev_mqs()
====================

Link: https://patch.msgid.link/20260323205843.624704-1-anthony.l.nguyen@intel.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Paolo Abeni
2026-03-26 15:14:51 +01:00
9 changed files with 60 additions and 46 deletions

View File

@@ -313,14 +313,13 @@ static int iavf_get_sset_count(struct net_device *netdev, int sset)
{
/* Report the maximum number queues, even if not every queue is
* currently configured. Since allocation of queues is in pairs,
* use netdev->real_num_tx_queues * 2. The real_num_tx_queues is set
* at device creation and never changes.
* use netdev->num_tx_queues * 2. The num_tx_queues is set at
* device creation and never changes.
*/
if (sset == ETH_SS_STATS)
return IAVF_STATS_LEN +
(IAVF_QUEUE_STATS_LEN * 2 *
netdev->real_num_tx_queues);
(IAVF_QUEUE_STATS_LEN * 2 * netdev->num_tx_queues);
else
return -EINVAL;
}
@@ -345,19 +344,19 @@ static void iavf_get_ethtool_stats(struct net_device *netdev,
iavf_add_ethtool_stats(&data, adapter, iavf_gstrings_stats);
rcu_read_lock();
/* As num_active_queues describe both tx and rx queues, we can use
* it to iterate over rings' stats.
/* Use num_tx_queues to report stats for the maximum number of queues.
* Queues beyond num_active_queues will report zero.
*/
for (i = 0; i < adapter->num_active_queues; i++) {
struct iavf_ring *ring;
for (i = 0; i < netdev->num_tx_queues; i++) {
struct iavf_ring *tx_ring = NULL, *rx_ring = NULL;
/* Tx rings stats */
ring = &adapter->tx_rings[i];
iavf_add_queue_stats(&data, ring);
if (i < adapter->num_active_queues) {
tx_ring = &adapter->tx_rings[i];
rx_ring = &adapter->rx_rings[i];
}
/* Rx rings stats */
ring = &adapter->rx_rings[i];
iavf_add_queue_stats(&data, ring);
iavf_add_queue_stats(&data, tx_ring);
iavf_add_queue_stats(&data, rx_ring);
}
rcu_read_unlock();
}
@@ -376,9 +375,9 @@ static void iavf_get_stat_strings(struct net_device *netdev, u8 *data)
iavf_add_stat_strings(&data, iavf_gstrings_stats);
/* Queues are always allocated in pairs, so we just use
* real_num_tx_queues for both Tx and Rx queues.
* num_tx_queues for both Tx and Rx queues.
*/
for (i = 0; i < netdev->real_num_tx_queues; i++) {
for (i = 0; i < netdev->num_tx_queues; i++) {
iavf_add_stat_strings(&data, iavf_gstrings_queue_stats,
"tx", i);
iavf_add_stat_strings(&data, iavf_gstrings_queue_stats,

View File

@@ -839,6 +839,28 @@ static inline void ice_tx_xsk_pool(struct ice_vsi *vsi, u16 qid)
WRITE_ONCE(ring->xsk_pool, ice_get_xp_from_qid(vsi, qid));
}
/**
* ice_get_max_txq - return the maximum number of Tx queues for in a PF
* @pf: PF structure
*
* Return: maximum number of Tx queues
*/
static inline int ice_get_max_txq(struct ice_pf *pf)
{
return min(num_online_cpus(), pf->hw.func_caps.common_cap.num_txq);
}
/**
* ice_get_max_rxq - return the maximum number of Rx queues for in a PF
* @pf: PF structure
*
* Return: maximum number of Rx queues
*/
static inline int ice_get_max_rxq(struct ice_pf *pf)
{
return min(num_online_cpus(), pf->hw.func_caps.common_cap.num_rxq);
}
/**
* ice_get_main_vsi - Get the PF VSI
* @pf: PF instance

View File

@@ -1930,6 +1930,17 @@ __ice_get_ethtool_stats(struct net_device *netdev,
int i = 0;
char *p;
if (ice_is_port_repr_netdev(netdev)) {
ice_update_eth_stats(vsi);
for (j = 0; j < ICE_VSI_STATS_LEN; j++) {
p = (char *)vsi + ice_gstrings_vsi_stats[j].stat_offset;
data[i++] = (ice_gstrings_vsi_stats[j].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
return;
}
ice_update_pf_stats(pf);
ice_update_vsi_stats(vsi);
@@ -1939,9 +1950,6 @@ __ice_get_ethtool_stats(struct net_device *netdev,
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
if (ice_is_port_repr_netdev(netdev))
return;
/* populate per queue stats */
rcu_read_lock();
@@ -3773,24 +3781,6 @@ ice_get_ts_info(struct net_device *dev, struct kernel_ethtool_ts_info *info)
return 0;
}
/**
* ice_get_max_txq - return the maximum number of Tx queues for in a PF
* @pf: PF structure
*/
static int ice_get_max_txq(struct ice_pf *pf)
{
return min(num_online_cpus(), pf->hw.func_caps.common_cap.num_txq);
}
/**
* ice_get_max_rxq - return the maximum number of Rx queues for in a PF
* @pf: PF structure
*/
static int ice_get_max_rxq(struct ice_pf *pf)
{
return min(num_online_cpus(), pf->hw.func_caps.common_cap.num_rxq);
}
/**
* ice_get_combined_cnt - return the current number of combined channels
* @vsi: PF VSI pointer

View File

@@ -4699,8 +4699,8 @@ static int ice_cfg_netdev(struct ice_vsi *vsi)
struct net_device *netdev;
u8 mac_addr[ETH_ALEN];
netdev = alloc_etherdev_mqs(sizeof(*np), vsi->alloc_txq,
vsi->alloc_rxq);
netdev = alloc_etherdev_mqs(sizeof(*np), ice_get_max_txq(vsi->back),
ice_get_max_rxq(vsi->back));
if (!netdev)
return -ENOMEM;

View File

@@ -2,6 +2,7 @@
/* Copyright (C) 2019-2021, Intel Corporation. */
#include "ice.h"
#include "ice_lib.h"
#include "ice_eswitch.h"
#include "devlink/devlink.h"
#include "devlink/port.h"
@@ -67,7 +68,7 @@ ice_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
return;
vsi = repr->src_vsi;
ice_update_vsi_stats(vsi);
ice_update_eth_stats(vsi);
eth_stats = &vsi->eth_stats;
stats->tx_packets = eth_stats->tx_unicast + eth_stats->tx_broadcast +
@@ -315,7 +316,7 @@ ice_repr_reg_netdev(struct net_device *netdev, const struct net_device_ops *ops)
static int ice_repr_ready_vf(struct ice_repr *repr)
{
return !ice_check_vf_ready_for_cfg(repr->vf);
return ice_check_vf_ready_for_cfg(repr->vf);
}
static int ice_repr_ready_sf(struct ice_repr *repr)

View File

@@ -1066,7 +1066,7 @@ bool idpf_vport_set_hsplit(const struct idpf_vport *vport, u8 val);
int idpf_idc_init(struct idpf_adapter *adapter);
int idpf_idc_init_aux_core_dev(struct idpf_adapter *adapter,
enum iidc_function_type ftype);
void idpf_idc_deinit_core_aux_device(struct iidc_rdma_core_dev_info *cdev_info);
void idpf_idc_deinit_core_aux_device(struct idpf_adapter *adapter);
void idpf_idc_deinit_vport_aux_device(struct iidc_rdma_vport_dev_info *vdev_info);
void idpf_idc_issue_reset_event(struct iidc_rdma_core_dev_info *cdev_info);
void idpf_idc_vdev_mtu_event(struct iidc_rdma_vport_dev_info *vdev_info,

View File

@@ -470,10 +470,11 @@ err_privd_alloc:
/**
* idpf_idc_deinit_core_aux_device - de-initialize Auxiliary Device(s)
* @cdev_info: IDC core device info pointer
* @adapter: driver private data structure
*/
void idpf_idc_deinit_core_aux_device(struct iidc_rdma_core_dev_info *cdev_info)
void idpf_idc_deinit_core_aux_device(struct idpf_adapter *adapter)
{
struct iidc_rdma_core_dev_info *cdev_info = adapter->cdev_info;
struct iidc_rdma_priv_dev_info *privd;
if (!cdev_info)
@@ -485,6 +486,7 @@ void idpf_idc_deinit_core_aux_device(struct iidc_rdma_core_dev_info *cdev_info)
kfree(privd->mapped_mem_regions);
kfree(privd);
kfree(cdev_info);
adapter->cdev_info = NULL;
}
/**

View File

@@ -1860,13 +1860,13 @@ static int idpf_rxq_group_alloc(struct idpf_vport *vport,
idpf_queue_assign(HSPLIT_EN, q, hs);
idpf_queue_assign(RSC_EN, q, rsc);
bufq_set->num_refillqs = num_rxq;
bufq_set->refillqs = kcalloc(num_rxq, swq_size,
GFP_KERNEL);
if (!bufq_set->refillqs) {
err = -ENOMEM;
goto err_alloc;
}
bufq_set->num_refillqs = num_rxq;
for (unsigned int k = 0; k < bufq_set->num_refillqs; k++) {
struct idpf_sw_queue *refillq =
&bufq_set->refillqs[k];

View File

@@ -3668,7 +3668,7 @@ void idpf_vc_core_deinit(struct idpf_adapter *adapter)
idpf_ptp_release(adapter);
idpf_deinit_task(adapter);
idpf_idc_deinit_core_aux_device(adapter->cdev_info);
idpf_idc_deinit_core_aux_device(adapter);
idpf_rel_rx_pt_lkup(adapter);
idpf_intr_rel(adapter);