Skip to content

Commit 95dcd89

Browse files
committed
Merge branch 'several-fixes-for-indirect-flow_blocks-offload'
wenxu says: ==================== several fixes for indirect flow_blocks offload v2: patch2: store the cb_priv of representor to the flow_block_cb->indr.cb_priv in the driver. And make the correct check with the statments this->indr.cb_priv == cb_priv patch4: del the driver list only in the indriect cleanup callbacks v3: add the cover letter and changlogs. v4: collapsed 1/4, 2/4, 4/4 in v3 to one fix Add the prepare patch 1 and 2 v5: patch1: place flow_indr_block_cb_alloc() right before flow_indr_dev_setup_offload() to avoid moving flow_block_indr_init() This series fixes commit 1fac52d ("net: flow_offload: consolidate indirect flow_block infrastructure") that revists the flow_block infrastructure. patch #1 #2: prepare for fix patch #3 add and use flow_indr_block_cb_alloc/remove function patch #3: fix flow_indr_dev_unregister path If the representor is removed, then identify the indirect flow_blocks that need to be removed by the release callback and the port representor structure. To identify the port representor structure, a new indr.cb_priv field needs to be introduced. The flow_block also needs to be removed from the driver list from the cleanup path patch#4 fix block->nooffloaddevcnt warning dmesg log. When a indr device add in offload success. The block->nooffloaddevcnt should be 0. After the representor go away. When the dir device go away the flow_block UNBIND operation with -EOPNOTSUPP which lead the warning demesg log. The block->nooffloaddevcnt should always count for indr block. even the indr block offload successful. The representor maybe gone away and the ingress qdisc can work in software mode. ==================== Reviewed-by: Simon Horman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
2 parents 56c09de + 3c00511 commit 95dcd89

File tree

10 files changed

+110
-63
lines changed

10 files changed

+110
-63
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,7 +1889,8 @@ static void bnxt_tc_setup_indr_rel(void *cb_priv)
18891889
}
18901890

18911891
static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp,
1892-
struct flow_block_offload *f)
1892+
struct flow_block_offload *f, void *data,
1893+
void (*cleanup)(struct flow_block_cb *block_cb))
18931894
{
18941895
struct bnxt_flower_indr_block_cb_priv *cb_priv;
18951896
struct flow_block_cb *block_cb;
@@ -1907,9 +1908,10 @@ static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp,
19071908
cb_priv->bp = bp;
19081909
list_add(&cb_priv->list, &bp->tc_indr_block_list);
19091910

1910-
block_cb = flow_block_cb_alloc(bnxt_tc_setup_indr_block_cb,
1911-
cb_priv, cb_priv,
1912-
bnxt_tc_setup_indr_rel);
1911+
block_cb = flow_indr_block_cb_alloc(bnxt_tc_setup_indr_block_cb,
1912+
cb_priv, cb_priv,
1913+
bnxt_tc_setup_indr_rel, f,
1914+
netdev, data, bp, cleanup);
19131915
if (IS_ERR(block_cb)) {
19141916
list_del(&cb_priv->list);
19151917
kfree(cb_priv);
@@ -1930,7 +1932,7 @@ static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp,
19301932
if (!block_cb)
19311933
return -ENOENT;
19321934

1933-
flow_block_cb_remove(block_cb, f);
1935+
flow_indr_block_cb_remove(block_cb, f);
19341936
list_del(&block_cb->driver_list);
19351937
break;
19361938
default:
@@ -1945,14 +1947,17 @@ static bool bnxt_is_netdev_indr_offload(struct net_device *netdev)
19451947
}
19461948

19471949
static int bnxt_tc_setup_indr_cb(struct net_device *netdev, void *cb_priv,
1948-
enum tc_setup_type type, void *type_data)
1950+
enum tc_setup_type type, void *type_data,
1951+
void *data,
1952+
void (*cleanup)(struct flow_block_cb *block_cb))
19491953
{
19501954
if (!bnxt_is_netdev_indr_offload(netdev))
19511955
return -EOPNOTSUPP;
19521956

19531957
switch (type) {
19541958
case TC_SETUP_BLOCK:
1955-
return bnxt_tc_setup_indr_block(netdev, cb_priv, type_data);
1959+
return bnxt_tc_setup_indr_block(netdev, cb_priv, type_data, data,
1960+
cleanup);
19561961
default:
19571962
break;
19581963
}
@@ -2074,7 +2079,7 @@ void bnxt_shutdown_tc(struct bnxt *bp)
20742079
return;
20752080

20762081
flow_indr_dev_unregister(bnxt_tc_setup_indr_cb, bp,
2077-
bnxt_tc_setup_indr_block_cb);
2082+
bnxt_tc_setup_indr_rel);
20782083
rhashtable_destroy(&tc_info->flow_table);
20792084
rhashtable_destroy(&tc_info->l2_table);
20802085
rhashtable_destroy(&tc_info->decap_l2_table);

drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,9 @@ static int
407407
mlx5e_rep_indr_setup_block(struct net_device *netdev,
408408
struct mlx5e_rep_priv *rpriv,
409409
struct flow_block_offload *f,
410-
flow_setup_cb_t *setup_cb)
410+
flow_setup_cb_t *setup_cb,
411+
void *data,
412+
void (*cleanup)(struct flow_block_cb *block_cb))
411413
{
412414
struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
413415
struct mlx5e_rep_indr_block_priv *indr_priv;
@@ -438,8 +440,10 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev,
438440
list_add(&indr_priv->list,
439441
&rpriv->uplink_priv.tc_indr_block_priv_list);
440442

441-
block_cb = flow_block_cb_alloc(setup_cb, indr_priv, indr_priv,
442-
mlx5e_rep_indr_block_unbind);
443+
block_cb = flow_indr_block_cb_alloc(setup_cb, indr_priv, indr_priv,
444+
mlx5e_rep_indr_block_unbind,
445+
f, netdev, data, rpriv,
446+
cleanup);
443447
if (IS_ERR(block_cb)) {
444448
list_del(&indr_priv->list);
445449
kfree(indr_priv);
@@ -458,7 +462,7 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev,
458462
if (!block_cb)
459463
return -ENOENT;
460464

461-
flow_block_cb_remove(block_cb, f);
465+
flow_indr_block_cb_remove(block_cb, f);
462466
list_del(&block_cb->driver_list);
463467
return 0;
464468
default:
@@ -469,15 +473,19 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev,
469473

470474
static
471475
int mlx5e_rep_indr_setup_cb(struct net_device *netdev, void *cb_priv,
472-
enum tc_setup_type type, void *type_data)
476+
enum tc_setup_type type, void *type_data,
477+
void *data,
478+
void (*cleanup)(struct flow_block_cb *block_cb))
473479
{
474480
switch (type) {
475481
case TC_SETUP_BLOCK:
476482
return mlx5e_rep_indr_setup_block(netdev, cb_priv, type_data,
477-
mlx5e_rep_indr_setup_tc_cb);
483+
mlx5e_rep_indr_setup_tc_cb,
484+
data, cleanup);
478485
case TC_SETUP_FT:
479486
return mlx5e_rep_indr_setup_block(netdev, cb_priv, type_data,
480-
mlx5e_rep_indr_setup_ft_cb);
487+
mlx5e_rep_indr_setup_ft_cb,
488+
data, cleanup);
481489
default:
482490
return -EOPNOTSUPP;
483491
}
@@ -496,7 +504,7 @@ int mlx5e_rep_tc_netdevice_event_register(struct mlx5e_rep_priv *rpriv)
496504
void mlx5e_rep_tc_netdevice_event_unregister(struct mlx5e_rep_priv *rpriv)
497505
{
498506
flow_indr_dev_unregister(mlx5e_rep_indr_setup_cb, rpriv,
499-
mlx5e_rep_indr_setup_tc_cb);
507+
mlx5e_rep_indr_block_unbind);
500508
}
501509

502510
#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)

drivers/net/ethernet/netronome/nfp/flower/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ static void nfp_flower_clean(struct nfp_app *app)
861861
flush_work(&app_priv->cmsg_work);
862862

863863
flow_indr_dev_unregister(nfp_flower_indr_setup_tc_cb, app,
864-
nfp_flower_setup_indr_block_cb);
864+
nfp_flower_setup_indr_tc_release);
865865

866866
if (app_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM)
867867
nfp_flower_qos_cleanup(app);

