mirror of
https://github.com/torvalds/linux.git
synced 2026-05-22 14:12:07 +02:00
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>
This commit is contained in:
commit
0a49abff43
|
|
@ -3591,11 +3591,10 @@ static int
|
|||
ice_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
|
||||
{
|
||||
struct ice_netdev_priv *np = netdev_priv(netdev);
|
||||
u32 rss_context = rxfh->rss_context;
|
||||
struct ice_vsi *vsi = np->vsi;
|
||||
struct ice_pf *pf = vsi->back;
|
||||
u16 qcount, offset;
|
||||
int err, num_tc, i;
|
||||
int err, i;
|
||||
u8 *lut;
|
||||
|
||||
if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) {
|
||||
|
|
@ -3603,24 +3602,8 @@ ice_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (rss_context && !ice_is_adq_active(pf)) {
|
||||
netdev_err(netdev, "RSS context cannot be non-zero when ADQ is not configured.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
qcount = vsi->mqprio_qopt.qopt.count[rss_context];
|
||||
offset = vsi->mqprio_qopt.qopt.offset[rss_context];
|
||||
|
||||
if (rss_context && ice_is_adq_active(pf)) {
|
||||
num_tc = vsi->mqprio_qopt.qopt.num_tc;
|
||||
if (rss_context >= num_tc) {
|
||||
netdev_err(netdev, "RSS context:%d > num_tc:%d\n",
|
||||
rss_context, num_tc);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Use channel VSI of given TC */
|
||||
vsi = vsi->tc_map_vsi[rss_context];
|
||||
}
|
||||
qcount = vsi->mqprio_qopt.qopt.count[0];
|
||||
offset = vsi->mqprio_qopt.qopt.offset[0];
|
||||
|
||||
rxfh->hfunc = ETH_RSS_HASH_TOP;
|
||||
if (vsi->rss_hfunc == ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ)
|
||||
|
|
@ -3680,9 +3663,6 @@ ice_set_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh,
|
|||
rxfh->hfunc != ETH_RSS_HASH_TOP)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (rxfh->rss_context)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) {
|
||||
/* RSS not supported return error here */
|
||||
netdev_warn(netdev, "RSS is not configured on this VSI!\n");
|
||||
|
|
@ -4750,12 +4730,10 @@ static int ice_repr_ethtool_reset(struct net_device *dev, u32 *flags)
|
|||
}
|
||||
|
||||
static const struct ethtool_ops ice_ethtool_ops = {
|
||||
.cap_rss_ctx_supported = true,
|
||||
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
|
||||
ETHTOOL_COALESCE_USE_ADAPTIVE |
|
||||
ETHTOOL_COALESCE_RX_USECS_HIGH,
|
||||
.supported_input_xfrm = RXH_XFRM_SYM_XOR,
|
||||
.rxfh_per_ctx_key = true,
|
||||
.get_link_ksettings = ice_get_link_ksettings,
|
||||
.set_link_ksettings = ice_set_link_ksettings,
|
||||
.get_fec_stats = ice_get_fec_stats,
|
||||
|
|
|
|||
|
|
@ -318,21 +318,20 @@ int otx2_set_flowkey_cfg(struct otx2_nic *pfvf)
|
|||
return err;
|
||||
}
|
||||
|
||||
int otx2_set_rss_table(struct otx2_nic *pfvf, int ctx_id)
|
||||
int otx2_set_rss_table(struct otx2_nic *pfvf, int ctx_id, const u32 *ind_tbl)
|
||||
{
|
||||
struct otx2_rss_info *rss = &pfvf->hw.rss_info;
|
||||
const int index = rss->rss_size * ctx_id;
|
||||
struct mbox *mbox = &pfvf->mbox;
|
||||
struct otx2_rss_ctx *rss_ctx;
|
||||
struct nix_aq_enq_req *aq;
|
||||
int idx, err;
|
||||
|
||||
mutex_lock(&mbox->lock);
|
||||
rss_ctx = rss->rss_ctx[ctx_id];
|
||||
ind_tbl = ind_tbl ?: rss->ind_tbl;
|
||||
/* Get memory to put this msg */
|
||||
for (idx = 0; idx < rss->rss_size; idx++) {
|
||||
/* Ignore the queue if AF_XDP zero copy is enabled */
|
||||
if (test_bit(rss_ctx->ind_tbl[idx], pfvf->af_xdp_zc_qidx))
|
||||
if (test_bit(ind_tbl[idx], pfvf->af_xdp_zc_qidx))
|
||||
continue;
|
||||
|
||||
aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
|
||||
|
|
@ -352,7 +351,7 @@ int otx2_set_rss_table(struct otx2_nic *pfvf, int ctx_id)
|
|||
}
|
||||
}
|
||||
|
||||
aq->rss.rq = rss_ctx->ind_tbl[idx];
|
||||
aq->rss.rq = ind_tbl[idx];
|
||||
|
||||
/* Fill AQ info */
|
||||
aq->qidx = index + idx;
|
||||
|
|
@ -390,30 +389,22 @@ void otx2_set_rss_key(struct otx2_nic *pfvf)
|
|||
int otx2_rss_init(struct otx2_nic *pfvf)
|
||||
{
|
||||
struct otx2_rss_info *rss = &pfvf->hw.rss_info;
|
||||
struct otx2_rss_ctx *rss_ctx;
|
||||
int idx, ret = 0;
|
||||
|
||||
rss->rss_size = sizeof(*rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP]);
|
||||
rss->rss_size = sizeof(*rss->ind_tbl);
|
||||
|
||||
/* Init RSS key if it is not setup already */
|
||||
if (!rss->enable)
|
||||
netdev_rss_key_fill(rss->key, sizeof(rss->key));
|
||||
otx2_set_rss_key(pfvf);
|
||||
|
||||
if (!netif_is_rxfh_configured(pfvf->netdev)) {
|
||||
/* Set RSS group 0 as default indirection table */
|
||||
rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP] = kzalloc(rss->rss_size,
|
||||
GFP_KERNEL);
|
||||
if (!rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP])
|
||||
return -ENOMEM;
|
||||
|
||||
rss_ctx = rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP];
|
||||
if (!netif_is_rxfh_configured(pfvf->netdev))
|
||||
for (idx = 0; idx < rss->rss_size; idx++)
|
||||
rss_ctx->ind_tbl[idx] =
|
||||
rss->ind_tbl[idx] =
|
||||
ethtool_rxfh_indir_default(idx,
|
||||
pfvf->hw.rx_queues);
|
||||
}
|
||||
ret = otx2_set_rss_table(pfvf, DEFAULT_RSS_CONTEXT_GROUP);
|
||||
|
||||
ret = otx2_set_rss_table(pfvf, DEFAULT_RSS_CONTEXT_GROUP, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -93,10 +93,6 @@ struct otx2_lmt_info {
|
|||
u64 lmt_addr;
|
||||
u16 lmt_id;
|
||||
};
|
||||
/* RSS configuration */
|
||||
struct otx2_rss_ctx {
|
||||
u8 ind_tbl[MAX_RSS_INDIR_TBL_SIZE];
|
||||
};
|
||||
|
||||
struct otx2_rss_info {
|
||||
u8 enable;
|
||||
|
|
@ -104,7 +100,7 @@ struct otx2_rss_info {
|
|||
u16 rss_size;
|
||||
#define RSS_HASH_KEY_SIZE 44 /* 352 bit key */
|
||||
u8 key[RSS_HASH_KEY_SIZE];
|
||||
struct otx2_rss_ctx *rss_ctx[MAX_RSS_GROUPS];
|
||||
u32 ind_tbl[MAX_RSS_INDIR_TBL_SIZE];
|
||||
};
|
||||
|
||||
/* NIX (or NPC) RX errors */
|
||||
|
|
@ -1067,7 +1063,7 @@ int otx2_set_hw_capabilities(struct otx2_nic *pfvf);
|
|||
int otx2_rss_init(struct otx2_nic *pfvf);
|
||||
int otx2_set_flowkey_cfg(struct otx2_nic *pfvf);
|
||||
void otx2_set_rss_key(struct otx2_nic *pfvf);
|
||||
int otx2_set_rss_table(struct otx2_nic *pfvf, int ctx_id);
|
||||
int otx2_set_rss_table(struct otx2_nic *pfvf, int ctx_id, const u32 *ind_tbl);
|
||||
|
||||
/* Mbox handlers */
|
||||
void mbox_handler_msix_offset(struct otx2_nic *pfvf,
|
||||
|
|
|
|||
|
|
@ -796,35 +796,75 @@ static u32 otx2_get_rxfh_indir_size(struct net_device *dev)
|
|||
return MAX_RSS_INDIR_TBL_SIZE;
|
||||
}
|
||||
|
||||
static int otx2_rss_ctx_delete(struct otx2_nic *pfvf, int ctx_id)
|
||||
static int otx2_create_rxfh(struct net_device *dev,
|
||||
struct ethtool_rxfh_context *ctx,
|
||||
const struct ethtool_rxfh_param *rxfh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct otx2_rss_info *rss = &pfvf->hw.rss_info;
|
||||
struct otx2_nic *pfvf = netdev_priv(dev);
|
||||
struct otx2_rss_info *rss;
|
||||
unsigned int queues;
|
||||
u32 *ind_tbl;
|
||||
int idx;
|
||||
|
||||
otx2_rss_ctx_flow_del(pfvf, ctx_id);
|
||||
kfree(rss->rss_ctx[ctx_id]);
|
||||
rss->rss_ctx[ctx_id] = NULL;
|
||||
rss = &pfvf->hw.rss_info;
|
||||
queues = pfvf->hw.rx_queues;
|
||||
|
||||
if (rxfh->hfunc && rxfh->hfunc != ETH_RSS_HASH_TOP)
|
||||
return -EOPNOTSUPP;
|
||||
ctx->hfunc = ETH_RSS_HASH_TOP;
|
||||
|
||||
if (!rss->enable) {
|
||||
netdev_err(dev, "RSS is disabled, cannot change settings\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ind_tbl = rxfh->indir;
|
||||
if (!ind_tbl) {
|
||||
ind_tbl = ethtool_rxfh_context_indir(ctx);
|
||||
for (idx = 0; idx < rss->rss_size; idx++)
|
||||
ind_tbl[idx] = ethtool_rxfh_indir_default(idx, queues);
|
||||
}
|
||||
|
||||
otx2_set_rss_table(pfvf, rxfh->rss_context, ind_tbl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int otx2_modify_rxfh(struct net_device *dev,
|
||||
struct ethtool_rxfh_context *ctx,
|
||||
const struct ethtool_rxfh_param *rxfh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct otx2_nic *pfvf = netdev_priv(dev);
|
||||
|
||||
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
|
||||
rxfh->hfunc != ETH_RSS_HASH_TOP)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!pfvf->hw.rss_info.enable) {
|
||||
netdev_err(dev, "RSS is disabled, cannot change settings\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (rxfh->indir)
|
||||
otx2_set_rss_table(pfvf, rxfh->rss_context, rxfh->indir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int otx2_rss_ctx_create(struct otx2_nic *pfvf,
|
||||
u32 *rss_context)
|
||||
static int otx2_remove_rxfh(struct net_device *dev,
|
||||
struct ethtool_rxfh_context *ctx,
|
||||
u32 rss_context,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct otx2_rss_info *rss = &pfvf->hw.rss_info;
|
||||
u8 ctx;
|
||||
struct otx2_nic *pfvf = netdev_priv(dev);
|
||||
|
||||
for (ctx = 0; ctx < MAX_RSS_GROUPS; ctx++) {
|
||||
if (!rss->rss_ctx[ctx])
|
||||
break;
|
||||
if (!pfvf->hw.rss_info.enable) {
|
||||
netdev_err(dev, "RSS is disabled, cannot change settings\n");
|
||||
return -EIO;
|
||||
}
|
||||
if (ctx == MAX_RSS_GROUPS)
|
||||
return -EINVAL;
|
||||
|
||||
rss->rss_ctx[ctx] = kzalloc(sizeof(*rss->rss_ctx[ctx]), GFP_KERNEL);
|
||||
if (!rss->rss_ctx[ctx])
|
||||
return -ENOMEM;
|
||||
*rss_context = ctx;
|
||||
|
||||
otx2_rss_ctx_flow_del(pfvf, rss_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -833,23 +873,14 @@ static int otx2_set_rxfh(struct net_device *dev,
|
|||
struct ethtool_rxfh_param *rxfh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
u32 rss_context = DEFAULT_RSS_CONTEXT_GROUP;
|
||||
struct otx2_nic *pfvf = netdev_priv(dev);
|
||||
struct otx2_rss_ctx *rss_ctx;
|
||||
struct otx2_rss_info *rss;
|
||||
int ret, idx;
|
||||
int idx;
|
||||
|
||||
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
|
||||
rxfh->hfunc != ETH_RSS_HASH_TOP)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (rxfh->rss_context)
|
||||
rss_context = rxfh->rss_context;
|
||||
|
||||
if (rss_context != ETH_RXFH_CONTEXT_ALLOC &&
|
||||
rss_context >= MAX_RSS_GROUPS)
|
||||
return -EINVAL;
|
||||
|
||||
rss = &pfvf->hw.rss_info;
|
||||
|
||||
if (!rss->enable) {
|
||||
|
|
@ -861,21 +892,12 @@ static int otx2_set_rxfh(struct net_device *dev,
|
|||
memcpy(rss->key, rxfh->key, sizeof(rss->key));
|
||||
otx2_set_rss_key(pfvf);
|
||||
}
|
||||
if (rxfh->rss_delete)
|
||||
return otx2_rss_ctx_delete(pfvf, rss_context);
|
||||
|
||||
if (rss_context == ETH_RXFH_CONTEXT_ALLOC) {
|
||||
ret = otx2_rss_ctx_create(pfvf, &rss_context);
|
||||
rxfh->rss_context = rss_context;
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (rxfh->indir) {
|
||||
rss_ctx = rss->rss_ctx[rss_context];
|
||||
for (idx = 0; idx < rss->rss_size; idx++)
|
||||
rss_ctx->ind_tbl[idx] = rxfh->indir[idx];
|
||||
rss->ind_tbl[idx] = rxfh->indir[idx];
|
||||
}
|
||||
otx2_set_rss_table(pfvf, rss_context);
|
||||
otx2_set_rss_table(pfvf, DEFAULT_RSS_CONTEXT_GROUP, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -884,9 +906,7 @@ static int otx2_set_rxfh(struct net_device *dev,
|
|||
static int otx2_get_rxfh(struct net_device *dev,
|
||||
struct ethtool_rxfh_param *rxfh)
|
||||
{
|
||||
u32 rss_context = DEFAULT_RSS_CONTEXT_GROUP;
|
||||
struct otx2_nic *pfvf = netdev_priv(dev);
|
||||
struct otx2_rss_ctx *rss_ctx;
|
||||
struct otx2_rss_info *rss;
|
||||
u32 *indir = rxfh->indir;
|
||||
int idx, rx_queues;
|
||||
|
|
@ -894,32 +914,21 @@ static int otx2_get_rxfh(struct net_device *dev,
|
|||
rss = &pfvf->hw.rss_info;
|
||||
|
||||
rxfh->hfunc = ETH_RSS_HASH_TOP;
|
||||
if (rxfh->rss_context)
|
||||
rss_context = rxfh->rss_context;
|
||||
|
||||
if (!indir)
|
||||
return 0;
|
||||
|
||||
if (!rss->enable && rss_context == DEFAULT_RSS_CONTEXT_GROUP) {
|
||||
if (!rss->enable) {
|
||||
rx_queues = pfvf->hw.rx_queues;
|
||||
for (idx = 0; idx < MAX_RSS_INDIR_TBL_SIZE; idx++)
|
||||
indir[idx] = ethtool_rxfh_indir_default(idx, rx_queues);
|
||||
return 0;
|
||||
}
|
||||
if (rss_context >= MAX_RSS_GROUPS)
|
||||
return -ENOENT;
|
||||
|
||||
rss_ctx = rss->rss_ctx[rss_context];
|
||||
if (!rss_ctx)
|
||||
return -ENOENT;
|
||||
|
||||
if (indir) {
|
||||
for (idx = 0; idx < rss->rss_size; idx++) {
|
||||
/* Ignore if the rx queue is AF_XDP zero copy enabled */
|
||||
if (test_bit(rss_ctx->ind_tbl[idx], pfvf->af_xdp_zc_qidx))
|
||||
continue;
|
||||
indir[idx] = rss_ctx->ind_tbl[idx];
|
||||
}
|
||||
for (idx = 0; idx < rss->rss_size; idx++) {
|
||||
/* Ignore if the rx queue is AF_XDP zero copy enabled */
|
||||
if (test_bit(rss->ind_tbl[idx], pfvf->af_xdp_zc_qidx))
|
||||
continue;
|
||||
indir[idx] = rss->ind_tbl[idx];
|
||||
}
|
||||
if (rxfh->key)
|
||||
memcpy(rxfh->key, rss->key, sizeof(rss->key));
|
||||
|
|
@ -1307,12 +1316,12 @@ static void otx2_get_fec_stats(struct net_device *netdev,
|
|||
}
|
||||
|
||||
static const struct ethtool_ops otx2_ethtool_ops = {
|
||||
.cap_rss_ctx_supported = true,
|
||||
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
|
||||
ETHTOOL_COALESCE_MAX_FRAMES |
|
||||
ETHTOOL_COALESCE_USE_ADAPTIVE,
|
||||
.supported_ring_params = ETHTOOL_RING_USE_RX_BUF_LEN |
|
||||
ETHTOOL_RING_USE_CQE_SIZE,
|
||||
.rxfh_max_num_contexts = MAX_RSS_GROUPS,
|
||||
.get_link = otx2_get_link,
|
||||
.get_drvinfo = otx2_get_drvinfo,
|
||||
.get_strings = otx2_get_strings,
|
||||
|
|
@ -1332,6 +1341,9 @@ static const struct ethtool_ops otx2_ethtool_ops = {
|
|||
.set_rxfh = otx2_set_rxfh,
|
||||
.get_rxfh_fields = otx2_get_rss_hash_opts,
|
||||
.set_rxfh_fields = otx2_set_rss_hash_opts,
|
||||
.create_rxfh_context = otx2_create_rxfh,
|
||||
.modify_rxfh_context = otx2_modify_rxfh,
|
||||
.remove_rxfh_context = otx2_remove_rxfh,
|
||||
.get_msglevel = otx2_get_msglevel,
|
||||
.set_msglevel = otx2_set_msglevel,
|
||||
.get_pauseparam = otx2_get_pauseparam,
|
||||
|
|
@ -1426,12 +1438,12 @@ static int otx2vf_get_link_ksettings(struct net_device *netdev,
|
|||
}
|
||||
|
||||
static const struct ethtool_ops otx2vf_ethtool_ops = {
|
||||
.cap_rss_ctx_supported = true,
|
||||
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
|
||||
ETHTOOL_COALESCE_MAX_FRAMES |
|
||||
ETHTOOL_COALESCE_USE_ADAPTIVE,
|
||||
.supported_ring_params = ETHTOOL_RING_USE_RX_BUF_LEN |
|
||||
ETHTOOL_RING_USE_CQE_SIZE,
|
||||
.rxfh_max_num_contexts = MAX_RSS_GROUPS,
|
||||
.get_link = otx2_get_link,
|
||||
.get_drvinfo = otx2vf_get_drvinfo,
|
||||
.get_strings = otx2vf_get_strings,
|
||||
|
|
@ -1447,6 +1459,9 @@ static const struct ethtool_ops otx2vf_ethtool_ops = {
|
|||
.set_rxfh = otx2_set_rxfh,
|
||||
.get_rxfh_fields = otx2_get_rss_hash_opts,
|
||||
.set_rxfh_fields = otx2_set_rss_hash_opts,
|
||||
.create_rxfh_context = otx2_create_rxfh,
|
||||
.modify_rxfh_context = otx2_modify_rxfh,
|
||||
.remove_rxfh_context = otx2_remove_rxfh,
|
||||
.get_ringparam = otx2_get_ringparam,
|
||||
.set_ringparam = otx2_set_ringparam,
|
||||
.get_coalesce = otx2_get_coalesce,
|
||||
|
|
|
|||
|
|
@ -2158,7 +2158,6 @@ int otx2_stop(struct net_device *netdev)
|
|||
struct otx2_nic *pf = netdev_priv(netdev);
|
||||
struct otx2_cq_poll *cq_poll = NULL;
|
||||
struct otx2_qset *qset = &pf->qset;
|
||||
struct otx2_rss_info *rss;
|
||||
int qidx, vec, wrk;
|
||||
|
||||
/* If the DOWN flag is set resources are already freed */
|
||||
|
|
@ -2176,10 +2175,7 @@ int otx2_stop(struct net_device *netdev)
|
|||
otx2_rxtx_enable(pf, false);
|
||||
|
||||
/* Clear RSS enable flag */
|
||||
rss = &pf->hw.rss_info;
|
||||
rss->enable = false;
|
||||
if (!netif_is_rxfh_configured(netdev))
|
||||
kfree(rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP]);
|
||||
pf->hw.rss_info.enable = false;
|
||||
|
||||
/* Cleanup Queue IRQ */
|
||||
vec = pci_irq_vector(pf->pdev,
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ int otx2_xsk_pool_enable(struct otx2_nic *pf, struct xsk_buff_pool *pool, u16 qi
|
|||
set_bit(qidx, pf->af_xdp_zc_qidx);
|
||||
otx2_clean_up_rq(pf, qidx);
|
||||
/* Reconfigure RSS table as 'qidx' cannot be part of RSS now */
|
||||
otx2_set_rss_table(pf, DEFAULT_RSS_CONTEXT_GROUP);
|
||||
otx2_set_rss_table(pf, DEFAULT_RSS_CONTEXT_GROUP, NULL);
|
||||
/* Kick start the NAPI context so that receiving will start */
|
||||
return otx2_xsk_wakeup(pf->netdev, qidx, XDP_WAKEUP_RX);
|
||||
}
|
||||
|
|
@ -153,7 +153,7 @@ int otx2_xsk_pool_disable(struct otx2_nic *pf, u16 qidx)
|
|||
clear_bit(qidx, pf->af_xdp_zc_qidx);
|
||||
xsk_pool_dma_unmap(pool, DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING);
|
||||
/* Reconfigure RSS table as 'qidx' now need to be part of RSS now */
|
||||
otx2_set_rss_table(pf, DEFAULT_RSS_CONTEXT_GROUP);
|
||||
otx2_set_rss_table(pf, DEFAULT_RSS_CONTEXT_GROUP, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -567,7 +567,8 @@ int mlx5e_rss_packet_merge_set_param(struct mlx5e_rss *rss,
|
|||
return final_err;
|
||||
}
|
||||
|
||||
int mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc, bool *symmetric)
|
||||
void mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc,
|
||||
bool *symmetric)
|
||||
{
|
||||
if (indir)
|
||||
memcpy(indir, rss->indir.table,
|
||||
|
|
@ -582,8 +583,6 @@ int mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc, bo
|
|||
|
||||
if (symmetric)
|
||||
*symmetric = rss->hash.symmetric;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ void mlx5e_rss_disable(struct mlx5e_rss *rss);
|
|||
|
||||
int mlx5e_rss_packet_merge_set_param(struct mlx5e_rss *rss,
|
||||
struct mlx5e_packet_merge_param *pkt_merge_param);
|
||||
int mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc, bool *symmetric);
|
||||
void mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc,
|
||||
bool *symmetric);
|
||||
int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
|
||||
const u8 *key, const u8 *hfunc, const bool *symmetric,
|
||||
u32 *rqns, u32 *vhca_ids, unsigned int num_rqns);
|
||||
|
|
|
|||
|
|
@ -71,17 +71,12 @@ static int mlx5e_rx_res_rss_init_def(struct mlx5e_rx_res *res,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 *rss_idx, unsigned int init_nch)
|
||||
int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 rss_idx, unsigned int init_nch)
|
||||
{
|
||||
bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
|
||||
struct mlx5e_rss *rss;
|
||||
int i;
|
||||
|
||||
for (i = 1; i < MLX5E_MAX_NUM_RSS; i++)
|
||||
if (!res->rss[i])
|
||||
break;
|
||||
|
||||
if (i == MLX5E_MAX_NUM_RSS)
|
||||
if (WARN_ON_ONCE(res->rss[rss_idx]))
|
||||
return -ENOSPC;
|
||||
|
||||
rss = mlx5e_rss_init(res->mdev, inner_ft_support, res->drop_rqn,
|
||||
|
|
@ -97,8 +92,7 @@ int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 *rss_idx, unsigned int i
|
|||
mlx5e_rss_enable(rss, res->rss_rqns, vhca_ids, res->rss_nch);
|
||||
}
|
||||
|
||||
res->rss[i] = rss;
|
||||
*rss_idx = i;
|
||||
res->rss[rss_idx] = rss;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -193,19 +187,17 @@ void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int n
|
|||
mlx5e_rss_set_indir_uniform(res->rss[0], nch);
|
||||
}
|
||||
|
||||
int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
|
||||
u32 *indir, u8 *key, u8 *hfunc, bool *symmetric)
|
||||
void mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
|
||||
u32 *indir, u8 *key, u8 *hfunc, bool *symmetric)
|
||||
{
|
||||
struct mlx5e_rss *rss;
|
||||
struct mlx5e_rss *rss = NULL;
|
||||
|
||||
if (rss_idx >= MLX5E_MAX_NUM_RSS)
|
||||
return -EINVAL;
|
||||
if (rss_idx < MLX5E_MAX_NUM_RSS)
|
||||
rss = res->rss[rss_idx];
|
||||
if (WARN_ON_ONCE(!rss))
|
||||
return;
|
||||
|
||||
rss = res->rss[rss_idx];
|
||||
if (!rss)
|
||||
return -ENOENT;
|
||||
|
||||
return mlx5e_rss_get_rxfh(rss, indir, key, hfunc, symmetric);
|
||||
mlx5e_rss_get_rxfh(rss, indir, key, hfunc, symmetric);
|
||||
}
|
||||
|
||||
int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
|
||||
|
|
|
|||
|
|
@ -48,8 +48,9 @@ void mlx5e_rx_res_xsk_update(struct mlx5e_rx_res *res, struct mlx5e_channels *ch
|
|||
|
||||
/* Configuration API */
|
||||
void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int nch);
|
||||
int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
|
||||
u32 *indir, u8 *key, u8 *hfunc, bool *symmetric);
|
||||
void mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
|
||||
u32 *indir, u8 *key, u8 *hfunc,
|
||||
bool *symmetric);
|
||||
int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
|
||||
const u32 *indir, const u8 *key, const u8 *hfunc,
|
||||
const bool *symmetric);
|
||||
|
|
@ -61,7 +62,7 @@ int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, u32 rss_idx,
|
|||
int mlx5e_rx_res_packet_merge_set_param(struct mlx5e_rx_res *res,
|
||||
struct mlx5e_packet_merge_param *pkt_merge_param);
|
||||
|
||||
int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 *rss_idx, unsigned int init_nch);
|
||||
int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 rss_idx, unsigned int init_nch);
|
||||
int mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res, u32 rss_idx);
|
||||
int mlx5e_rx_res_rss_cnt(struct mlx5e_rx_res *res);
|
||||
int mlx5e_rx_res_rss_index(struct mlx5e_rx_res *res, struct mlx5e_rss *rss);
|
||||
|
|
|
|||
|
|
@ -1480,61 +1480,55 @@ static u32 mlx5e_get_rxfh_indir_size(struct net_device *netdev)
|
|||
static int mlx5e_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
|
||||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(netdev);
|
||||
u32 rss_context = rxfh->rss_context;
|
||||
bool symmetric;
|
||||
int err;
|
||||
|
||||
mutex_lock(&priv->state_lock);
|
||||
err = mlx5e_rx_res_rss_get_rxfh(priv->rx_res, rss_context,
|
||||
rxfh->indir, rxfh->key, &rxfh->hfunc, &symmetric);
|
||||
mlx5e_rx_res_rss_get_rxfh(priv->rx_res, 0, rxfh->indir, rxfh->key,
|
||||
&rxfh->hfunc, &symmetric);
|
||||
mutex_unlock(&priv->state_lock);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (symmetric)
|
||||
rxfh->input_xfrm = RXH_XFRM_SYM_OR_XOR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlx5e_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
|
||||
static int mlx5e_rxfh_hfunc_check(struct mlx5e_priv *priv,
|
||||
const struct ethtool_rxfh_param *rxfh)
|
||||
{
|
||||
unsigned int count;
|
||||
|
||||
count = priv->channels.params.num_channels;
|
||||
|
||||
if (rxfh->hfunc == ETH_RSS_HASH_XOR) {
|
||||
unsigned int xor8_max_channels = mlx5e_rqt_max_num_channels_allowed_for_xor8();
|
||||
|
||||
if (count > xor8_max_channels) {
|
||||
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",
|
||||
__func__, count, xor8_max_channels);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlx5e_set_rxfh(struct net_device *dev,
|
||||
struct ethtool_rxfh_param *rxfh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
bool symmetric = rxfh->input_xfrm == RXH_XFRM_SYM_OR_XOR;
|
||||
struct mlx5e_priv *priv = netdev_priv(dev);
|
||||
u32 *rss_context = &rxfh->rss_context;
|
||||
u8 hfunc = rxfh->hfunc;
|
||||
unsigned int count;
|
||||
int err;
|
||||
|
||||
mutex_lock(&priv->state_lock);
|
||||
|
||||
count = priv->channels.params.num_channels;
|
||||
|
||||
if (hfunc == ETH_RSS_HASH_XOR) {
|
||||
unsigned int xor8_max_channels = mlx5e_rqt_max_num_channels_allowed_for_xor8();
|
||||
|
||||
if (count > xor8_max_channels) {
|
||||
err = -EINVAL;
|
||||
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",
|
||||
__func__, count, xor8_max_channels);
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
|
||||
if (*rss_context && rxfh->rss_delete) {
|
||||
err = mlx5e_rx_res_rss_destroy(priv->rx_res, *rss_context);
|
||||
err = mlx5e_rxfh_hfunc_check(priv, rxfh);
|
||||
if (err)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
|
||||
err = mlx5e_rx_res_rss_init(priv->rx_res, rss_context, count);
|
||||
if (err)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, *rss_context,
|
||||
err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, rxfh->rss_context,
|
||||
rxfh->indir, rxfh->key,
|
||||
hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc,
|
||||
rxfh->input_xfrm == RXH_XFRM_NO_CHANGE ? NULL : &symmetric);
|
||||
|
|
@ -1544,6 +1538,86 @@ static int mlx5e_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxf
|
|||
return err;
|
||||
}
|
||||
|
||||
static int mlx5e_create_rxfh_context(struct net_device *dev,
|
||||
struct ethtool_rxfh_context *ctx,
|
||||
const struct ethtool_rxfh_param *rxfh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
bool symmetric = rxfh->input_xfrm == RXH_XFRM_SYM_OR_XOR;
|
||||
struct mlx5e_priv *priv = netdev_priv(dev);
|
||||
u8 hfunc = rxfh->hfunc;
|
||||
int err;
|
||||
|
||||
mutex_lock(&priv->state_lock);
|
||||
|
||||
err = mlx5e_rxfh_hfunc_check(priv, rxfh);
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
err = mlx5e_rx_res_rss_init(priv->rx_res, rxfh->rss_context,
|
||||
priv->channels.params.num_channels);
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, rxfh->rss_context,
|
||||
rxfh->indir, rxfh->key,
|
||||
hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc,
|
||||
rxfh->input_xfrm == RXH_XFRM_NO_CHANGE ? NULL : &symmetric);
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
mlx5e_rx_res_rss_get_rxfh(priv->rx_res, rxfh->rss_context,
|
||||
ethtool_rxfh_context_indir(ctx),
|
||||
ethtool_rxfh_context_key(ctx),
|
||||
&ctx->hfunc, &symmetric);
|
||||
if (symmetric)
|
||||
ctx->input_xfrm = RXH_XFRM_SYM_OR_XOR;
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&priv->state_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mlx5e_modify_rxfh_context(struct net_device *dev,
|
||||
struct ethtool_rxfh_context *ctx,
|
||||
const struct ethtool_rxfh_param *rxfh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
bool symmetric = rxfh->input_xfrm == RXH_XFRM_SYM_OR_XOR;
|
||||
struct mlx5e_priv *priv = netdev_priv(dev);
|
||||
u8 hfunc = rxfh->hfunc;
|
||||
int err;
|
||||
|
||||
mutex_lock(&priv->state_lock);
|
||||
|
||||
err = mlx5e_rxfh_hfunc_check(priv, rxfh);
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, rxfh->rss_context,
|
||||
rxfh->indir, rxfh->key,
|
||||
hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc,
|
||||
rxfh->input_xfrm == RXH_XFRM_NO_CHANGE ? NULL : &symmetric);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&priv->state_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mlx5e_remove_rxfh_context(struct net_device *dev,
|
||||
struct ethtool_rxfh_context *ctx,
|
||||
u32 rss_context,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(dev);
|
||||
int err;
|
||||
|
||||
mutex_lock(&priv->state_lock);
|
||||
err = mlx5e_rx_res_rss_destroy(priv->rx_res, rss_context);
|
||||
mutex_unlock(&priv->state_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
#define MLX5E_PFC_PREVEN_AUTO_TOUT_MSEC 100
|
||||
#define MLX5E_PFC_PREVEN_TOUT_MAX_MSEC 8000
|
||||
#define MLX5E_PFC_PREVEN_MINOR_PRECENT 85
|
||||
|
|
@ -2654,9 +2728,9 @@ static void mlx5e_get_ts_stats(struct net_device *netdev,
|
|||
|
||||
const struct ethtool_ops mlx5e_ethtool_ops = {
|
||||
.cap_link_lanes_supported = true,
|
||||
.cap_rss_ctx_supported = true,
|
||||
.rxfh_per_ctx_fields = true,
|
||||
.rxfh_per_ctx_key = true,
|
||||
.rxfh_max_num_contexts = MLX5E_MAX_NUM_RSS,
|
||||
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
|
||||
ETHTOOL_COALESCE_MAX_FRAMES |
|
||||
ETHTOOL_COALESCE_USE_ADAPTIVE |
|
||||
|
|
@ -2685,6 +2759,9 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
|
|||
.set_rxfh = mlx5e_set_rxfh,
|
||||
.get_rxfh_fields = mlx5e_get_rxfh_fields,
|
||||
.set_rxfh_fields = mlx5e_set_rxfh_fields,
|
||||
.create_rxfh_context = mlx5e_create_rxfh_context,
|
||||
.modify_rxfh_context = mlx5e_modify_rxfh_context,
|
||||
.remove_rxfh_context = mlx5e_remove_rxfh_context,
|
||||
.get_rxnfc = mlx5e_get_rxnfc,
|
||||
.set_rxnfc = mlx5e_set_rxnfc,
|
||||
.get_tunable = mlx5e_get_tunable,
|
||||
|
|
|
|||
|
|
@ -865,9 +865,6 @@ struct kernel_ethtool_ts_info {
|
|||
* @supported_input_xfrm: supported types of input xfrm from %RXH_XFRM_*.
|
||||
* @cap_link_lanes_supported: indicates if the driver supports lanes
|
||||
* parameter.
|
||||
* @cap_rss_ctx_supported: indicates if the driver supports RSS
|
||||
* contexts via legacy API, drivers implementing @create_rxfh_context
|
||||
* do not have to set this bit.
|
||||
* @rxfh_per_ctx_fields: device supports selecting different header fields
|
||||
* for Rx hash calculation and RSS for each additional context.
|
||||
* @rxfh_per_ctx_key: device supports setting different RSS key for each
|
||||
|
|
@ -1100,7 +1097,6 @@ struct kernel_ethtool_ts_info {
|
|||
struct ethtool_ops {
|
||||
u32 supported_input_xfrm:8;
|
||||
u32 cap_link_lanes_supported:1;
|
||||
u32 cap_rss_ctx_supported:1;
|
||||
u32 rxfh_per_ctx_fields:1;
|
||||
u32 rxfh_per_ctx_key:1;
|
||||
u32 cap_rss_rxnfc_adds:1;
|
||||
|
|
|
|||
|
|
@ -11979,21 +11979,8 @@ static void netdev_rss_contexts_free(struct net_device *dev)
|
|||
|
||||
mutex_lock(&dev->ethtool->rss_lock);
|
||||
xa_for_each(&dev->ethtool->rss_ctx, context, ctx) {
|
||||
struct ethtool_rxfh_param rxfh;
|
||||
|
||||
rxfh.indir = ethtool_rxfh_context_indir(ctx);
|
||||
rxfh.key = ethtool_rxfh_context_key(ctx);
|
||||
rxfh.hfunc = ctx->hfunc;
|
||||
rxfh.input_xfrm = ctx->input_xfrm;
|
||||
rxfh.rss_context = context;
|
||||
rxfh.rss_delete = true;
|
||||
|
||||
xa_erase(&dev->ethtool->rss_ctx, context);
|
||||
if (dev->ethtool_ops->create_rxfh_context)
|
||||
dev->ethtool_ops->remove_rxfh_context(dev, ctx,
|
||||
context, NULL);
|
||||
else
|
||||
dev->ethtool_ops->set_rxfh(dev, &rxfh, NULL);
|
||||
dev->ethtool_ops->remove_rxfh_context(dev, ctx, context, NULL);
|
||||
kfree(ctx);
|
||||
}
|
||||
xa_destroy(&dev->ethtool->rss_ctx);
|
||||
|
|
|
|||
|
|
@ -1391,8 +1391,7 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev,
|
|||
if (rxfh.rsvd8[0] || rxfh.rsvd8[1] || rxfh.rsvd32)
|
||||
return -EINVAL;
|
||||
/* Most drivers don't handle rss_context, check it's 0 as well */
|
||||
if (rxfh.rss_context && !(ops->cap_rss_ctx_supported ||
|
||||
ops->create_rxfh_context))
|
||||
if (rxfh.rss_context && !ops->create_rxfh_context)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
rxfh.indir_size = rxfh_dev.indir_size;
|
||||
|
|
@ -1534,8 +1533,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
|
|||
if (rxfh.rsvd8[0] || rxfh.rsvd8[1] || rxfh.rsvd32)
|
||||
return -EINVAL;
|
||||
/* Most drivers don't handle rss_context, check it's 0 as well */
|
||||
if (rxfh.rss_context && !(ops->cap_rss_ctx_supported ||
|
||||
ops->create_rxfh_context))
|
||||
if (rxfh.rss_context && !ops->create_rxfh_context)
|
||||
return -EOPNOTSUPP;
|
||||
/* Check input data transformation capabilities */
|
||||
if (rxfh.input_xfrm && rxfh.input_xfrm != RXH_XFRM_SYM_XOR &&
|
||||
|
|
@ -1634,6 +1632,8 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
|
|||
}
|
||||
|
||||
if (create) {
|
||||
u32 limit, ctx_id;
|
||||
|
||||
if (rxfh_dev.rss_delete) {
|
||||
ret = -EINVAL;
|
||||
goto out_unlock;
|
||||
|
|
@ -1644,21 +1644,15 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (ops->create_rxfh_context) {
|
||||
u32 limit = ops->rxfh_max_num_contexts ?: U32_MAX;
|
||||
u32 ctx_id;
|
||||
|
||||
/* driver uses new API, core allocates ID */
|
||||
ret = xa_alloc(&dev->ethtool->rss_ctx, &ctx_id, ctx,
|
||||
XA_LIMIT(1, limit - 1),
|
||||
GFP_KERNEL_ACCOUNT);
|
||||
if (ret < 0) {
|
||||
kfree(ctx);
|
||||
goto out_unlock;
|
||||
}
|
||||
WARN_ON(!ctx_id); /* can't happen */
|
||||
rxfh.rss_context = ctx_id;
|
||||
limit = ops->rxfh_max_num_contexts ?: U32_MAX;
|
||||
ret = xa_alloc(&dev->ethtool->rss_ctx, &ctx_id, ctx,
|
||||
XA_LIMIT(1, limit - 1), GFP_KERNEL_ACCOUNT);
|
||||
if (ret < 0) {
|
||||
kfree(ctx);
|
||||
goto out_unlock;
|
||||
}
|
||||
WARN_ON(!ctx_id); /* can't happen */
|
||||
rxfh.rss_context = ctx_id;
|
||||
} else if (rxfh.rss_context) {
|
||||
ctx = xa_load(&dev->ethtool->rss_ctx, rxfh.rss_context);
|
||||
if (!ctx) {
|
||||
|
|
@ -1670,31 +1664,24 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
|
|||
rxfh_dev.rss_context = rxfh.rss_context;
|
||||
rxfh_dev.input_xfrm = rxfh.input_xfrm;
|
||||
|
||||
if (rxfh.rss_context && ops->create_rxfh_context) {
|
||||
if (create) {
|
||||
ret = ops->create_rxfh_context(dev, ctx, &rxfh_dev,
|
||||
extack);
|
||||
/* Make sure driver populates defaults */
|
||||
WARN_ON_ONCE(!ret && !rxfh_dev.key &&
|
||||
ops->rxfh_per_ctx_key &&
|
||||
!memchr_inv(ethtool_rxfh_context_key(ctx),
|
||||
0, ctx->key_size));
|
||||
} else if (rxfh_dev.rss_delete) {
|
||||
ret = ops->remove_rxfh_context(dev, ctx,
|
||||
rxfh.rss_context,
|
||||
extack);
|
||||
} else {
|
||||
ret = ops->modify_rxfh_context(dev, ctx, &rxfh_dev,
|
||||
extack);
|
||||
}
|
||||
} else {
|
||||
if (!rxfh.rss_context) {
|
||||
ret = ops->set_rxfh(dev, &rxfh_dev, extack);
|
||||
} else if (create) {
|
||||
ret = ops->create_rxfh_context(dev, ctx, &rxfh_dev, extack);
|
||||
/* Make sure driver populates defaults */
|
||||
WARN_ON_ONCE(!ret && !rxfh_dev.key && ops->rxfh_per_ctx_key &&
|
||||
!memchr_inv(ethtool_rxfh_context_key(ctx), 0,
|
||||
ctx->key_size));
|
||||
} else if (rxfh_dev.rss_delete) {
|
||||
ret = ops->remove_rxfh_context(dev, ctx, rxfh.rss_context,
|
||||
extack);
|
||||
} else {
|
||||
ret = ops->modify_rxfh_context(dev, ctx, &rxfh_dev, extack);
|
||||
}
|
||||
if (ret) {
|
||||
if (create) {
|
||||
/* failed to create, free our new tracking entry */
|
||||
if (ops->create_rxfh_context)
|
||||
xa_erase(&dev->ethtool->rss_ctx, rxfh.rss_context);
|
||||
xa_erase(&dev->ethtool->rss_ctx, rxfh.rss_context);
|
||||
kfree(ctx);
|
||||
}
|
||||
goto out_unlock;
|
||||
|
|
@ -1713,36 +1700,6 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
|
|||
dev->priv_flags |= IFF_RXFH_CONFIGURED;
|
||||
}
|
||||
/* Update rss_ctx tracking */
|
||||
if (create && !ops->create_rxfh_context) {
|
||||
/* driver uses old API, it chose context ID */
|
||||
if (WARN_ON(xa_load(&dev->ethtool->rss_ctx, rxfh_dev.rss_context))) {
|
||||
/* context ID reused, our tracking is screwed */
|
||||
kfree(ctx);
|
||||
goto out_unlock;
|
||||
}
|
||||
/* Allocate the exact ID the driver gave us */
|
||||
if (xa_is_err(xa_store(&dev->ethtool->rss_ctx, rxfh_dev.rss_context,
|
||||
ctx, GFP_KERNEL))) {
|
||||
kfree(ctx);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* Fetch the defaults for the old API, in the new API drivers
|
||||
* should write defaults into ctx themselves.
|
||||
*/
|
||||
rxfh_dev.indir = (u32 *)rss_config;
|
||||
rxfh_dev.indir_size = dev_indir_size;
|
||||
|
||||
rxfh_dev.key = rss_config + indir_bytes;
|
||||
rxfh_dev.key_size = dev_key_size;
|
||||
|
||||
ret = ops->get_rxfh(dev, &rxfh_dev);
|
||||
if (WARN_ON(ret)) {
|
||||
xa_erase(&dev->ethtool->rss_ctx, rxfh.rss_context);
|
||||
kfree(ctx);
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
if (rxfh_dev.rss_delete) {
|
||||
WARN_ON(xa_erase(&dev->ethtool->rss_ctx, rxfh.rss_context) != ctx);
|
||||
kfree(ctx);
|
||||
|
|
|
|||
|
|
@ -163,8 +163,7 @@ rss_prepare_data(const struct ethnl_req_info *req_base,
|
|||
return -EOPNOTSUPP;
|
||||
|
||||
/* Some drivers don't handle rss_context */
|
||||
if (request->rss_context &&
|
||||
!ops->cap_rss_ctx_supported && !ops->create_rxfh_context)
|
||||
if (request->rss_context && !ops->create_rxfh_context)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mutex_lock(&dev->ethtool->rss_lock);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user