Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-migrate-remaining-drivers-to-dedicated-_rxfh_context-ops'

Jakub Kicinski says:

====================
net: migrate remaining drivers to dedicated _rxfh_context ops

Around a year ago Ed added dedicated ops for managing RSS contexts.
This significantly improved the clarity of the driver facing API.
Migrate the remaining 3 drivers and remove the old way of muxing
the RSS context operations via .set_rxfh().

v2: https://lore.kernel.org/20250702030606.1776293-1-kuba@kernel.org
v1: https://lore.kernel.org/20250630160953.1093267-1-kuba@kernel.org
====================

Link: https://patch.msgid.link/20250707184115.2285277-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+250 -265
+3 -25
drivers/net/ethernet/intel/ice/ice_ethtool.c
··· 3591 3591 ice_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh) 3592 3592 { 3593 3593 struct ice_netdev_priv *np = netdev_priv(netdev); 3594 - u32 rss_context = rxfh->rss_context; 3595 3594 struct ice_vsi *vsi = np->vsi; 3596 3595 struct ice_pf *pf = vsi->back; 3597 3596 u16 qcount, offset; 3598 - int err, num_tc, i; 3597 + int err, i; 3599 3598 u8 *lut; 3600 3599 3601 3600 if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { ··· 3602 3603 return -EOPNOTSUPP; 3603 3604 } 3604 3605 3605 - if (rss_context && !ice_is_adq_active(pf)) { 3606 - netdev_err(netdev, "RSS context cannot be non-zero when ADQ is not configured.\n"); 3607 - return -EINVAL; 3608 - } 3609 - 3610 - qcount = vsi->mqprio_qopt.qopt.count[rss_context]; 3611 - offset = vsi->mqprio_qopt.qopt.offset[rss_context]; 3612 - 3613 - if (rss_context && ice_is_adq_active(pf)) { 3614 - num_tc = vsi->mqprio_qopt.qopt.num_tc; 3615 - if (rss_context >= num_tc) { 3616 - netdev_err(netdev, "RSS context:%d > num_tc:%d\n", 3617 - rss_context, num_tc); 3618 - return -EINVAL; 3619 - } 3620 - /* Use channel VSI of given TC */ 3621 - vsi = vsi->tc_map_vsi[rss_context]; 3622 - } 3606 + qcount = vsi->mqprio_qopt.qopt.count[0]; 3607 + offset = vsi->mqprio_qopt.qopt.offset[0]; 3623 3608 3624 3609 rxfh->hfunc = ETH_RSS_HASH_TOP; 3625 3610 if (vsi->rss_hfunc == ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ) ··· 3661 3678 dev = ice_pf_to_dev(pf); 3662 3679 if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && 3663 3680 rxfh->hfunc != ETH_RSS_HASH_TOP) 3664 - return -EOPNOTSUPP; 3665 - 3666 - if (rxfh->rss_context) 3667 3681 return -EOPNOTSUPP; 3668 3682 3669 3683 if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { ··· 4730 4750 } 4731 4751 4732 4752 static const struct ethtool_ops ice_ethtool_ops = { 4733 - .cap_rss_ctx_supported = true, 4734 4753 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 4735 4754 ETHTOOL_COALESCE_USE_ADAPTIVE | 4736 4755 ETHTOOL_COALESCE_RX_USECS_HIGH, 4737 4756 .supported_input_xfrm = RXH_XFRM_SYM_XOR, 4738 - .rxfh_per_ctx_key = true, 4739 4757 .get_link_ksettings = ice_get_link_ksettings, 4740 4758 .set_link_ksettings = ice_set_link_ksettings, 4741 4759 .get_fec_stats = ice_get_fec_stats,
+9 -18
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
··· 318 318 return err; 319 319 } 320 320 321 - int otx2_set_rss_table(struct otx2_nic *pfvf, int ctx_id) 321 + int otx2_set_rss_table(struct otx2_nic *pfvf, int ctx_id, const u32 *ind_tbl) 322 322 { 323 323 struct otx2_rss_info *rss = &pfvf->hw.rss_info; 324 324 const int index = rss->rss_size * ctx_id; 325 325 struct mbox *mbox = &pfvf->mbox; 326 - struct otx2_rss_ctx *rss_ctx; 327 326 struct nix_aq_enq_req *aq; 328 327 int idx, err; 329 328 330 329 mutex_lock(&mbox->lock); 331 - rss_ctx = rss->rss_ctx[ctx_id]; 330 + ind_tbl = ind_tbl ?: rss->ind_tbl; 332 331 /* Get memory to put this msg */ 333 332 for (idx = 0; idx < rss->rss_size; idx++) { 334 333 /* Ignore the queue if AF_XDP zero copy is enabled */ 335 - if (test_bit(rss_ctx->ind_tbl[idx], pfvf->af_xdp_zc_qidx)) 334 + if (test_bit(ind_tbl[idx], pfvf->af_xdp_zc_qidx)) 336 335 continue; 337 336 338 337 aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox); ··· 351 352 } 352 353 } 353 354 354 - aq->rss.rq = rss_ctx->ind_tbl[idx]; 355 + aq->rss.rq = ind_tbl[idx]; 355 356 356 357 /* Fill AQ info */ 357 358 aq->qidx = index + idx; ··· 389 390 int otx2_rss_init(struct otx2_nic *pfvf) 390 391 { 391 392 struct otx2_rss_info *rss = &pfvf->hw.rss_info; 392 - struct otx2_rss_ctx *rss_ctx; 393 393 int idx, ret = 0; 394 394 395 - rss->rss_size = sizeof(*rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP]); 395 + rss->rss_size = sizeof(*rss->ind_tbl); 396 396 397 397 /* Init RSS key if it is not setup already */ 398 398 if (!rss->enable) 399 399 netdev_rss_key_fill(rss->key, sizeof(rss->key)); 400 400 otx2_set_rss_key(pfvf); 401 401 402 - if (!netif_is_rxfh_configured(pfvf->netdev)) { 403 - /* Set RSS group 0 as default indirection table */ 404 - rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP] = kzalloc(rss->rss_size, 405 - GFP_KERNEL); 406 - if (!rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP]) 407 - return -ENOMEM; 408 - 409 - rss_ctx = rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP]; 402 + if (!netif_is_rxfh_configured(pfvf->netdev)) 410 403 for (idx = 0; idx < rss->rss_size; idx++) 411 - rss_ctx->ind_tbl[idx] = 404 + rss->ind_tbl[idx] = 412 405 ethtool_rxfh_indir_default(idx, 413 406 pfvf->hw.rx_queues); 414 - } 415 - ret = otx2_set_rss_table(pfvf, DEFAULT_RSS_CONTEXT_GROUP); 407 + 408 + ret = otx2_set_rss_table(pfvf, DEFAULT_RSS_CONTEXT_GROUP, NULL); 416 409 if (ret) 417 410 return ret; 418 411
+2 -6
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
··· 93 93 u64 lmt_addr; 94 94 u16 lmt_id; 95 95 }; 96 - /* RSS configuration */ 97 - struct otx2_rss_ctx { 98 - u8 ind_tbl[MAX_RSS_INDIR_TBL_SIZE]; 99 - }; 100 96 101 97 struct otx2_rss_info { 102 98 u8 enable; ··· 100 104 u16 rss_size; 101 105 #define RSS_HASH_KEY_SIZE 44 /* 352 bit key */ 102 106 u8 key[RSS_HASH_KEY_SIZE]; 103 - struct otx2_rss_ctx *rss_ctx[MAX_RSS_GROUPS]; 107 + u32 ind_tbl[MAX_RSS_INDIR_TBL_SIZE]; 104 108 }; 105 109 106 110 /* NIX (or NPC) RX errors */ ··· 1063 1067 int otx2_rss_init(struct otx2_nic *pfvf); 1064 1068 int otx2_set_flowkey_cfg(struct otx2_nic *pfvf); 1065 1069 void otx2_set_rss_key(struct otx2_nic *pfvf); 1066 - int otx2_set_rss_table(struct otx2_nic *pfvf, int ctx_id); 1070 + int otx2_set_rss_table(struct otx2_nic *pfvf, int ctx_id, const u32 *ind_tbl); 1067 1071 1068 1072 /* Mbox handlers */ 1069 1073 void mbox_handler_msix_offset(struct otx2_nic *pfvf,
+76 -61
drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
··· 796 796 return MAX_RSS_INDIR_TBL_SIZE; 797 797 } 798 798 799 - static int otx2_rss_ctx_delete(struct otx2_nic *pfvf, int ctx_id) 799 + static int otx2_create_rxfh(struct net_device *dev, 800 + struct ethtool_rxfh_context *ctx, 801 + const struct ethtool_rxfh_param *rxfh, 802 + struct netlink_ext_ack *extack) 800 803 { 801 - struct otx2_rss_info *rss = &pfvf->hw.rss_info; 804 + struct otx2_nic *pfvf = netdev_priv(dev); 805 + struct otx2_rss_info *rss; 806 + unsigned int queues; 807 + u32 *ind_tbl; 808 + int idx; 802 809 803 - otx2_rss_ctx_flow_del(pfvf, ctx_id); 804 - kfree(rss->rss_ctx[ctx_id]); 805 - rss->rss_ctx[ctx_id] = NULL; 810 + rss = &pfvf->hw.rss_info; 811 + queues = pfvf->hw.rx_queues; 812 + 813 + if (rxfh->hfunc && rxfh->hfunc != ETH_RSS_HASH_TOP) 814 + return -EOPNOTSUPP; 815 + ctx->hfunc = ETH_RSS_HASH_TOP; 816 + 817 + if (!rss->enable) { 818 + netdev_err(dev, "RSS is disabled, cannot change settings\n"); 819 + return -EIO; 820 + } 821 + 822 + ind_tbl = rxfh->indir; 823 + if (!ind_tbl) { 824 + ind_tbl = ethtool_rxfh_context_indir(ctx); 825 + for (idx = 0; idx < rss->rss_size; idx++) 826 + ind_tbl[idx] = ethtool_rxfh_indir_default(idx, queues); 827 + } 828 + 829 + otx2_set_rss_table(pfvf, rxfh->rss_context, ind_tbl); 830 + return 0; 831 + } 832 + 833 + static int otx2_modify_rxfh(struct net_device *dev, 834 + struct ethtool_rxfh_context *ctx, 835 + const struct ethtool_rxfh_param *rxfh, 836 + struct netlink_ext_ack *extack) 837 + { 838 + struct otx2_nic *pfvf = netdev_priv(dev); 839 + 840 + if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && 841 + rxfh->hfunc != ETH_RSS_HASH_TOP) 842 + return -EOPNOTSUPP; 843 + 844 + if (!pfvf->hw.rss_info.enable) { 845 + netdev_err(dev, "RSS is disabled, cannot change settings\n"); 846 + return -EIO; 847 + } 848 + 849 + if (rxfh->indir) 850 + otx2_set_rss_table(pfvf, rxfh->rss_context, rxfh->indir); 806 851 807 852 return 0; 808 853 } 809 854 810 - static int otx2_rss_ctx_create(struct otx2_nic *pfvf, 811 - u32 *rss_context) 855 + static int otx2_remove_rxfh(struct net_device *dev, 856 + struct ethtool_rxfh_context *ctx, 857 + u32 rss_context, 858 + struct netlink_ext_ack *extack) 812 859 { 813 - struct otx2_rss_info *rss = &pfvf->hw.rss_info; 814 - u8 ctx; 860 + struct otx2_nic *pfvf = netdev_priv(dev); 815 861 816 - for (ctx = 0; ctx < MAX_RSS_GROUPS; ctx++) { 817 - if (!rss->rss_ctx[ctx]) 818 - break; 862 + if (!pfvf->hw.rss_info.enable) { 863 + netdev_err(dev, "RSS is disabled, cannot change settings\n"); 864 + return -EIO; 819 865 } 820 - if (ctx == MAX_RSS_GROUPS) 821 - return -EINVAL; 822 866 823 - rss->rss_ctx[ctx] = kzalloc(sizeof(*rss->rss_ctx[ctx]), GFP_KERNEL); 824 - if (!rss->rss_ctx[ctx]) 825 - return -ENOMEM; 826 - *rss_context = ctx; 827 - 867 + otx2_rss_ctx_flow_del(pfvf, rss_context); 828 868 return 0; 829 869 } 830 870 ··· 873 833 struct ethtool_rxfh_param *rxfh, 874 834 struct netlink_ext_ack *extack) 875 835 { 876 - u32 rss_context = DEFAULT_RSS_CONTEXT_GROUP; 877 836 struct otx2_nic *pfvf = netdev_priv(dev); 878 - struct otx2_rss_ctx *rss_ctx; 879 837 struct otx2_rss_info *rss; 880 - int ret, idx; 838 + int idx; 881 839 882 840 if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && 883 841 rxfh->hfunc != ETH_RSS_HASH_TOP) 884 842 return -EOPNOTSUPP; 885 - 886 - if (rxfh->rss_context) 887 - rss_context = rxfh->rss_context; 888 - 889 - if (rss_context != ETH_RXFH_CONTEXT_ALLOC && 890 - rss_context >= MAX_RSS_GROUPS) 891 - return -EINVAL; 892 843 893 844 rss = &pfvf->hw.rss_info; 894 845 ··· 892 861 memcpy(rss->key, rxfh->key, sizeof(rss->key)); 893 862 otx2_set_rss_key(pfvf); 894 863 } 895 - if (rxfh->rss_delete) 896 - return otx2_rss_ctx_delete(pfvf, rss_context); 897 864 898 - if (rss_context == ETH_RXFH_CONTEXT_ALLOC) { 899 - ret = otx2_rss_ctx_create(pfvf, &rss_context); 900 - rxfh->rss_context = rss_context; 901 - if (ret) 902 - return ret; 903 - } 904 865 if (rxfh->indir) { 905 - rss_ctx = rss->rss_ctx[rss_context]; 906 866 for (idx = 0; idx < rss->rss_size; idx++) 907 - rss_ctx->ind_tbl[idx] = rxfh->indir[idx]; 867 + rss->ind_tbl[idx] = rxfh->indir[idx]; 908 868 } 909 - otx2_set_rss_table(pfvf, rss_context); 869 + otx2_set_rss_table(pfvf, DEFAULT_RSS_CONTEXT_GROUP, NULL); 910 870 911 871 return 0; 912 872 } ··· 906 884 static int otx2_get_rxfh(struct net_device *dev, 907 885 struct ethtool_rxfh_param *rxfh) 908 886 { 909 - u32 rss_context = DEFAULT_RSS_CONTEXT_GROUP; 910 887 struct otx2_nic *pfvf = netdev_priv(dev); 911 - struct otx2_rss_ctx *rss_ctx; 912 888 struct otx2_rss_info *rss; 913 889 u32 *indir = rxfh->indir; 914 890 int idx, rx_queues; ··· 914 894 rss = &pfvf->hw.rss_info; 915 895 916 896 rxfh->hfunc = ETH_RSS_HASH_TOP; 917 - if (rxfh->rss_context) 918 - rss_context = rxfh->rss_context; 919 - 920 897 if (!indir) 921 898 return 0; 922 899 923 - if (!rss->enable && rss_context == DEFAULT_RSS_CONTEXT_GROUP) { 900 + if (!rss->enable) { 924 901 rx_queues = pfvf->hw.rx_queues; 925 902 for (idx = 0; idx < MAX_RSS_INDIR_TBL_SIZE; idx++) 926 903 indir[idx] = ethtool_rxfh_indir_default(idx, rx_queues); 927 904 return 0; 928 905 } 929 - if (rss_context >= MAX_RSS_GROUPS) 930 - return -ENOENT; 931 906 932 - rss_ctx = rss->rss_ctx[rss_context]; 933 - if (!rss_ctx) 934 - return -ENOENT; 935 - 936 - if (indir) { 937 - for (idx = 0; idx < rss->rss_size; idx++) { 938 - /* Ignore if the rx queue is AF_XDP zero copy enabled */ 939 - if (test_bit(rss_ctx->ind_tbl[idx], pfvf->af_xdp_zc_qidx)) 940 - continue; 941 - indir[idx] = rss_ctx->ind_tbl[idx]; 942 - } 907 + for (idx = 0; idx < rss->rss_size; idx++) { 908 + /* Ignore if the rx queue is AF_XDP zero copy enabled */ 909 + if (test_bit(rss->ind_tbl[idx], pfvf->af_xdp_zc_qidx)) 910 + continue; 911 + indir[idx] = rss->ind_tbl[idx]; 943 912 } 944 913 if (rxfh->key) 945 914 memcpy(rxfh->key, rss->key, sizeof(rss->key)); ··· 1316 1307 } 1317 1308 1318 1309 static const struct ethtool_ops otx2_ethtool_ops = { 1319 - .cap_rss_ctx_supported = true, 1320 1310 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 1321 1311 ETHTOOL_COALESCE_MAX_FRAMES | 1322 1312 ETHTOOL_COALESCE_USE_ADAPTIVE, 1323 1313 .supported_ring_params = ETHTOOL_RING_USE_RX_BUF_LEN | 1324 1314 ETHTOOL_RING_USE_CQE_SIZE, 1315 + .rxfh_max_num_contexts = MAX_RSS_GROUPS, 1325 1316 .get_link = otx2_get_link, 1326 1317 .get_drvinfo = otx2_get_drvinfo, 1327 1318 .get_strings = otx2_get_strings, ··· 1341 1332 .set_rxfh = otx2_set_rxfh, 1342 1333 .get_rxfh_fields = otx2_get_rss_hash_opts, 1343 1334 .set_rxfh_fields = otx2_set_rss_hash_opts, 1335 + .create_rxfh_context = otx2_create_rxfh, 1336 + .modify_rxfh_context = otx2_modify_rxfh, 1337 + .remove_rxfh_context = otx2_remove_rxfh, 1344 1338 .get_msglevel = otx2_get_msglevel, 1345 1339 .set_msglevel = otx2_set_msglevel, 1346 1340 .get_pauseparam = otx2_get_pauseparam, ··· 1438 1426 } 1439 1427 1440 1428 static const struct ethtool_ops otx2vf_ethtool_ops = { 1441 - .cap_rss_ctx_supported = true, 1442 1429 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 1443 1430 ETHTOOL_COALESCE_MAX_FRAMES | 1444 1431 ETHTOOL_COALESCE_USE_ADAPTIVE, 1445 1432 .supported_ring_params = ETHTOOL_RING_USE_RX_BUF_LEN | 1446 1433 ETHTOOL_RING_USE_CQE_SIZE, 1434 + .rxfh_max_num_contexts = MAX_RSS_GROUPS, 1447 1435 .get_link = otx2_get_link, 1448 1436 .get_drvinfo = otx2vf_get_drvinfo, 1449 1437 .get_strings = otx2vf_get_strings, ··· 1459 1447 .set_rxfh = otx2_set_rxfh, 1460 1448 .get_rxfh_fields = otx2_get_rss_hash_opts, 1461 1449 .set_rxfh_fields = otx2_set_rss_hash_opts, 1450 + .create_rxfh_context = otx2_create_rxfh, 1451 + .modify_rxfh_context = otx2_modify_rxfh, 1452 + .remove_rxfh_context = otx2_remove_rxfh, 1462 1453 .get_ringparam = otx2_get_ringparam, 1463 1454 .set_ringparam = otx2_set_ringparam, 1464 1455 .get_coalesce = otx2_get_coalesce,
+1 -5
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
··· 2158 2158 struct otx2_nic *pf = netdev_priv(netdev); 2159 2159 struct otx2_cq_poll *cq_poll = NULL; 2160 2160 struct otx2_qset *qset = &pf->qset; 2161 - struct otx2_rss_info *rss; 2162 2161 int qidx, vec, wrk; 2163 2162 2164 2163 /* If the DOWN flag is set resources are already freed */ ··· 2175 2176 otx2_rxtx_enable(pf, false); 2176 2177 2177 2178 /* Clear RSS enable flag */ 2178 - rss = &pf->hw.rss_info; 2179 - rss->enable = false; 2180 - if (!netif_is_rxfh_configured(netdev)) 2181 - kfree(rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP]); 2179 + pf->hw.rss_info.enable = false; 2182 2180 2183 2181 /* Cleanup Queue IRQ */ 2184 2182 vec = pci_irq_vector(pf->pdev,
+2 -2
drivers/net/ethernet/marvell/octeontx2/nic/otx2_xsk.c
··· 132 132 set_bit(qidx, pf->af_xdp_zc_qidx); 133 133 otx2_clean_up_rq(pf, qidx); 134 134 /* Reconfigure RSS table as 'qidx' cannot be part of RSS now */ 135 - otx2_set_rss_table(pf, DEFAULT_RSS_CONTEXT_GROUP); 135 + otx2_set_rss_table(pf, DEFAULT_RSS_CONTEXT_GROUP, NULL); 136 136 /* Kick start the NAPI context so that receiving will start */ 137 137 return otx2_xsk_wakeup(pf->netdev, qidx, XDP_WAKEUP_RX); 138 138 } ··· 153 153 clear_bit(qidx, pf->af_xdp_zc_qidx); 154 154 xsk_pool_dma_unmap(pool, DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING); 155 155 /* Reconfigure RSS table as 'qidx' now need to be part of RSS now */ 156 - otx2_set_rss_table(pf, DEFAULT_RSS_CONTEXT_GROUP); 156 + otx2_set_rss_table(pf, DEFAULT_RSS_CONTEXT_GROUP, NULL); 157 157 158 158 return 0; 159 159 }
+2 -3
drivers/net/ethernet/mellanox/mlx5/core/en/rss.c
··· 567 567 return final_err; 568 568 } 569 569 570 - int mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc, bool *symmetric) 570 + void mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc, 571 + bool *symmetric) 571 572 { 572 573 if (indir) 573 574 memcpy(indir, rss->indir.table, ··· 583 582 584 583 if (symmetric) 585 584 *symmetric = rss->hash.symmetric; 586 - 587 - return 0; 588 585 } 589 586 590 587 int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
+2 -1
drivers/net/ethernet/mellanox/mlx5/core/en/rss.h
··· 47 47 48 48 int mlx5e_rss_packet_merge_set_param(struct mlx5e_rss *rss, 49 49 struct mlx5e_packet_merge_param *pkt_merge_param); 50 - int mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc, bool *symmetric); 50 + void mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc, 51 + bool *symmetric); 51 52 int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir, 52 53 const u8 *key, const u8 *hfunc, const bool *symmetric, 53 54 u32 *rqns, u32 *vhca_ids, unsigned int num_rqns);
+11 -19
drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c
··· 71 71 return 0; 72 72 } 73 73 74 - int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 *rss_idx, unsigned int init_nch) 74 + int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 rss_idx, unsigned int init_nch) 75 75 { 76 76 bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT; 77 77 struct mlx5e_rss *rss; 78 - int i; 79 78 80 - for (i = 1; i < MLX5E_MAX_NUM_RSS; i++) 81 - if (!res->rss[i]) 82 - break; 83 - 84 - if (i == MLX5E_MAX_NUM_RSS) 79 + if (WARN_ON_ONCE(res->rss[rss_idx])) 85 80 return -ENOSPC; 86 81 87 82 rss = mlx5e_rss_init(res->mdev, inner_ft_support, res->drop_rqn, ··· 92 97 mlx5e_rss_enable(rss, res->rss_rqns, vhca_ids, res->rss_nch); 93 98 } 94 99 95 - res->rss[i] = rss; 96 - *rss_idx = i; 100 + res->rss[rss_idx] = rss; 97 101 98 102 return 0; 99 103 } ··· 187 193 mlx5e_rss_set_indir_uniform(res->rss[0], nch); 188 194 } 189 195 190 - int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx, 191 - u32 *indir, u8 *key, u8 *hfunc, bool *symmetric) 196 + void mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx, 197 + u32 *indir, u8 *key, u8 *hfunc, bool *symmetric) 192 198 { 193 - struct mlx5e_rss *rss; 199 + struct mlx5e_rss *rss = NULL; 194 200 195 - if (rss_idx >= MLX5E_MAX_NUM_RSS) 196 - return -EINVAL; 201 + if (rss_idx < MLX5E_MAX_NUM_RSS) 202 + rss = res->rss[rss_idx]; 203 + if (WARN_ON_ONCE(!rss)) 204 + return; 197 205 198 - rss = res->rss[rss_idx]; 199 - if (!rss) 200 - return -ENOENT; 201 - 202 - return mlx5e_rss_get_rxfh(rss, indir, key, hfunc, symmetric); 206 + mlx5e_rss_get_rxfh(rss, indir, key, hfunc, symmetric); 203 207 } 204 208 205 209 int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
+4 -3
drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.h
··· 48 48 49 49 /* Configuration API */ 50 50 void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int nch); 51 - int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx, 52 - u32 *indir, u8 *key, u8 *hfunc, bool *symmetric); 51 + void mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx, 52 + u32 *indir, u8 *key, u8 *hfunc, 53 + bool *symmetric); 53 54 int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx, 54 55 const u32 *indir, const u8 *key, const u8 *hfunc, 55 56 const bool *symmetric); ··· 62 61 int mlx5e_rx_res_packet_merge_set_param(struct mlx5e_rx_res *res, 63 62 struct mlx5e_packet_merge_param *pkt_merge_param); 64 63 65 - int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 *rss_idx, unsigned int init_nch); 64 + int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 rss_idx, unsigned int init_nch); 66 65 int mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res, u32 rss_idx); 67 66 int mlx5e_rx_res_rss_cnt(struct mlx5e_rx_res *res); 68 67 int mlx5e_rx_res_rss_index(struct mlx5e_rx_res *res, struct mlx5e_rss *rss);
+111 -34
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
··· 1480 1480 static int mlx5e_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh) 1481 1481 { 1482 1482 struct mlx5e_priv *priv = netdev_priv(netdev); 1483 - u32 rss_context = rxfh->rss_context; 1484 1483 bool symmetric; 1485 - int err; 1486 1484 1487 1485 mutex_lock(&priv->state_lock); 1488 - err = mlx5e_rx_res_rss_get_rxfh(priv->rx_res, rss_context, 1489 - rxfh->indir, rxfh->key, &rxfh->hfunc, &symmetric); 1486 + mlx5e_rx_res_rss_get_rxfh(priv->rx_res, 0, rxfh->indir, rxfh->key, 1487 + &rxfh->hfunc, &symmetric); 1490 1488 mutex_unlock(&priv->state_lock); 1491 - 1492 - if (err) 1493 - return err; 1494 1489 1495 1490 if (symmetric) 1496 1491 rxfh->input_xfrm = RXH_XFRM_SYM_OR_XOR; ··· 1493 1498 return 0; 1494 1499 } 1495 1500 1496 - static int mlx5e_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh, 1501 + static int mlx5e_rxfh_hfunc_check(struct mlx5e_priv *priv, 1502 + const struct ethtool_rxfh_param *rxfh) 1503 + { 1504 + unsigned int count; 1505 + 1506 + count = priv->channels.params.num_channels; 1507 + 1508 + if (rxfh->hfunc == ETH_RSS_HASH_XOR) { 1509 + unsigned int xor8_max_channels = mlx5e_rqt_max_num_channels_allowed_for_xor8(); 1510 + 1511 + if (count > xor8_max_channels) { 1512 + netdev_err(priv->netdev, "%s: Cannot set RSS hash function to XOR, current number of channels (%d) exceeds the maximum allowed for XOR8 RSS hfunc (%d)\n", 1513 + __func__, count, xor8_max_channels); 1514 + return -EINVAL; 1515 + } 1516 + } 1517 + 1518 + return 0; 1519 + } 1520 + 1521 + static int mlx5e_set_rxfh(struct net_device *dev, 1522 + struct ethtool_rxfh_param *rxfh, 1497 1523 struct netlink_ext_ack *extack) 1498 1524 { 1499 1525 bool symmetric = rxfh->input_xfrm == RXH_XFRM_SYM_OR_XOR; 1500 1526 struct mlx5e_priv *priv = netdev_priv(dev); 1501 - u32 *rss_context = &rxfh->rss_context; 1502 1527 u8 hfunc = rxfh->hfunc; 1503 - unsigned int count; 1504 1528 int err; 1505 1529 1506 1530 mutex_lock(&priv->state_lock); 1507 1531 1508 - count = priv->channels.params.num_channels; 1509 - 1510 - if (hfunc == ETH_RSS_HASH_XOR) { 1511 - unsigned int xor8_max_channels = mlx5e_rqt_max_num_channels_allowed_for_xor8(); 1512 - 1513 - if (count > xor8_max_channels) { 1514 - err = -EINVAL; 1515 - netdev_err(priv->netdev, "%s: Cannot set RSS hash function to XOR, current number of channels (%d) exceeds the maximum allowed for XOR8 RSS hfunc (%d)\n", 1516 - __func__, count, xor8_max_channels); 1517 - goto unlock; 1518 - } 1519 - } 1520 - 1521 - if (*rss_context && rxfh->rss_delete) { 1522 - err = mlx5e_rx_res_rss_destroy(priv->rx_res, *rss_context); 1532 + err = mlx5e_rxfh_hfunc_check(priv, rxfh); 1533 + if (err) 1523 1534 goto unlock; 1524 - } 1525 1535 1526 - if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) { 1527 - err = mlx5e_rx_res_rss_init(priv->rx_res, rss_context, count); 1528 - if (err) 1529 - goto unlock; 1530 - } 1531 - 1532 - err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, *rss_context, 1536 + err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, rxfh->rss_context, 1533 1537 rxfh->indir, rxfh->key, 1534 1538 hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc, 1535 1539 rxfh->input_xfrm == RXH_XFRM_NO_CHANGE ? NULL : &symmetric); 1536 1540 1537 1541 unlock: 1542 + mutex_unlock(&priv->state_lock); 1543 + return err; 1544 + } 1545 + 1546 + static int mlx5e_create_rxfh_context(struct net_device *dev, 1547 + struct ethtool_rxfh_context *ctx, 1548 + const struct ethtool_rxfh_param *rxfh, 1549 + struct netlink_ext_ack *extack) 1550 + { 1551 + bool symmetric = rxfh->input_xfrm == RXH_XFRM_SYM_OR_XOR; 1552 + struct mlx5e_priv *priv = netdev_priv(dev); 1553 + u8 hfunc = rxfh->hfunc; 1554 + int err; 1555 + 1556 + mutex_lock(&priv->state_lock); 1557 + 1558 + err = mlx5e_rxfh_hfunc_check(priv, rxfh); 1559 + if (err) 1560 + goto unlock; 1561 + 1562 + err = mlx5e_rx_res_rss_init(priv->rx_res, rxfh->rss_context, 1563 + priv->channels.params.num_channels); 1564 + if (err) 1565 + goto unlock; 1566 + 1567 + err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, rxfh->rss_context, 1568 + rxfh->indir, rxfh->key, 1569 + hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc, 1570 + rxfh->input_xfrm == RXH_XFRM_NO_CHANGE ? NULL : &symmetric); 1571 + if (err) 1572 + goto unlock; 1573 + 1574 + mlx5e_rx_res_rss_get_rxfh(priv->rx_res, rxfh->rss_context, 1575 + ethtool_rxfh_context_indir(ctx), 1576 + ethtool_rxfh_context_key(ctx), 1577 + &ctx->hfunc, &symmetric); 1578 + if (symmetric) 1579 + ctx->input_xfrm = RXH_XFRM_SYM_OR_XOR; 1580 + 1581 + unlock: 1582 + mutex_unlock(&priv->state_lock); 1583 + return err; 1584 + } 1585 + 1586 + static int mlx5e_modify_rxfh_context(struct net_device *dev, 1587 + struct ethtool_rxfh_context *ctx, 1588 + const struct ethtool_rxfh_param *rxfh, 1589 + struct netlink_ext_ack *extack) 1590 + { 1591 + bool symmetric = rxfh->input_xfrm == RXH_XFRM_SYM_OR_XOR; 1592 + struct mlx5e_priv *priv = netdev_priv(dev); 1593 + u8 hfunc = rxfh->hfunc; 1594 + int err; 1595 + 1596 + mutex_lock(&priv->state_lock); 1597 + 1598 + err = mlx5e_rxfh_hfunc_check(priv, rxfh); 1599 + if (err) 1600 + goto unlock; 1601 + 1602 + err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, rxfh->rss_context, 1603 + rxfh->indir, rxfh->key, 1604 + hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc, 1605 + rxfh->input_xfrm == RXH_XFRM_NO_CHANGE ? NULL : &symmetric); 1606 + 1607 + unlock: 1608 + mutex_unlock(&priv->state_lock); 1609 + return err; 1610 + } 1611 + 1612 + static int mlx5e_remove_rxfh_context(struct net_device *dev, 1613 + struct ethtool_rxfh_context *ctx, 1614 + u32 rss_context, 1615 + struct netlink_ext_ack *extack) 1616 + { 1617 + struct mlx5e_priv *priv = netdev_priv(dev); 1618 + int err; 1619 + 1620 + mutex_lock(&priv->state_lock); 1621 + err = mlx5e_rx_res_rss_destroy(priv->rx_res, rss_context); 1538 1622 mutex_unlock(&priv->state_lock); 1539 1623 return err; 1540 1624 } ··· 2728 2654 2729 2655 const struct ethtool_ops mlx5e_ethtool_ops = { 2730 2656 .cap_link_lanes_supported = true, 2731 - .cap_rss_ctx_supported = true, 2732 2657 .rxfh_per_ctx_fields = true, 2733 2658 .rxfh_per_ctx_key = true, 2659 + .rxfh_max_num_contexts = MLX5E_MAX_NUM_RSS, 2734 2660 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 2735 2661 ETHTOOL_COALESCE_MAX_FRAMES | 2736 2662 ETHTOOL_COALESCE_USE_ADAPTIVE | ··· 2759 2685 .set_rxfh = mlx5e_set_rxfh, 2760 2686 .get_rxfh_fields = mlx5e_get_rxfh_fields, 2761 2687 .set_rxfh_fields = mlx5e_set_rxfh_fields, 2688 + .create_rxfh_context = mlx5e_create_rxfh_context, 2689 + .modify_rxfh_context = mlx5e_modify_rxfh_context, 2690 + .remove_rxfh_context = mlx5e_remove_rxfh_context, 2762 2691 .get_rxnfc = mlx5e_get_rxnfc, 2763 2692 .set_rxnfc = mlx5e_set_rxnfc, 2764 2693 .get_tunable = mlx5e_get_tunable,
-4
include/linux/ethtool.h
··· 865 865 * @supported_input_xfrm: supported types of input xfrm from %RXH_XFRM_*. 866 866 * @cap_link_lanes_supported: indicates if the driver supports lanes 867 867 * parameter. 868 - * @cap_rss_ctx_supported: indicates if the driver supports RSS 869 - * contexts via legacy API, drivers implementing @create_rxfh_context 870 - * do not have to set this bit. 871 868 * @rxfh_per_ctx_fields: device supports selecting different header fields 872 869 * for Rx hash calculation and RSS for each additional context. 873 870 * @rxfh_per_ctx_key: device supports setting different RSS key for each ··· 1097 1100 struct ethtool_ops { 1098 1101 u32 supported_input_xfrm:8; 1099 1102 u32 cap_link_lanes_supported:1; 1100 - u32 cap_rss_ctx_supported:1; 1101 1103 u32 rxfh_per_ctx_fields:1; 1102 1104 u32 rxfh_per_ctx_key:1; 1103 1105 u32 cap_rss_rxnfc_adds:1;
+1 -14
net/core/dev.c
··· 11979 11979 11980 11980 mutex_lock(&dev->ethtool->rss_lock); 11981 11981 xa_for_each(&dev->ethtool->rss_ctx, context, ctx) { 11982 - struct ethtool_rxfh_param rxfh; 11983 - 11984 - rxfh.indir = ethtool_rxfh_context_indir(ctx); 11985 - rxfh.key = ethtool_rxfh_context_key(ctx); 11986 - rxfh.hfunc = ctx->hfunc; 11987 - rxfh.input_xfrm = ctx->input_xfrm; 11988 - rxfh.rss_context = context; 11989 - rxfh.rss_delete = true; 11990 - 11991 11982 xa_erase(&dev->ethtool->rss_ctx, context); 11992 - if (dev->ethtool_ops->create_rxfh_context) 11993 - dev->ethtool_ops->remove_rxfh_context(dev, ctx, 11994 - context, NULL); 11995 - else 11996 - dev->ethtool_ops->set_rxfh(dev, &rxfh, NULL); 11983 + dev->ethtool_ops->remove_rxfh_context(dev, ctx, context, NULL); 11997 11984 kfree(ctx); 11998 11985 } 11999 11986 xa_destroy(&dev->ethtool->rss_ctx);
+25 -68
net/ethtool/ioctl.c
··· 1391 1391 if (rxfh.rsvd8[0] || rxfh.rsvd8[1] || rxfh.rsvd32) 1392 1392 return -EINVAL; 1393 1393 /* Most drivers don't handle rss_context, check it's 0 as well */ 1394 - if (rxfh.rss_context && !(ops->cap_rss_ctx_supported || 1395 - ops->create_rxfh_context)) 1394 + if (rxfh.rss_context && !ops->create_rxfh_context) 1396 1395 return -EOPNOTSUPP; 1397 1396 1398 1397 rxfh.indir_size = rxfh_dev.indir_size; ··· 1533 1534 if (rxfh.rsvd8[0] || rxfh.rsvd8[1] || rxfh.rsvd32) 1534 1535 return -EINVAL; 1535 1536 /* Most drivers don't handle rss_context, check it's 0 as well */ 1536 - if (rxfh.rss_context && !(ops->cap_rss_ctx_supported || 1537 - ops->create_rxfh_context)) 1537 + if (rxfh.rss_context && !ops->create_rxfh_context) 1538 1538 return -EOPNOTSUPP; 1539 1539 /* Check input data transformation capabilities */ 1540 1540 if (rxfh.input_xfrm && rxfh.input_xfrm != RXH_XFRM_SYM_XOR && ··· 1632 1634 } 1633 1635 1634 1636 if (create) { 1637 + u32 limit, ctx_id; 1638 + 1635 1639 if (rxfh_dev.rss_delete) { 1636 1640 ret = -EINVAL; 1637 1641 goto out_unlock; ··· 1644 1644 goto out_unlock; 1645 1645 } 1646 1646 1647 - if (ops->create_rxfh_context) { 1648 - u32 limit = ops->rxfh_max_num_contexts ?: U32_MAX; 1649 - u32 ctx_id; 1650 - 1651 - /* driver uses new API, core allocates ID */ 1652 - ret = xa_alloc(&dev->ethtool->rss_ctx, &ctx_id, ctx, 1653 - XA_LIMIT(1, limit - 1), 1654 - GFP_KERNEL_ACCOUNT); 1655 - if (ret < 0) { 1656 - kfree(ctx); 1657 - goto out_unlock; 1658 - } 1659 - WARN_ON(!ctx_id); /* can't happen */ 1660 - rxfh.rss_context = ctx_id; 1647 + limit = ops->rxfh_max_num_contexts ?: U32_MAX; 1648 + ret = xa_alloc(&dev->ethtool->rss_ctx, &ctx_id, ctx, 1649 + XA_LIMIT(1, limit - 1), GFP_KERNEL_ACCOUNT); 1650 + if (ret < 0) { 1651 + kfree(ctx); 1652 + goto out_unlock; 1661 1653 } 1654 + WARN_ON(!ctx_id); /* can't happen */ 1655 + rxfh.rss_context = ctx_id; 1662 1656 } else if (rxfh.rss_context) { 1663 1657 ctx = xa_load(&dev->ethtool->rss_ctx, rxfh.rss_context); 1664 1658 if (!ctx) { ··· 1664 1670 rxfh_dev.rss_context = rxfh.rss_context; 1665 1671 rxfh_dev.input_xfrm = rxfh.input_xfrm; 1666 1672 1667 - if (rxfh.rss_context && ops->create_rxfh_context) { 1668 - if (create) { 1669 - ret = ops->create_rxfh_context(dev, ctx, &rxfh_dev, 1670 - extack); 1671 - /* Make sure driver populates defaults */ 1672 - WARN_ON_ONCE(!ret && !rxfh_dev.key && 1673 - ops->rxfh_per_ctx_key && 1674 - !memchr_inv(ethtool_rxfh_context_key(ctx), 1675 - 0, ctx->key_size)); 1676 - } else if (rxfh_dev.rss_delete) { 1677 - ret = ops->remove_rxfh_context(dev, ctx, 1678 - rxfh.rss_context, 1679 - extack); 1680 - } else { 1681 - ret = ops->modify_rxfh_context(dev, ctx, &rxfh_dev, 1682 - extack); 1683 - } 1684 - } else { 1673 + if (!rxfh.rss_context) { 1685 1674 ret = ops->set_rxfh(dev, &rxfh_dev, extack); 1675 + } else if (create) { 1676 + ret = ops->create_rxfh_context(dev, ctx, &rxfh_dev, extack); 1677 + /* Make sure driver populates defaults */ 1678 + WARN_ON_ONCE(!ret && !rxfh_dev.key && ops->rxfh_per_ctx_key && 1679 + !memchr_inv(ethtool_rxfh_context_key(ctx), 0, 1680 + ctx->key_size)); 1681 + } else if (rxfh_dev.rss_delete) { 1682 + ret = ops->remove_rxfh_context(dev, ctx, rxfh.rss_context, 1683 + extack); 1684 + } else { 1685 + ret = ops->modify_rxfh_context(dev, ctx, &rxfh_dev, extack); 1686 1686 } 1687 1687 if (ret) { 1688 1688 if (create) { 1689 1689 /* failed to create, free our new tracking entry */ 1690 - if (ops->create_rxfh_context) 1691 - xa_erase(&dev->ethtool->rss_ctx, rxfh.rss_context); 1690 + xa_erase(&dev->ethtool->rss_ctx, rxfh.rss_context); 1692 1691 kfree(ctx); 1693 1692 } 1694 1693 goto out_unlock; ··· 1700 1713 dev->priv_flags |= IFF_RXFH_CONFIGURED; 1701 1714 } 1702 1715 /* Update rss_ctx tracking */ 1703 - if (create && !ops->create_rxfh_context) { 1704 - /* driver uses old API, it chose context ID */ 1705 - if (WARN_ON(xa_load(&dev->ethtool->rss_ctx, rxfh_dev.rss_context))) { 1706 - /* context ID reused, our tracking is screwed */ 1707 - kfree(ctx); 1708 - goto out_unlock; 1709 - } 1710 - /* Allocate the exact ID the driver gave us */ 1711 - if (xa_is_err(xa_store(&dev->ethtool->rss_ctx, rxfh_dev.rss_context, 1712 - ctx, GFP_KERNEL))) { 1713 - kfree(ctx); 1714 - goto out_unlock; 1715 - } 1716 - 1717 - /* Fetch the defaults for the old API, in the new API drivers 1718 - * should write defaults into ctx themselves. 1719 - */ 1720 - rxfh_dev.indir = (u32 *)rss_config; 1721 - rxfh_dev.indir_size = dev_indir_size; 1722 - 1723 - rxfh_dev.key = rss_config + indir_bytes; 1724 - rxfh_dev.key_size = dev_key_size; 1725 - 1726 - ret = ops->get_rxfh(dev, &rxfh_dev); 1727 - if (WARN_ON(ret)) { 1728 - xa_erase(&dev->ethtool->rss_ctx, rxfh.rss_context); 1729 - kfree(ctx); 1730 - goto out_unlock; 1731 - } 1732 - } 1733 1716 if (rxfh_dev.rss_delete) { 1734 1717 WARN_ON(xa_erase(&dev->ethtool->rss_ctx, rxfh.rss_context) != ctx); 1735 1718 kfree(ctx);
+1 -2
net/ethtool/rss.c
··· 163 163 return -EOPNOTSUPP; 164 164 165 165 /* Some drivers don't handle rss_context */ 166 - if (request->rss_context && 167 - !ops->cap_rss_ctx_supported && !ops->create_rxfh_context) 166 + if (request->rss_context && !ops->create_rxfh_context) 168 167 return -EOPNOTSUPP; 169 168 170 169 mutex_lock(&dev->ethtool->rss_lock);