Re: [PATCH net-next v03 1/6] hinic3: Add ethtool queue ops

From: Mohsin Bashir

Date: Wed Apr 01 2026 - 03:53:02 EST



+static int hinic3_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring,
+ struct kernel_ethtool_ringparam *kernel_ring,
+ struct netlink_ext_ack *extack)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dyna_txrxq_params q_params = {};
+ u32 new_sq_depth, new_rq_depth;
+ int err;
+
+ err = hinic3_check_ringparam_valid(netdev, ring);
+ if (err)
+ return err;
+
+ new_sq_depth = 1U << ilog2(ring->tx_pending);
+ new_rq_depth = 1U << ilog2(ring->rx_pending);
+ if (new_sq_depth == nic_dev->q_params.sq_depth &&
+ new_rq_depth == nic_dev->q_params.rq_depth)
+ return 0;
+

So non power of 2 values would trimmed to the nearest power of 2 even when the driver support these values. If such values are not supported, should these be rejected here? or if we want to force the nearest power of 2, should we use NL_SET_ERR_MSG to inform the user about rounding?

+int
+hinic3_change_channel_settings(struct net_device *netdev,
+ struct hinic3_dyna_txrxq_params *trxq_params)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dyna_qp_params new_qp_params = {};
+ struct hinic3_dyna_qp_params cur_qp_params = {};
+ bool need_teardown = false;
+ unsigned long flags;
+ int err;
+
+ mutex_lock(&nic_dev->channel_cfg_lock);
+
+ hinic3_config_num_qps(netdev, trxq_params);
+
+ err = hinic3_alloc_channel_resources(netdev, &new_qp_params,
+ trxq_params);
+ if (err) {
+ netdev_err(netdev, "Failed to alloc channel resources\n");
+ mutex_unlock(&nic_dev->channel_cfg_lock);
+ return err;
+ }
+
+ spin_lock_irqsave(&nic_dev->channel_res_lock, flags);
+ if (!test_and_set_bit(HINIC3_CHANGE_RES_INVALID, &nic_dev->flags))
+ need_teardown = true;
+ spin_unlock_irqrestore(&nic_dev->channel_res_lock, flags);
+
+ if (need_teardown) {
+ hinic3_vport_down(netdev);
+ hinic3_close_channel(netdev);
+ hinic3_uninit_qps(nic_dev, &cur_qp_params);
+ hinic3_free_channel_resources(netdev, &cur_qp_params,
+ &nic_dev->q_params);
+ }
+
+ if (nic_dev->num_qp_irq > trxq_params->num_qps)
+ hinic3_qp_irq_change(netdev, trxq_params->num_qps);
+
+ spin_lock_irqsave(&nic_dev->channel_res_lock, flags);
+ nic_dev->q_params = *trxq_params;

[1] Here we are overwriting the old parameters
+ spin_unlock_irqrestore(&nic_dev->channel_res_lock, flags);
+
+ hinic3_init_qps(nic_dev, &new_qp_params);
+
+ err = hinic3_open_channel(netdev);
+ if (err)
+ goto err_uninit_qps;
+
+ err = hinic3_vport_up(netdev);
+ if (err)
+ goto err_close_channel;
+
+ spin_lock_irqsave(&nic_dev->channel_res_lock, flags);
+ clear_bit(HINIC3_CHANGE_RES_INVALID, &nic_dev->flags);
+ spin_unlock_irqrestore(&nic_dev->channel_res_lock, flags);
+
+ mutex_unlock(&nic_dev->channel_cfg_lock);
+
+ return 0;
+
+err_close_channel:
+ hinic3_close_channel(netdev);
+err_uninit_qps:
+ spin_lock_irqsave(&nic_dev->channel_res_lock, flags);
+ memset(&nic_dev->q_params, 0, sizeof(nic_dev->q_params));

Looks like we are asking for trouble here. The old parameters were already overwritten at [1] and now we are destroying the new ones?

+ spin_unlock_irqrestore(&nic_dev->channel_res_lock, flags);
+
+ hinic3_uninit_qps(nic_dev, &new_qp_params);
+ hinic3_free_channel_resources(netdev, &new_qp_params, trxq_params);
+
+ mutex_unlock(&nic_dev->channel_cfg_lock);
+
+ return err;
+}
+