Commit 95dcd892 authored by David S. Miller's avatar David S. Miller
Browse files

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 1fac52da ("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: default avatarSimon Horman <simon.horman@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 56c09de3 3c005110
Loading
Loading
Loading
Loading
+13 −8
Original line number Diff line number Diff line
@@ -1889,7 +1889,8 @@ static void bnxt_tc_setup_indr_rel(void *cb_priv)
}

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

		block_cb = flow_block_cb_alloc(bnxt_tc_setup_indr_block_cb,
		block_cb = flow_indr_block_cb_alloc(bnxt_tc_setup_indr_block_cb,
						    cb_priv, cb_priv,
					       bnxt_tc_setup_indr_rel);
						    bnxt_tc_setup_indr_rel, f,
						    netdev, data, bp, cleanup);
		if (IS_ERR(block_cb)) {
			list_del(&cb_priv->list);
			kfree(cb_priv);
@@ -1930,7 +1932,7 @@ static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp,
		if (!block_cb)
			return -ENOENT;

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

static int bnxt_tc_setup_indr_cb(struct net_device *netdev, void *cb_priv,
				 enum tc_setup_type type, void *type_data)
				 enum tc_setup_type type, void *type_data,
				 void *data,
				 void (*cleanup)(struct flow_block_cb *block_cb))
{
	if (!bnxt_is_netdev_indr_offload(netdev))
		return -EOPNOTSUPP;

	switch (type) {
	case TC_SETUP_BLOCK:
		return bnxt_tc_setup_indr_block(netdev, cb_priv, type_data);
		return bnxt_tc_setup_indr_block(netdev, cb_priv, type_data, data,
						cleanup);
	default:
		break;
	}
@@ -2074,7 +2079,7 @@ void bnxt_shutdown_tc(struct bnxt *bp)
		return;

	flow_indr_dev_unregister(bnxt_tc_setup_indr_cb, bp,
				 bnxt_tc_setup_indr_block_cb);
				 bnxt_tc_setup_indr_rel);
	rhashtable_destroy(&tc_info->flow_table);
	rhashtable_destroy(&tc_info->l2_table);
	rhashtable_destroy(&tc_info->decap_l2_table);
+16 −8
Original line number Diff line number Diff line
@@ -407,7 +407,9 @@ static int
mlx5e_rep_indr_setup_block(struct net_device *netdev,
			   struct mlx5e_rep_priv *rpriv,
			   struct flow_block_offload *f,
			   flow_setup_cb_t *setup_cb)
			   flow_setup_cb_t *setup_cb,
			   void *data,
			   void (*cleanup)(struct flow_block_cb *block_cb))
{
	struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
	struct mlx5e_rep_indr_block_priv *indr_priv;
@@ -438,8 +440,10 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev,
		list_add(&indr_priv->list,
			 &rpriv->uplink_priv.tc_indr_block_priv_list);

		block_cb = flow_block_cb_alloc(setup_cb, indr_priv, indr_priv,
					       mlx5e_rep_indr_block_unbind);
		block_cb = flow_indr_block_cb_alloc(setup_cb, indr_priv, indr_priv,
						    mlx5e_rep_indr_block_unbind,
						    f, netdev, data, rpriv,
						    cleanup);
		if (IS_ERR(block_cb)) {
			list_del(&indr_priv->list);
			kfree(indr_priv);
@@ -458,7 +462,7 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev,
		if (!block_cb)
			return -ENOENT;

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

static
int mlx5e_rep_indr_setup_cb(struct net_device *netdev, void *cb_priv,
			    enum tc_setup_type type, void *type_data)
			    enum tc_setup_type type, void *type_data,
			    void *data,
			    void (*cleanup)(struct flow_block_cb *block_cb))
{
	switch (type) {
	case TC_SETUP_BLOCK:
		return mlx5e_rep_indr_setup_block(netdev, cb_priv, type_data,
						  mlx5e_rep_indr_setup_tc_cb);
						  mlx5e_rep_indr_setup_tc_cb,
						  data, cleanup);
	case TC_SETUP_FT:
		return mlx5e_rep_indr_setup_block(netdev, cb_priv, type_data,
						  mlx5e_rep_indr_setup_ft_cb);
						  mlx5e_rep_indr_setup_ft_cb,
						  data, cleanup);
	default:
		return -EOPNOTSUPP;
	}