drivers/net/ethernet/netronome/nfp/flower/main.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,10 @@ int nfp_flower_setup_qos_offload(struct nfp_app *app, struct net_device *netdev,
459459
struct tc_cls_matchall_offload *flow);
460460
void nfp_flower_stats_rlim_reply(struct nfp_app *app, struct sk_buff *skb);
461461
int nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,
462-
enum tc_setup_type type, void *type_data);
463-
int nfp_flower_setup_indr_block_cb(enum tc_setup_type type, void *type_data,
464-
void *cb_priv);
462+
enum tc_setup_type type, void *type_data,
463+
void *data,
464+
void (*cleanup)(struct flow_block_cb *block_cb));
465+
void nfp_flower_setup_indr_tc_release(void *cb_priv);
465466

466467
void
467468
__nfp_flower_non_repr_priv_get(struct nfp_flower_non_repr_priv *non_repr_priv);

drivers/net/ethernet/netronome/nfp/flower/offload.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,8 +1619,8 @@ nfp_flower_indr_block_cb_priv_lookup(struct nfp_app *app,
16191619
return NULL;
16201620
}
16211621

1622-
int nfp_flower_setup_indr_block_cb(enum tc_setup_type type,
1623-
void *type_data, void *cb_priv)
1622+
static int nfp_flower_setup_indr_block_cb(enum tc_setup_type type,
1623+
void *type_data, void *cb_priv)
16241624
{
16251625
struct nfp_flower_indr_block_cb_priv *priv = cb_priv;
16261626
struct flow_cls_offload *flower = type_data;
@@ -1637,7 +1637,7 @@ int nfp_flower_setup_indr_block_cb(enum tc_setup_type type,
16371637
}
16381638
}
16391639

1640-
static void nfp_flower_setup_indr_tc_release(void *cb_priv)
1640+
void nfp_flower_setup_indr_tc_release(void *cb_priv)
16411641
{
16421642
struct nfp_flower_indr_block_cb_priv *priv = cb_priv;
16431643

@@ -1647,7 +1647,8 @@ static void nfp_flower_setup_indr_tc_release(void *cb_priv)
16471647

16481648
static int
16491649
nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
1650-
struct flow_block_offload *f)
1650+
struct flow_block_offload *f, void *data,
1651+
void (*cleanup)(struct flow_block_cb *block_cb))
16511652
{
16521653
struct nfp_flower_indr_block_cb_priv *cb_priv;
16531654
struct nfp_flower_priv *priv = app->priv;
@@ -1676,9 +1677,10 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
16761677
cb_priv->app = app;
16771678
list_add(&cb_priv->list, &priv->indr_block_cb_priv);
16781679

1679-
block_cb = flow_block_cb_alloc(nfp_flower_setup_indr_block_cb,
1680-
cb_priv, cb_priv,
1681-
nfp_flower_setup_indr_tc_release);
1680+
block_cb = flow_indr_block_cb_alloc(nfp_flower_setup_indr_block_cb,
1681+
cb_priv, cb_priv,
1682+
nfp_flower_setup_indr_tc_release,
1683+
f, netdev, data, app, cleanup);
16821684
if (IS_ERR(block_cb)) {
16831685
list_del(&cb_priv->list);
16841686
kfree(cb_priv);
@@ -1699,7 +1701,7 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
16991701
if (!block_cb)
17001702
return -ENOENT;
17011703

1702-
flow_block_cb_remove(block_cb, f);
1704+
flow_indr_block_cb_remove(block_cb, f);
17031705
list_del(&block_cb->driver_list);
17041706
return 0;
17051707
default:
@@ -1710,15 +1712,17 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
17101712

17111713
int
17121714
nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,
1713-
enum tc_setup_type type, void *type_data)
1715+
enum tc_setup_type type, void *type_data,
1716+
void *data,
1717+
void (*cleanup)(struct flow_block_cb *block_cb))
17141718
{
17151719
if (!nfp_fl_is_netdev_to_offload(netdev))
17161720
return -EOPNOTSUPP;
17171721

17181722
switch (type) {
17191723
case TC_SETUP_BLOCK:
17201724
return nfp_flower_setup_indr_tc_block(netdev, cb_priv,
1721-
type_data);
1725+
type_data, data, cleanup);
17221726
default:
17231727
return -EOPNOTSUPP;
17241728
}

