Commit deec4f7b authored by Paolo Abeni's avatar Paolo Abeni
Browse files
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: default avatarPaolo Abeni <pabeni@redhat.com>
parents 72d96e4e b5e5797e
Loading
Loading
Loading
Loading
+15 −16
Original line number Diff line number Diff line
@@ -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,
+22 −0
Original line number Diff line number Diff line
@@ -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
+11 −21
Original line number Diff line number Diff line
@@ -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
+2 −2
Original line number Diff line number Diff line
@@ -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;

+3 −2
Original line number Diff line number Diff line
@@ -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)
Loading