As noted in the subsequent review. After that, hinic3_sw_init()->hinic3_try_to_enable_rss() can shrink max_qps to 1 when alloc_rss_resource() or hinic3_set_hw_rss_parameters() fails: hinic3_rss.c:hinic3_try_to_enable_rss() { ... err = alloc_rss_resource(netdev); if (err) { nic_dev->max_qps = 1; goto err_reset_q_params; } ... } Only hinic3_vport_up() lowers real_num_*_queues, and only on a successful open. A device-scope dump before the first successful open (or after opens that fail before hinic3_vport_up()) still does this: netdev_nl_stats_by_netdev() netdev_stat_queue_sum(netdev, 0, netdev->real_num_rx_queues, &rx_sum, 0, netdev->real_num_tx_queues, &tx_sum); There is no netdev->up check on this path, so i runs from 1 to func_max_qnum - 1 against a one-entry array. Would this read past the end of the rxqs and txqs slab objects and return those values to user space? NETDEV_CMD_QSTATS_GET does not require GENL_ADMIN_PERM, so any local user can issue it. The same applies to nic_dev->txqs[i] in hinic3_get_queue_stats_tx(). Before this patch hinic3 had no stat_ops, and hinic3_get_stats64() bounds its loops by max_qps. This patch also solve some defects reported by checkpatch. Co-developed-by: Wu Di Signed-off-by: Wu Di Co-developed-by: Teng Peisen Signed-off-by: Teng Peisen Signed-off-by: Fan Gong --- .../huawei/hinic3/hinic3_netdev_ops.c | 24 ++++++++++--------- .../net/ethernet/huawei/hinic3/hinic3_rss.c | 11 ++++----- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c index 474ea81f1750..7428c4d98917 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c @@ -251,16 +251,17 @@ static void hinic3_remove_configure(struct net_device *netdev) hinic3_rss_uninit(netdev); } -static int hinic3_alloc_channel_resources(struct net_device *netdev, - struct hinic3_dyna_qp_params *qp_params, - struct hinic3_dyna_txrxq_params *trxq_params) +static int +hinic3_alloc_channel_resources(struct net_device *netdev, + struct hinic3_dyna_qp_params *qp_params, + struct hinic3_dyna_txrxq_params *q_params) { struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); int err; - qp_params->num_qps = trxq_params->num_qps; - qp_params->sq_depth = trxq_params->sq_depth; - qp_params->rq_depth = trxq_params->rq_depth; + qp_params->num_qps = q_params->num_qps; + qp_params->sq_depth = q_params->sq_depth; + qp_params->rq_depth = q_params->rq_depth; err = hinic3_alloc_qps(nic_dev, qp_params); if (err) { @@ -268,7 +269,7 @@ static int hinic3_alloc_channel_resources(struct net_device *netdev, return err; } - err = hinic3_alloc_txrxq_resources(netdev, trxq_params); + err = hinic3_alloc_txrxq_resources(netdev, q_params); if (err) { netdev_err(netdev, "Failed to alloc txrxq resources\n"); hinic3_free_qps(nic_dev, qp_params); @@ -278,13 +279,14 @@ static int hinic3_alloc_channel_resources(struct net_device *netdev, return 0; } -static void hinic3_free_channel_resources(struct net_device *netdev, - struct hinic3_dyna_qp_params *qp_params, - struct hinic3_dyna_txrxq_params *trxq_params) +static void +hinic3_free_channel_resources(struct net_device *netdev, + struct hinic3_dyna_qp_params *qp_params, + struct hinic3_dyna_txrxq_params *q_params) { struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); - hinic3_free_txrxq_resources(netdev, trxq_params); + hinic3_free_txrxq_resources(netdev, q_params); hinic3_free_qps(nic_dev, qp_params); } diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c index 25db74d8c7dd..4aa725339e60 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c @@ -308,14 +308,14 @@ void hinic3_try_to_enable_rss(struct net_device *netdev) nic_dev->max_qps = hinic3_func_max_qnum(hwdev); if (nic_dev->max_qps <= 1 || - !hinic3_test_support(nic_dev, HINIC3_NIC_F_RSS)) + !hinic3_test_support(nic_dev, HINIC3_NIC_F_RSS)) { + nic_dev->max_qps = 1; goto err_reset_q_params; + } err = alloc_rss_resource(netdev); - if (err) { - nic_dev->max_qps = 1; + if (err) goto err_reset_q_params; - } set_bit(HINIC3_RSS_ENABLE, &nic_dev->flags); decide_num_qps(netdev); @@ -324,7 +324,6 @@ void hinic3_try_to_enable_rss(struct net_device *netdev) if (err) { dev_err(hwdev->dev, "Failed to set hardware rss parameters\n"); hinic3_clear_rss_config(netdev); - nic_dev->max_qps = 1; goto err_reset_q_params; } @@ -332,5 +331,5 @@ void hinic3_try_to_enable_rss(struct net_device *netdev) err_reset_q_params: clear_bit(HINIC3_RSS_ENABLE, &nic_dev->flags); - nic_dev->q_params.num_qps = nic_dev->max_qps; + nic_dev->q_params.num_qps = 1; } -- 2.43.0