Skip to content

Commit a9ee8d4

Browse files
Edward Creekuba-moo
authored andcommitted
sfc: use new rxfh_context API
The core is now responsible for allocating IDs and a memory region for us to store our state (struct efx_rss_context_priv), so we no longer need efx_alloc_rss_context_entry() and friends. Since the contexts are now maintained by the core, use the core's lock (net_dev->ethtool->rss_lock), rather than our own mutex (efx->rss_lock), to serialise access against changes; and remove the now-unused efx->rss_lock from struct efx_nic. Signed-off-by: Edward Cree <[email protected]> Reviewed-by: Przemek Kitszel <[email protected]> Link: https://patch.msgid.link/150274740ea8cc137fef5502541ce573d32fb319.1719502240.git.ecree.xilinx@gmail.com Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 8792515 commit a9ee8d4

File tree

13 files changed

+212
-219
lines changed

13 files changed

+212
-219
lines changed

drivers/net/ethernet/sfc/ef10.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1396,7 +1396,7 @@ static void efx_ef10_table_reset_mc_allocations(struct efx_nic *efx)
13961396
efx_mcdi_filter_table_reset_mc_allocations(efx);
13971397
nic_data->must_restore_piobufs = true;
13981398
efx_ef10_forget_old_piobufs(efx);
1399-
efx->rss_context.context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
1399+
efx->rss_context.priv.context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
14001400

14011401
/* Driver-created vswitches and vports must be re-created */
14021402
nic_data->must_probe_vswitching = true;

drivers/net/ethernet/sfc/ef100_ethtool.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,12 @@ const struct ethtool_ops ef100_ethtool_ops = {
5959

6060
.get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size,
6161
.get_rxfh_key_size = efx_ethtool_get_rxfh_key_size,
62+
.rxfh_priv_size = sizeof(struct efx_rss_context_priv),
6263
.get_rxfh = efx_ethtool_get_rxfh,
6364
.set_rxfh = efx_ethtool_set_rxfh,
65+
.create_rxfh_context = efx_ethtool_create_rxfh_context,
66+
.modify_rxfh_context = efx_ethtool_modify_rxfh_context,
67+
.remove_rxfh_context = efx_ethtool_remove_rxfh_context,
6468

6569
.get_module_info = efx_ethtool_get_module_info,
6670
.get_module_eeprom = efx_ethtool_get_module_eeprom,

drivers/net/ethernet/sfc/efx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ static int efx_probe_nic(struct efx_nic *efx)
299299
if (efx->n_channels > 1)
300300
netdev_rss_key_fill(efx->rss_context.rx_hash_key,
301301
sizeof(efx->rss_context.rx_hash_key));
302-
efx_set_default_rx_indir_table(efx, &efx->rss_context);
302+
efx_set_default_rx_indir_table(efx, efx->rss_context.rx_indir_table);
303303

304304
/* Initialise the interrupt moderation settings */
305305
efx->irq_mod_step_us = DIV_ROUND_UP(efx->timer_quantum_ns, 1000);

drivers/net/ethernet/sfc/efx.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ static inline s32 efx_filter_get_rx_ids(struct efx_nic *efx,
158158
}
159159

160160
/* RSS contexts */
161-
static inline bool efx_rss_active(struct efx_rss_context *ctx)
161+
static inline bool efx_rss_active(struct efx_rss_context_priv *ctx)
162162
{
163163
return ctx->context_id != EFX_MCDI_RSS_CONTEXT_INVALID;
164164
}

drivers/net/ethernet/sfc/efx_common.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method)
714714

715715
mutex_lock(&efx->mac_lock);
716716
down_write(&efx->filter_sem);
717-
mutex_lock(&efx->rss_lock);
717+
mutex_lock(&efx->net_dev->ethtool->rss_lock);
718718
efx->type->fini(efx);
719719
}
720720

@@ -777,7 +777,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
777777

778778
if (efx->type->rx_restore_rss_contexts)
779779
efx->type->rx_restore_rss_contexts(efx);
780-
mutex_unlock(&efx->rss_lock);
780+
mutex_unlock(&efx->net_dev->ethtool->rss_lock);
781781
efx->type->filter_table_restore(efx);
782782
up_write(&efx->filter_sem);
783783

@@ -793,7 +793,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
793793
fail:
794794
efx->port_initialized = false;
795795

796-
mutex_unlock(&efx->rss_lock);
796+
mutex_unlock(&efx->net_dev->ethtool->rss_lock);
797797
up_write(&efx->filter_sem);
798798
mutex_unlock(&efx->mac_lock);
799799

