Skip to content
/ linux Public
forked from torvalds/linux

Commit

Permalink
drivers: net: use flow block API
Browse files Browse the repository at this point in the history
This patch updates flow_block_cb_setup_simple() to use the flow block API.
Several drivers are also adjusted to use it.

This patch introduces the per-driver list of flow blocks to account for
blocks that are already in use.

Remove tc_block_offload alias.

Signed-off-by: Pablo Neira Ayuso <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
ummakynes authored and davem330 committed Jul 9, 2019
1 parent 59094b1 commit 955bcb6
Show file tree
Hide file tree
Showing 25 changed files with 286 additions and 130 deletions.
5 changes: 4 additions & 1 deletion drivers/net/ethernet/broadcom/bnxt/bnxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -9907,14 +9907,17 @@ static int bnxt_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
}
}

static LIST_HEAD(bnxt_block_cb_list);

static int bnxt_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
struct bnxt *bp = netdev_priv(dev);

switch (type) {
case TC_SETUP_BLOCK:
return flow_block_cb_setup_simple(type_data, NULL,
return flow_block_cb_setup_simple(type_data,
&bnxt_block_cb_list,
bnxt_setup_tc_block_cb,
bp, bp, true);
case TC_SETUP_QDISC_MQPRIO: {
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,17 @@ static int bnxt_vf_rep_setup_tc_block_cb(enum tc_setup_type type,
}
}

static LIST_HEAD(bnxt_vf_block_cb_list);

static int bnxt_vf_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
struct bnxt_vf_rep *vf_rep = netdev_priv(dev);

switch (type) {
case TC_SETUP_BLOCK:
return flow_block_cb_setup_simple(type_data, NULL,
return flow_block_cb_setup_simple(type_data,
&bnxt_vf_block_cb_list,
bnxt_vf_rep_setup_tc_block_cb,
vf_rep, vf_rep, true);
default:
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3190,14 +3190,17 @@ static int cxgb_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
}
}

static LIST_HEAD(cxgb_block_cb_list);

static int cxgb_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
struct port_info *pi = netdev2pinfo(dev);

switch (type) {
case TC_SETUP_BLOCK:
return flow_block_cb_setup_simple(type_data, NULL,
return flow_block_cb_setup_simple(type_data,
&cxgb_block_cb_list,
cxgb_setup_tc_block_cb,
pi, dev, true);
default:
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/intel/i40e/i40e_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8177,6 +8177,8 @@ static int i40e_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
}
}

static LIST_HEAD(i40e_block_cb_list);

static int __i40e_setup_tc(struct net_device *netdev, enum tc_setup_type type,
void *type_data)
{
Expand All @@ -8186,7 +8188,8 @@ static int __i40e_setup_tc(struct net_device *netdev, enum tc_setup_type type,
case TC_SETUP_QDISC_MQPRIO:
return i40e_setup_tc(netdev, type_data);
case TC_SETUP_BLOCK:
return flow_block_cb_setup_simple(type_data, NULL,
return flow_block_cb_setup_simple(type_data,
&i40e_block_cb_list,
i40e_setup_tc_block_cb,
np, np, true);
default:
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/intel/iavf/iavf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3113,6 +3113,8 @@ static int iavf_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
}
}

static LIST_HEAD(iavf_block_cb_list);

/**
* iavf_setup_tc - configure multiple traffic classes
* @netdev: network interface device structure
Expand All @@ -3133,7 +3135,8 @@ static int iavf_setup_tc(struct net_device *netdev, enum tc_setup_type type,
case TC_SETUP_QDISC_MQPRIO:
return __iavf_setup_tc(netdev, type_data);
case TC_SETUP_BLOCK:
return flow_block_cb_setup_simple(type_data, NULL,
return flow_block_cb_setup_simple(type_data,
&iavf_block_cb_list,
iavf_setup_tc_block_cb,
adapter, adapter, true);
default:
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/intel/igb/igb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2806,6 +2806,8 @@ static int igb_offload_txtime(struct igb_adapter *adapter,
return 0;
}

static LIST_HEAD(igb_block_cb_list);

static int igb_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
Expand All @@ -2815,7 +2817,8 @@ static int igb_setup_tc(struct net_device *dev, enum tc_setup_type type,
case TC_SETUP_QDISC_CBS:
return igb_offload_cbs(adapter, type_data);
case TC_SETUP_BLOCK:
return flow_block_cb_setup_simple(type_data, NULL,
return flow_block_cb_setup_simple(type_data,
&igb_block_cb_list,
igb_setup_tc_block_cb,
adapter, adapter, true);

Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9614,14 +9614,17 @@ static int ixgbe_setup_tc_mqprio(struct net_device *dev,
return ixgbe_setup_tc(dev, mqprio->num_tc);
}

static LIST_HEAD(ixgbe_block_cb_list);

static int __ixgbe_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
struct ixgbe_adapter *adapter = netdev_priv(dev);

switch (type) {
case TC_SETUP_BLOCK:
return flow_block_cb_setup_simple(type_data, NULL,
return flow_block_cb_setup_simple(type_data,
&ixgbe_block_cb_list,
ixgbe_setup_tc_block_cb,
adapter, adapter, true);
case TC_SETUP_QDISC_MQPRIO:
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3459,6 +3459,8 @@ static int mlx5e_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
}
#endif

static LIST_HEAD(mlx5e_block_cb_list);

static int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
Expand All @@ -3467,7 +3469,8 @@ static int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type,
switch (type) {
#ifdef CONFIG_MLX5_ESWITCH
case TC_SETUP_BLOCK:
return flow_block_cb_setup_simple(type_data, NULL,
return flow_block_cb_setup_simple(type_data,
&mlx5e_block_cb_list,
mlx5e_setup_tc_block_cb,
priv, priv, true);
#endif
Expand Down
42 changes: 30 additions & 12 deletions drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,17 +693,29 @@ static int mlx5e_rep_indr_setup_block_cb(enum tc_setup_type type,
}
}

static void mlx5e_rep_indr_tc_block_unbind(void *cb_priv)
{
struct mlx5e_rep_indr_block_priv *indr_priv = cb_priv;

list_del(&indr_priv->list);
kfree(indr_priv);
}

static LIST_HEAD(mlx5e_block_cb_list);

static int
mlx5e_rep_indr_setup_tc_block(struct net_device *netdev,
struct mlx5e_rep_priv *rpriv,
struct tc_block_offload *f)
struct flow_block_offload *f)
{
struct mlx5e_rep_indr_block_priv *indr_priv;
int err = 0;
struct flow_block_cb *block_cb;

if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
return -EOPNOTSUPP;

f->driver_block_list = &mlx5e_block_cb_list;

switch (f->command) {
case FLOW_BLOCK_BIND:
indr_priv = mlx5e_rep_indr_block_priv_lookup(rpriv, netdev);
Expand All @@ -719,26 +731,32 @@ mlx5e_rep_indr_setup_tc_block(struct net_device *netdev,
list_add(&indr_priv->list,
&rpriv->uplink_priv.tc_indr_block_priv_list);

err = tcf_block_cb_register(f->block,
mlx5e_rep_indr_setup_block_cb,
indr_priv, indr_priv, f->extack);
if (err) {
block_cb = flow_block_cb_alloc(f->net,
mlx5e_rep_indr_setup_block_cb,
indr_priv, indr_priv,
mlx5e_rep_indr_tc_block_unbind);
if (IS_ERR(block_cb)) {
list_del(&indr_priv->list);
kfree(indr_priv);
return PTR_ERR(block_cb);
}
flow_block_cb_add(block_cb, f);
list_add_tail(&block_cb->driver_list, &mlx5e_block_cb_list);

return err;
return 0;
case FLOW_BLOCK_UNBIND:
indr_priv = mlx5e_rep_indr_block_priv_lookup(rpriv, netdev);
if (!indr_priv)
return -ENOENT;

tcf_block_cb_unregister(f->block,
mlx5e_rep_indr_setup_block_cb,
indr_priv);
list_del(&indr_priv->list);
kfree(indr_priv);
block_cb = flow_block_cb_lookup(f,
mlx5e_rep_indr_setup_block_cb,
indr_priv);
if (!block_cb)
return -ENOENT;

flow_block_cb_remove(block_cb, f);
list_del(&block_cb->driver_list);
return 0;
default:
return -EOPNOTSUPP;
Expand Down
92 changes: 58 additions & 34 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -1585,33 +1585,45 @@ static int mlxsw_sp_setup_tc_block_cb_flower(enum tc_setup_type type,
}
}

static void mlxsw_sp_tc_block_flower_release(void *cb_priv)
{
struct mlxsw_sp_acl_block *acl_block = cb_priv;

mlxsw_sp_acl_block_destroy(acl_block);
}

static LIST_HEAD(mlxsw_sp_block_cb_list);

static int
mlxsw_sp_setup_tc_block_flower_bind(struct mlxsw_sp_port *mlxsw_sp_port,
struct tcf_block *block, bool ingress,
struct netlink_ext_ack *extack)
struct flow_block_offload *f, bool ingress)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
struct mlxsw_sp_acl_block *acl_block;
struct tcf_block_cb *block_cb;
struct flow_block_cb *block_cb;
bool register_block = false;
int err;

block_cb = tcf_block_cb_lookup(block, mlxsw_sp_setup_tc_block_cb_flower,
mlxsw_sp);
block_cb = flow_block_cb_lookup(f, mlxsw_sp_setup_tc_block_cb_flower,
mlxsw_sp);
if (!block_cb) {
acl_block = mlxsw_sp_acl_block_create(mlxsw_sp, block->net);
acl_block = mlxsw_sp_acl_block_create(mlxsw_sp, f->net);
if (!acl_block)
return -ENOMEM;
block_cb = __tcf_block_cb_register(block,
mlxsw_sp_setup_tc_block_cb_flower,
mlxsw_sp, acl_block, extack);
block_cb = flow_block_cb_alloc(f->net,
mlxsw_sp_setup_tc_block_cb_flower,
mlxsw_sp, acl_block,
mlxsw_sp_tc_block_flower_release);
if (IS_ERR(block_cb)) {
mlxsw_sp_acl_block_destroy(acl_block);
err = PTR_ERR(block_cb);
goto err_cb_register;
}
register_block = true;
} else {
acl_block = tcf_block_cb_priv(block_cb);
acl_block = flow_block_cb_priv(block_cb);
}
tcf_block_cb_incref(block_cb);
flow_block_cb_incref(block_cb);
err = mlxsw_sp_acl_block_bind(mlxsw_sp, acl_block,
mlxsw_sp_port, ingress);
if (err)
Expand All @@ -1622,28 +1634,31 @@ mlxsw_sp_setup_tc_block_flower_bind(struct mlxsw_sp_port *mlxsw_sp_port,
else
mlxsw_sp_port->eg_acl_block = acl_block;

if (register_block) {
flow_block_cb_add(block_cb, f);
list_add_tail(&block_cb->driver_list, &mlxsw_sp_block_cb_list);
}

return 0;

err_block_bind:
if (!tcf_block_cb_decref(block_cb)) {
__tcf_block_cb_unregister(block, block_cb);
if (!flow_block_cb_decref(block_cb))
flow_block_cb_free(block_cb);
err_cb_register:
mlxsw_sp_acl_block_destroy(acl_block);
}
return err;
}

static void
mlxsw_sp_setup_tc_block_flower_unbind(struct mlxsw_sp_port *mlxsw_sp_port,
struct tcf_block *block, bool ingress)
struct flow_block_offload *f, bool ingress)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
struct mlxsw_sp_acl_block *acl_block;
struct tcf_block_cb *block_cb;
struct flow_block_cb *block_cb;
int err;

block_cb = tcf_block_cb_lookup(block, mlxsw_sp_setup_tc_block_cb_flower,
mlxsw_sp);
block_cb = flow_block_cb_lookup(f, mlxsw_sp_setup_tc_block_cb_flower,
mlxsw_sp);
if (!block_cb)
return;

Expand All @@ -1652,18 +1667,19 @@ mlxsw_sp_setup_tc_block_flower_unbind(struct mlxsw_sp_port *mlxsw_sp_port,
else
mlxsw_sp_port->eg_acl_block = NULL;

acl_block = tcf_block_cb_priv(block_cb);
acl_block = flow_block_cb_priv(block_cb);
err = mlxsw_sp_acl_block_unbind(mlxsw_sp, acl_block,
mlxsw_sp_port, ingress);
if (!err && !tcf_block_cb_decref(block_cb)) {
__tcf_block_cb_unregister(block, block_cb);
mlxsw_sp_acl_block_destroy(acl_block);
if (!err && !flow_block_cb_decref(block_cb)) {
flow_block_cb_remove(block_cb, f);
list_del(&block_cb->driver_list);
}
}

static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port,
struct tc_block_offload *f)
struct flow_block_offload *f)
{
struct flow_block_cb *block_cb;
tc_setup_cb_t *cb;
bool ingress;
int err;
Expand All @@ -1678,24 +1694,32 @@ static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port,
return -EOPNOTSUPP;
}

f->driver_block_list = &mlxsw_sp_block_cb_list;

switch (f->command) {
case FLOW_BLOCK_BIND:
err = tcf_block_cb_register(f->block, cb, mlxsw_sp_port,
mlxsw_sp_port, f->extack);
if (err)
return err;
err = mlxsw_sp_setup_tc_block_flower_bind(mlxsw_sp_port,
f->block, ingress,
f->extack);
block_cb = flow_block_cb_alloc(f->net, cb, mlxsw_sp_port,
mlxsw_sp_port, NULL);
if (IS_ERR(block_cb))
return PTR_ERR(block_cb);
err = mlxsw_sp_setup_tc_block_flower_bind(mlxsw_sp_port, f,
ingress);
if (err) {
tcf_block_cb_unregister(f->block, cb, mlxsw_sp_port);
flow_block_cb_free(block_cb);
return err;
}
flow_block_cb_add(block_cb, f);
list_add_tail(&block_cb->driver_list, &mlxsw_sp_block_cb_list);
return 0;
case FLOW_BLOCK_UNBIND:
mlxsw_sp_setup_tc_block_flower_unbind(mlxsw_sp_port,
f->block, ingress);
tcf_block_cb_unregister(f->block, cb, mlxsw_sp_port);
f, ingress);
block_cb = flow_block_cb_lookup(f, cb, mlxsw_sp_port);
if (!block_cb)
return -ENOENT;

flow_block_cb_remove(block_cb, f);
list_del(&block_cb->driver_list);
return 0;
default:
return -EOPNOTSUPP;
Expand Down
Loading

0 comments on commit 955bcb6

Please sign in to comment.