[PATCH v8 16/17] net/nbl: add nbl device xstats and stats

Stephen Hemminger stephen at networkplumber.org
Fri Sep 12 17:13:31 CEST 2025


On Thu, 11 Sep 2025 23:17:51 -0700
Dimon Zhao <dimon.zhao at nebula-matrix.com> wrote:

> +static int nbl_dev_update_hw_xstats(struct nbl_dev_mgt *dev_mgt, struct rte_eth_xstat *xstats,
> +				    u16 hw_xstats_cnt, u16 *xstats_cnt)
> +{
> +	struct nbl_dev_net_mgt *net_dev = dev_mgt->net_dev;
> +	struct nbl_common_info *common = NBL_DEV_MGT_TO_COMMON(dev_mgt);
> +	struct nbl_dispatch_ops *disp_ops = NBL_DEV_MGT_TO_DISP_OPS(dev_mgt);
> +	int i;
> +	u16 count = *xstats_cnt;
> +
> +	disp_ops->get_private_stat_data(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
> +					common->eth_id, net_dev->hw_xstats,
> +					net_dev->hw_xstats_size);
> +	for (i = 0; i < hw_xstats_cnt; i++) {
> +		xstats[count].value = net_dev->hw_xstats[i] - dev_mgt->net_dev->hw_xstats_offset[i];
> +		xstats[count].id = count;
> +		count++;
> +	}
> +
> +	*xstats_cnt = count;
> +	return 0;
> +}
> +
> +int nbl_xstats_get(struct rte_eth_dev *eth_dev, struct rte_eth_xstat *xstats, unsigned int n)
> +{
> +	struct nbl_adapter *adapter = ETH_DEV_TO_NBL_DEV_PF_PRIV(eth_dev);
> +	struct nbl_dev_mgt *dev_mgt = NBL_ADAPTER_TO_DEV_MGT(adapter);
> +	struct nbl_common_info *common = NBL_DEV_MGT_TO_COMMON(dev_mgt);
> +	struct nbl_dispatch_ops *disp_ops = NBL_DEV_MGT_TO_DISP_OPS(dev_mgt);
> +	int ret = 0;
> +	u16 txrx_xstats_cnt = 0, hw_xstats_cnt = 0, xstats_cnt = 0;
> +
> +	if (!xstats)
> +		return 0;
> +
> +	ret = disp_ops->get_txrx_xstats_cnt(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), &txrx_xstats_cnt);
> +	if (!common->is_vf)
> +		ret |= disp_ops->get_hw_xstats_cnt(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
> +						   &hw_xstats_cnt);
> +	if (ret)
> +		return -EIO;
> +
> +	if (n < (txrx_xstats_cnt + hw_xstats_cnt))
> +		return txrx_xstats_cnt + hw_xstats_cnt;
> +
> +	if (txrx_xstats_cnt)
> +		ret = disp_ops->get_txrx_xstats(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
> +						xstats, &xstats_cnt);
> +	if (hw_xstats_cnt)
> +		ret |= nbl_dev_update_hw_xstats(dev_mgt, xstats, hw_xstats_cnt, &xstats_cnt);
> +
> +	if (ret)
> +		return -EIO;
> +
> +	return xstats_cnt;
> +}
> +
> +int nbl_xstats_get_names(struct rte_eth_dev *eth_dev,
> +			 struct rte_eth_xstat_name *xstats_names,
> +			 __rte_unused unsigned int limit)
> +{
> +	struct nbl_adapter *adapter = ETH_DEV_TO_NBL_DEV_PF_PRIV(eth_dev);
> +	struct nbl_dev_mgt *dev_mgt = NBL_ADAPTER_TO_DEV_MGT(adapter);
> +	struct nbl_common_info *common = NBL_DEV_MGT_TO_COMMON(dev_mgt);
> +	struct nbl_dispatch_ops *disp_ops = NBL_DEV_MGT_TO_DISP_OPS(dev_mgt);
> +	u16 txrx_xstats_cnt = 0, hw_xstats_cnt = 0, xstats_cnt = 0;
> +	int ret = 0;
> +
> +	ret = disp_ops->get_txrx_xstats_cnt(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), &txrx_xstats_cnt);
> +	if (!common->is_vf)
> +		ret |= disp_ops->get_hw_xstats_cnt(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
> +							&hw_xstats_cnt);
> +	if (ret)
> +		return -EIO;
> +
> +	if (!xstats_names)
> +		return txrx_xstats_cnt + hw_xstats_cnt;
> +
> +	if (txrx_xstats_cnt)
> +		ret = disp_ops->get_txrx_xstats_names(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
> +						      xstats_names, &xstats_cnt);
> +	if (hw_xstats_cnt)
> +		ret |= disp_ops->get_hw_xstats_names(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
> +						     xstats_names, &xstats_cnt);
> +	if (ret)
> +		return -EIO;
> +
> +	return xstats_cnt;
> +}
> +

You need to check the limit value.
The API is designed so that application is allowed to request only a subset
of the counters.


More information about the dev mailing list