@@ -1000,9 +1000,7 @@ int efx_init_struct(struct efx_nic *efx, struct pci_dev *pci_dev)
10001000
efx->type->rx_hash_offset - efx->type->rx_prefix_size;
10011001
efx->rx_packet_ts_offset =
10021002
efx->type->rx_ts_offset - efx->type->rx_prefix_size;
1003-
INIT_LIST_HEAD(&efx->rss_context.list);
1004-
efx->rss_context.context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
1005-
mutex_init(&efx->rss_lock);
1003+
efx->rss_context.priv.context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
10061004
efx->vport_id = EVB_PORT_ID_ASSIGNED;
10071005
spin_lock_init(&efx->stats_lock);
10081006
efx->vi_stride = EFX_DEFAULT_VI_STRIDE;

drivers/net/ethernet/sfc/ethtool.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,12 @@ const struct ethtool_ops efx_ethtool_ops = {
268268
.set_rxnfc = efx_ethtool_set_rxnfc,
269269
.get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size,
270270
.get_rxfh_key_size = efx_ethtool_get_rxfh_key_size,
271+
.rxfh_priv_size = sizeof(struct efx_rss_context_priv),
271272
.get_rxfh = efx_ethtool_get_rxfh,
272273
.set_rxfh = efx_ethtool_set_rxfh,
274+
.create_rxfh_context = efx_ethtool_create_rxfh_context,
275+
.modify_rxfh_context = efx_ethtool_modify_rxfh_context,
276+
.remove_rxfh_context = efx_ethtool_remove_rxfh_context,
273277
.get_ts_info = efx_ethtool_get_ts_info,
274278
.get_module_info = efx_ethtool_get_module_info,
275279
.get_module_eeprom = efx_ethtool_get_module_eeprom,

drivers/net/ethernet/sfc/ethtool_common.c

Lines changed: 86 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -820,10 +820,10 @@ int efx_ethtool_get_rxnfc(struct net_device *net_dev,
820820
return 0;
821821

822822
case ETHTOOL_GRXFH: {
823-
struct efx_rss_context *ctx = &efx->rss_context;
823+
struct efx_rss_context_priv *ctx = &efx->rss_context.priv;
824824
__u64 data;
825825

826-
mutex_lock(&efx->rss_lock);
826+
mutex_lock(&net_dev->ethtool->rss_lock);
827827
if (info->flow_type & FLOW_RSS && info->rss_context) {
828828
ctx = efx_find_rss_context_entry(efx, info->rss_context);
829829
if (!ctx) {
@@ -864,7 +864,7 @@ int efx_ethtool_get_rxnfc(struct net_device *net_dev,
864864
out_setdata_unlock:
865865
info->data = data;
866866
out_unlock:
867-
mutex_unlock(&efx->rss_lock);
867+
mutex_unlock(&net_dev->ethtool->rss_lock);
868868
return rc;
869869
}
870870

@@ -1167,31 +1167,33 @@ static int efx_ethtool_get_rxfh_context(struct net_device *net_dev,
11671167
struct ethtool_rxfh_param *rxfh)
11681168
{
11691169
struct efx_nic *efx = efx_netdev_priv(net_dev);
1170-
struct efx_rss_context *ctx;
1170+
struct efx_rss_context_priv *ctx_priv;
1171+
struct efx_rss_context ctx;
11711172
int rc = 0;
11721173

11731174
if (!efx->type->rx_pull_rss_context_config)
11741175
return -EOPNOTSUPP;
11751176

1176-
mutex_lock(&efx->rss_lock);
1177-
ctx = efx_find_rss_context_entry(efx, rxfh->rss_context);
1178-
if (!ctx) {
1177+
mutex_lock(&net_dev->ethtool->rss_lock);
1178+
ctx_priv = efx_find_rss_context_entry(efx, rxfh->rss_context);
1179+
if (!ctx_priv) {
11791180
rc = -ENOENT;
11801181
goto out_unlock;
11811182
}
1182-
rc = efx->type->rx_pull_rss_context_config(efx, ctx);
1183+
ctx.priv = *ctx_priv;
1184+
rc = efx->type->rx_pull_rss_context_config(efx, &ctx);
11831185
if (rc)
11841186
goto out_unlock;
11851187

11861188
rxfh->hfunc = ETH_RSS_HASH_TOP;
11871189
if (rxfh->indir)
1188-
memcpy(rxfh->indir, ctx->rx_indir_table,
1189-
sizeof(ctx->rx_indir_table));
1190+
memcpy(rxfh->indir, ctx.rx_indir_table,
1191+
sizeof(ctx.rx_indir_table));
11901192
if (rxfh->key)
1191-
memcpy(rxfh->key, ctx->rx_hash_key,
1193+
memcpy(rxfh->key, ctx.rx_hash_key,
11921194
efx->type->rx_hash_key_size);
11931195
out_unlock:
1194-
mutex_unlock(&efx->rss_lock);
1196+
mutex_unlock(&net_dev->ethtool->rss_lock);
11951197
return rc;
11961198
}
11971199

@@ -1218,68 +1220,85 @@ int efx_ethtool_get_rxfh(struct net_device *net_dev,
12181220
return 0;
12191221
}
12201222

1221-
static int efx_ethtool_set_rxfh_context(struct net_device *net_dev,
1222-
struct ethtool_rxfh_param *rxfh,
1223-
struct netlink_ext_ack *extack)
1223+
int efx_ethtool_modify_rxfh_context(struct net_device *net_dev,
1224+
struct ethtool_rxfh_context *ctx,
1225+
const struct ethtool_rxfh_param *rxfh,
1226+
struct netlink_ext_ack *extack)
12241227
{
12251228
struct efx_nic *efx = efx_netdev_priv(net_dev);
1226-
u32 *rss_context = &rxfh->rss_context;
1227-
struct efx_rss_context *ctx;
1228-
u32 *indir = rxfh->indir;
1229-
bool allocated = false;
1230-
u8 *key = rxfh->key;
1231-
int rc;
1229+
struct efx_rss_context_priv *priv;
1230+
const u32 *indir = rxfh->indir;
1231+
const u8 *key = rxfh->key;
12321232

1233-
if (!efx->type->rx_push_rss_context_config)
1233+
if (!efx->type->rx_push_rss_context_config) {
1234+
NL_SET_ERR_MSG_MOD(extack,
1235+
"NIC type does not support custom contexts");
12341236
return -EOPNOTSUPP;
1235-
1236-
mutex_lock(&efx->rss_lock);
1237-
1238-
if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
1239-
if (rxfh->rss_delete) {
1240-
/* alloc + delete == Nothing to do */
1241-
rc = -EINVAL;
1242-
goto out_unlock;
1243-
}
1244-
ctx = efx_alloc_rss_context_entry(efx);
1245-
if (!ctx) {
1246-
rc = -ENOMEM;
1247-
goto out_unlock;
1248-
}
1249-
ctx->context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
1250-
/* Initialise indir table and key to defaults */
1251-
efx_set_default_rx_indir_table(efx, ctx);
1252-
netdev_rss_key_fill(ctx->rx_hash_key, sizeof(ctx->rx_hash_key));
1253-
allocated = true;
1254-
} else {
1255-
ctx = efx_find_rss_context_entry(efx, *rss_context);
1256-
if (!ctx) {
1257-
rc = -ENOENT;
1258-
goto out_unlock;
1259-
}
12601237
}
1261-
1262-
if (rxfh->rss_delete) {
1263-
/* delete this context */
1264-
rc = efx->type->rx_push_rss_context_config(efx, ctx, NULL, NULL);
1265-
if (!rc)
1266-
efx_free_rss_context_entry(ctx);
1267-
goto out_unlock;
1238+
/* Hash function is Toeplitz, cannot be changed */
1239+
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
1240+
rxfh->hfunc != ETH_RSS_HASH_TOP) {
1241+
NL_SET_ERR_MSG_MOD(extack, "Only Toeplitz hash is supported");
1242+
return -EOPNOTSUPP;
12681243
}
12691244

1245+
priv = ethtool_rxfh_context_priv(ctx);
1246+
12701247
if (!key)
1271-
key = ctx->rx_hash_key;
1248+
key = ethtool_rxfh_context_key(ctx);
12721249
if (!indir)
1273-
indir = ctx->rx_indir_table;
1250+
indir = ethtool_rxfh_context_indir(ctx);
12741251

1275-
rc = efx->type->rx_push_rss_context_config(efx, ctx, indir, key);
1276-
if (rc && allocated)
1277-
efx_free_rss_context_entry(ctx);
1278-
else
1279-
*rss_context = ctx->user_id;
1280-
out_unlock:
1281-
mutex_unlock(&efx->rss_lock);
1282-
return rc;
1252+
return efx->type->rx_push_rss_context_config(efx, priv, indir, key,
1253+
false);
1254+
}
1255+
1256+
int efx_ethtool_create_rxfh_context(struct net_device *net_dev,
1257+
struct ethtool_rxfh_context *ctx,
1258+
const struct ethtool_rxfh_param *rxfh,
1259+
struct netlink_ext_ack *extack)
1260+
{
1261+
struct efx_nic *efx = efx_netdev_priv(net_dev);
1262+
struct efx_rss_context_priv *priv;
1263+
1264+
priv = ethtool_rxfh_context_priv(ctx);
1265+
1266+
priv->context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
1267+
priv->rx_hash_udp_4tuple = false;
1268+
/* Generate default indir table and/or key if not specified.
1269+
* We use ctx as a place to store these; this is fine because
1270+
* we're doing a create, so if we fail then the ctx will just
1271+
* be deleted.
1272+
*/
1273+
if (!rxfh->indir)
1274+
efx_set_default_rx_indir_table(efx, ethtool_rxfh_context_indir(ctx));
1275+
if (!rxfh->key)
1276+
netdev_rss_key_fill(ethtool_rxfh_context_key(ctx),
1277+
ctx->key_size);
1278+
if (rxfh->hfunc == ETH_RSS_HASH_NO_CHANGE)
1279+
ctx->hfunc = ETH_RSS_HASH_TOP;
1280+
if (rxfh->input_xfrm == RXH_XFRM_NO_CHANGE)
1281+
ctx->input_xfrm = 0;
1282+
return efx_ethtool_modify_rxfh_context(net_dev, ctx, rxfh, extack);
1283+
}
1284+
1285+
int efx_ethtool_remove_rxfh_context(struct net_device *net_dev,
1286+
struct ethtool_rxfh_context *ctx,
1287+
u32 rss_context,
1288+
struct netlink_ext_ack *extack)
1289+
{
1290+
struct efx_nic *efx = efx_netdev_priv(net_dev);
1291+
struct efx_rss_context_priv *priv;
1292+
1293+
if (!efx->type->rx_push_rss_context_config) {
1294+
NL_SET_ERR_MSG_MOD(extack,
1295+
"NIC type does not support custom contexts");
1296+
return -EOPNOTSUPP;
1297+
}
1298+
1299+
priv = ethtool_rxfh_context_priv(ctx);
1300+
return efx->type->rx_push_rss_context_config(efx, priv, NULL, NULL,
1301+
true);
12831302
}
12841303

12851304
int efx_ethtool_set_rxfh(struct net_device *net_dev,
@@ -1295,8 +1314,9 @@ int efx_ethtool_set_rxfh(struct net_device *net_dev,
12951314
rxfh->hfunc != ETH_RSS_HASH_TOP)
12961315
return -EOPNOTSUPP;
12971316

1298-
if (rxfh->rss_context)
1299-
return efx_ethtool_set_rxfh_context(net_dev, rxfh, extack);
1317+
/* Custom contexts should use new API */
1318+
if (WARN_ON_ONCE(rxfh->rss_context))
1319+
return -EIO;
13001320

13011321
if (!indir && !key)
13021322
return 0;

drivers/net/ethernet/sfc/ethtool_common.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ int efx_ethtool_get_rxfh(struct net_device *net_dev,
4949
int efx_ethtool_set_rxfh(struct net_device *net_dev,
5050
struct ethtool_rxfh_param *rxfh,
5151
struct netlink_ext_ack *extack);
52+
int efx_ethtool_create_rxfh_context(struct net_device *net_dev,
53+
struct ethtool_rxfh_context *ctx,
54+
const struct ethtool_rxfh_param *rxfh,
55+
struct netlink_ext_ack *extack);
56+
int efx_ethtool_modify_rxfh_context(struct net_device *net_dev,
57+
struct ethtool_rxfh_context *ctx,
58+
const struct ethtool_rxfh_param *rxfh,
59+
struct netlink_ext_ack *extack);
60+
int efx_ethtool_remove_rxfh_context(struct net_device *net_dev,
61+
struct ethtool_rxfh_context *ctx,
62+
u32 rss_context,
63+
struct netlink_ext_ack *extack);
5264
int efx_ethtool_reset(struct net_device *net_dev, u32 *flags);
5365
int efx_ethtool_get_module_eeprom(struct net_device *net_dev,
5466
struct ethtool_eeprom *ee,

0 commit comments

Comments
 (0)