@@ -496,7 +504,7 @@ int mlx5e_rep_tc_netdevice_event_register(struct mlx5e_rep_priv *rpriv)
void mlx5e_rep_tc_netdevice_event_unregister(struct mlx5e_rep_priv *rpriv)
{
	flow_indr_dev_unregister(mlx5e_rep_indr_setup_cb, rpriv,
				 mlx5e_rep_indr_setup_tc_cb);
				 mlx5e_rep_indr_block_unbind);
}

#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
+1 −1
Original line number Diff line number Diff line
@@ -861,7 +861,7 @@ static void nfp_flower_clean(struct nfp_app *app)
	flush_work(&app_priv->cmsg_work);

	flow_indr_dev_unregister(nfp_flower_indr_setup_tc_cb, app,
				 nfp_flower_setup_indr_block_cb);
				 nfp_flower_setup_indr_tc_release);

	if (app_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM)
		nfp_flower_qos_cleanup(app);
+4 −3
Original line number Diff line number Diff line
@@ -459,9 +459,10 @@ int nfp_flower_setup_qos_offload(struct nfp_app *app, struct net_device *netdev,
				 struct tc_cls_matchall_offload *flow);
void nfp_flower_stats_rlim_reply(struct nfp_app *app, struct sk_buff *skb);
int nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,
				enum tc_setup_type type, void *type_data);
int nfp_flower_setup_indr_block_cb(enum tc_setup_type type, void *type_data,
				   void *cb_priv);
				enum tc_setup_type type, void *type_data,
				void *data,
				void (*cleanup)(struct flow_block_cb *block_cb));
void nfp_flower_setup_indr_tc_release(void *cb_priv);

void
__nfp_flower_non_repr_priv_get(struct nfp_flower_non_repr_priv *non_repr_priv);
+14 −10
Original line number Diff line number Diff line
@@ -1619,7 +1619,7 @@ nfp_flower_indr_block_cb_priv_lookup(struct nfp_app *app,
	return NULL;
}

int nfp_flower_setup_indr_block_cb(enum tc_setup_type type,
static int nfp_flower_setup_indr_block_cb(enum tc_setup_type type,
					  void *type_data, void *cb_priv)
{
	struct nfp_flower_indr_block_cb_priv *priv = cb_priv;
@@ -1637,7 +1637,7 @@ int nfp_flower_setup_indr_block_cb(enum tc_setup_type type,
	}
}

static void nfp_flower_setup_indr_tc_release(void *cb_priv)
void nfp_flower_setup_indr_tc_release(void *cb_priv)
{
	struct nfp_flower_indr_block_cb_priv *priv = cb_priv;

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

static int
nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
			       struct flow_block_offload *f)
			       struct flow_block_offload *f, void *data,
			       void (*cleanup)(struct flow_block_cb *block_cb))
{
	struct nfp_flower_indr_block_cb_priv *cb_priv;
	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,
		cb_priv->app = app;
		list_add(&cb_priv->list, &priv->indr_block_cb_priv);

		block_cb = flow_block_cb_alloc(nfp_flower_setup_indr_block_cb,
		block_cb = flow_indr_block_cb_alloc(nfp_flower_setup_indr_block_cb,
						    cb_priv, cb_priv,
					       nfp_flower_setup_indr_tc_release);
						    nfp_flower_setup_indr_tc_release,
						    f, netdev, data, app, cleanup);
		if (IS_ERR(block_cb)) {
			list_del(&cb_priv->list);
			kfree(cb_priv);
@@ -1699,7 +1701,7 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
		if (!block_cb)
			return -ENOENT;

		flow_block_cb_remove(block_cb, f);
		flow_indr_block_cb_remove(block_cb, f);
		list_del(&block_cb->driver_list);
		return 0;
	default:
@@ -1710,7 +1712,9 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,

int
nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,
			    enum tc_setup_type type, void *type_data)
			    enum tc_setup_type type, void *type_data,
			    void *data,
			    void (*cleanup)(struct flow_block_cb *block_cb))
{
	if (!nfp_fl_is_netdev_to_offload(netdev))
		return -EOPNOTSUPP;
@@ -1718,7 +1722,7 @@ nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,
	switch (type) {
	case TC_SETUP_BLOCK:
		return nfp_flower_setup_indr_tc_block(netdev, cb_priv,
						      type_data);
						      type_data, data, cleanup);
	default:
		return -EOPNOTSUPP;
	}
Loading