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

net: ethtool: move rxfh_fields callbacks under the rss_lock

Netlink code will want to perform the RSS_SET operation atomically
under the rss_lock. sfc wants to hold the rss_lock in rxfh_fields_get,
which makes that difficult. Lets move the locking up to the core
so that for all driver-facing callbacks rss_lock is taken consistently
by the core.

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

+12 -12
+2 -7
drivers/net/ethernet/sfc/ethtool_common.c
··· 810 810 811 811 ctx = &efx->rss_context.priv; 812 812 813 - mutex_lock(&net_dev->ethtool->rss_lock); 814 813 if (info->rss_context) { 815 814 ctx = efx_find_rss_context_entry(efx, info->rss_context); 816 - if (!ctx) { 817 - rc = -ENOENT; 818 - goto out_unlock; 819 - } 815 + if (!ctx) 816 + return -ENOENT; 820 817 } 821 818 822 819 data = 0; ··· 847 850 } 848 851 out_setdata_unlock: 849 852 info->data = data; 850 - out_unlock: 851 - mutex_unlock(&net_dev->ethtool->rss_lock); 852 853 return rc; 853 854 } 854 855
+10 -5
net/ethtool/ioctl.c
··· 1096 1096 if (info.flow_type & FLOW_RSS) 1097 1097 fields.rss_context = info.rss_context; 1098 1098 1099 - return ops->set_rxfh_fields(dev, &fields, NULL); 1099 + mutex_lock(&dev->ethtool->rss_lock); 1100 + rc = ops->set_rxfh_fields(dev, &fields, NULL); 1101 + mutex_unlock(&dev->ethtool->rss_lock); 1102 + return rc; 1100 1103 } 1101 1104 1102 1105 static noinline_for_stack int ··· 1126 1123 if (info.flow_type & FLOW_RSS) 1127 1124 fields.rss_context = info.rss_context; 1128 1125 1126 + mutex_lock(&dev->ethtool->rss_lock); 1129 1127 ret = ops->get_rxfh_fields(dev, &fields); 1128 + mutex_unlock(&dev->ethtool->rss_lock); 1130 1129 if (ret < 0) 1131 1130 return ret; 1132 1131 ··· 1558 1553 rxfh.input_xfrm == RXH_XFRM_NO_CHANGE)) 1559 1554 return -EINVAL; 1560 1555 1561 - ret = ethtool_check_flow_types(dev, rxfh.input_xfrm); 1562 - if (ret) 1563 - return ret; 1564 - 1565 1556 indir_bytes = dev_indir_size * sizeof(rxfh_dev.indir[0]); 1566 1557 1567 1558 /* Check settings which may be global rather than per RSS-context */ ··· 1617 1616 } 1618 1617 1619 1618 mutex_lock(&dev->ethtool->rss_lock); 1619 + 1620 + ret = ethtool_check_flow_types(dev, rxfh.input_xfrm); 1621 + if (ret) 1622 + goto out_unlock; 1620 1623 1621 1624 if (rxfh.rss_context && rxfh_dev.rss_delete) { 1622 1625 ret = ethtool_check_rss_ctx_busy(dev, rxfh.rss_context);