include/net/flow_offload.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ struct flow_block_indr {
450450
struct net_device *dev;
451451
enum flow_block_binder_type binder_type;
452452
void *data;
453+
void *cb_priv;
453454
void (*cleanup)(struct flow_block_cb *block_cb);
454455
};
455456

@@ -467,6 +468,13 @@ struct flow_block_cb {
467468
struct flow_block_cb *flow_block_cb_alloc(flow_setup_cb_t *cb,
468469
void *cb_ident, void *cb_priv,
469470
void (*release)(void *cb_priv));
471+
struct flow_block_cb *flow_indr_block_cb_alloc(flow_setup_cb_t *cb,
472+
void *cb_ident, void *cb_priv,
473+
void (*release)(void *cb_priv),
474+
struct flow_block_offload *bo,
475+
struct net_device *dev, void *data,
476+
void *indr_cb_priv,
477+
void (*cleanup)(struct flow_block_cb *block_cb));
470478
void flow_block_cb_free(struct flow_block_cb *block_cb);
471479

472480
struct flow_block_cb *flow_block_cb_lookup(struct flow_block *block,
@@ -488,6 +496,13 @@ static inline void flow_block_cb_remove(struct flow_block_cb *block_cb,
488496
list_move(&block_cb->list, &offload->cb_list);
489497
}
490498

499+
static inline void flow_indr_block_cb_remove(struct flow_block_cb *block_cb,
500+
struct flow_block_offload *offload)
501+
{
502+
list_del(&block_cb->indr.list);
503+
list_move(&block_cb->list, &offload->cb_list);
504+
}
505+
491506
bool flow_block_cb_is_busy(flow_setup_cb_t *cb, void *cb_ident,
492507
struct list_head *driver_block_list);
493508

@@ -532,11 +547,13 @@ static inline void flow_block_init(struct flow_block *flow_block)
532547
}
533548

534549
typedef int flow_indr_block_bind_cb_t(struct net_device *dev, void *cb_priv,
535-
enum tc_setup_type type, void *type_data);
550+
enum tc_setup_type type, void *type_data,
551+
void *data,
552+
void (*cleanup)(struct flow_block_cb *block_cb));
536553

537554
int flow_indr_dev_register(flow_indr_block_bind_cb_t *cb, void *cb_priv);
538555
void flow_indr_dev_unregister(flow_indr_block_bind_cb_t *cb, void *cb_priv,
539-
flow_setup_cb_t *setup_cb);
556+
void (*release)(void *cb_priv));
540557
int flow_indr_dev_setup_offload(struct net_device *dev,
541558
enum tc_setup_type type, void *data,
542559
struct flow_block_offload *bo,

net/core/flow_offload.c

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -372,14 +372,15 @@ int flow_indr_dev_register(flow_indr_block_bind_cb_t *cb, void *cb_priv)
372372
}
373373
EXPORT_SYMBOL(flow_indr_dev_register);
374374

375-
static void __flow_block_indr_cleanup(flow_setup_cb_t *setup_cb, void *cb_priv,
375+
static void __flow_block_indr_cleanup(void (*release)(void *cb_priv),
376+
void *cb_priv,
376377
struct list_head *cleanup_list)
377378
{
378379
struct flow_block_cb *this, *next;
379380

380381
list_for_each_entry_safe(this, next, &flow_block_indr_list, indr.list) {
381-
if (this->cb == setup_cb &&
382-
this->cb_priv == cb_priv) {
382+
if (this->release == release &&
383+
this->indr.cb_priv == cb_priv) {
383384
list_move(&this->indr.list, cleanup_list);
384385
return;
385386
}
@@ -397,7 +398,7 @@ static void flow_block_indr_notify(struct list_head *cleanup_list)
397398
}
398399

399400
void flow_indr_dev_unregister(flow_indr_block_bind_cb_t *cb, void *cb_priv,
400-
flow_setup_cb_t *setup_cb)
401+
void (*release)(void *cb_priv))
401402
{
402403
struct flow_indr_dev *this, *next, *indr_dev = NULL;
403404
LIST_HEAD(cleanup_list);
@@ -418,7 +419,7 @@ void flow_indr_dev_unregister(flow_indr_block_bind_cb_t *cb, void *cb_priv,
418419
return;
419420
}
420421

421-
__flow_block_indr_cleanup(setup_cb, cb_priv, &cleanup_list);
422+
__flow_block_indr_cleanup(release, cb_priv, &cleanup_list);
422423
mutex_unlock(&flow_indr_block_lock);
423424

424425
flow_block_indr_notify(&cleanup_list);
@@ -429,32 +430,37 @@ EXPORT_SYMBOL(flow_indr_dev_unregister);
429430
static void flow_block_indr_init(struct flow_block_cb *flow_block,
430431
struct flow_block_offload *bo,
431432
struct net_device *dev, void *data,
433+
void *cb_priv,
432434
void (*cleanup)(struct flow_block_cb *block_cb))
433435
{
434436
flow_block->indr.binder_type = bo->binder_type;
435437
flow_block->indr.data = data;
438+
flow_block->indr.cb_priv = cb_priv;
436439
flow_block->indr.dev = dev;
437440
flow_block->indr.cleanup = cleanup;
438441
}
439442

440-
static void __flow_block_indr_binding(struct flow_block_offload *bo,
441-
struct net_device *dev, void *data,
442-
void (*cleanup)(struct flow_block_cb *block_cb))
443+
struct flow_block_cb *flow_indr_block_cb_alloc(flow_setup_cb_t *cb,
444+
void *cb_ident, void *cb_priv,
445+
void (*release)(void *cb_priv),
446+
struct flow_block_offload *bo,
447+
struct net_device *dev, void *data,
448+
void *indr_cb_priv,
449+
void (*cleanup)(struct flow_block_cb *block_cb))
443450
{
444451
struct flow_block_cb *block_cb;
445452

446-
list_for_each_entry(block_cb, &bo->cb_list, list) {
447-
switch (bo->command) {
448-
case FLOW_BLOCK_BIND:
449-
flow_block_indr_init(block_cb, bo, dev, data, cleanup);
450-
list_add(&block_cb->indr.list, &flow_block_indr_list);
451-
break;
452-
case FLOW_BLOCK_UNBIND:
453-
list_del(&block_cb->indr.list);
454-
break;
455-
}
456-
}
453+
block_cb = flow_block_cb_alloc(cb, cb_ident, cb_priv, release);
454+
if (IS_ERR(block_cb))
455+
goto out;
456+
457+
flow_block_indr_init(block_cb, bo, dev, data, indr_cb_priv, cleanup);
458+
list_add(&block_cb->indr.list, &flow_block_indr_list);
459+
460+
out:
461+
return block_cb;
457462
}
463+
EXPORT_SYMBOL(flow_indr_block_cb_alloc);
458464

459465
int flow_indr_dev_setup_offload(struct net_device *dev,
460466
enum tc_setup_type type, void *data,
@@ -465,9 +471,8 @@ int flow_indr_dev_setup_offload(struct net_device *dev,
465471

466472
mutex_lock(&flow_indr_block_lock);
467473
list_for_each_entry(this, &flow_block_indr_dev_list, list)
468-
this->cb(dev, this->cb_priv, type, bo);
474+
this->cb(dev, this->cb_priv, type, bo, data, cleanup);
469475

470-
__flow_block_indr_binding(bo, dev, data, cleanup);
471476
mutex_unlock(&flow_indr_block_lock);
472477

473478
return list_empty(&bo->cb_list) ? -EOPNOTSUPP : 0;

net/netfilter/nf_flow_table_offload.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,7 @@ static void nf_flow_table_indr_cleanup(struct flow_block_cb *block_cb)
950950
nf_flow_table_gc_cleanup(flowtable, dev);
951951
down_write(&flowtable->flow_block_lock);
952952
list_del(&block_cb->list);
953+
list_del(&block_cb->driver_list);
953954
flow_block_cb_free(block_cb);
954955
up_write(&flowtable->flow_block_lock);
955956
}

net/netfilter/nf_tables_offload.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ static void nft_indr_block_cleanup(struct flow_block_cb *block_cb)
296296
nft_flow_block_offload_init(&bo, dev_net(dev), FLOW_BLOCK_UNBIND,
297297
basechain, &extack);
298298
mutex_lock(&net->nft.commit_mutex);
299+
list_del(&block_cb->driver_list);
299300
list_move(&block_cb->list, &bo.cb_list);
300301
nft_flow_offload_unbind(&bo, basechain);
301302
mutex_unlock(&net->nft.commit_mutex);

0 commit comments

Comments
 (0)