Commit c40f4e50 authored by Petr Machata's avatar Petr Machata Committed by David S. Miller
Browse files

net: sched: Pass qdisc reference in struct flow_block_offload



Previously, shared blocks were only relevant for the pseudo-qdiscs ingress
and clsact. Recently, a qevent facility was introduced, which allows to
bind blocks to well-defined slots of a qdisc instance. RED in particular
got two qevents: early_drop and mark. Drivers that wish to offload these
blocks will be sent the usual notification, and need to know which qdisc it
is related to.

To that end, extend flow_block_offload with a "sch" pointer, and initialize
as appropriate. This prompts changes in the indirect block facility, which
now tracks the scheduler in addition to the netdevice. Update signatures of
several functions similarly.

Signed-off-by: default avatarPetr Machata <petrm@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e1d82f7a
Loading
Loading
Loading
Loading
+4 −5
Original line number Original line Diff line number Diff line
@@ -1888,7 +1888,7 @@ static void bnxt_tc_setup_indr_rel(void *cb_priv)
	kfree(priv);
	kfree(priv);
}
}


static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp,
static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct Qdisc *sch, struct bnxt *bp,
				    struct flow_block_offload *f, void *data,
				    struct flow_block_offload *f, void *data,
				    void (*cleanup)(struct flow_block_cb *block_cb))
				    void (*cleanup)(struct flow_block_cb *block_cb))
{
{
@@ -1911,7 +1911,7 @@ static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp,
		block_cb = flow_indr_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,
						    cb_priv, cb_priv,
						    bnxt_tc_setup_indr_rel, f,
						    bnxt_tc_setup_indr_rel, f,
						    netdev, data, bp, cleanup);
						    netdev, sch, data, bp, cleanup);
		if (IS_ERR(block_cb)) {
		if (IS_ERR(block_cb)) {
			list_del(&cb_priv->list);
			list_del(&cb_priv->list);
			kfree(cb_priv);
			kfree(cb_priv);
@@ -1946,7 +1946,7 @@ static bool bnxt_is_netdev_indr_offload(struct net_device *netdev)
	return netif_is_vxlan(netdev);
	return netif_is_vxlan(netdev);
}
}


static int bnxt_tc_setup_indr_cb(struct net_device *netdev, void *cb_priv,
static int bnxt_tc_setup_indr_cb(struct net_device *netdev, struct Qdisc *sch, void *cb_priv,
				 enum tc_setup_type type, void *type_data,
				 enum tc_setup_type type, void *type_data,
				 void *data,
				 void *data,
				 void (*cleanup)(struct flow_block_cb *block_cb))
				 void (*cleanup)(struct flow_block_cb *block_cb))
@@ -1956,8 +1956,7 @@ static int bnxt_tc_setup_indr_cb(struct net_device *netdev, void *cb_priv,


	switch (type) {
	switch (type) {
	case TC_SETUP_BLOCK:
	case TC_SETUP_BLOCK:
		return bnxt_tc_setup_indr_block(netdev, cb_priv, type_data, data,
		return bnxt_tc_setup_indr_block(netdev, sch, cb_priv, type_data, data, cleanup);
						cleanup);
	default:
	default:
		break;
		break;
	}
	}
+5 −5
Original line number Original line Diff line number Diff line
@@ -404,7 +404,7 @@ static void mlx5e_rep_indr_block_unbind(void *cb_priv)
static LIST_HEAD(mlx5e_block_cb_list);
static LIST_HEAD(mlx5e_block_cb_list);


static int
static int
mlx5e_rep_indr_setup_block(struct net_device *netdev,
mlx5e_rep_indr_setup_block(struct net_device *netdev, struct Qdisc *sch,
			   struct mlx5e_rep_priv *rpriv,
			   struct mlx5e_rep_priv *rpriv,
			   struct flow_block_offload *f,
			   struct flow_block_offload *f,
			   flow_setup_cb_t *setup_cb,
			   flow_setup_cb_t *setup_cb,
@@ -442,7 +442,7 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev,


		block_cb = flow_indr_block_cb_alloc(setup_cb, indr_priv, indr_priv,
		block_cb = flow_indr_block_cb_alloc(setup_cb, indr_priv, indr_priv,
						    mlx5e_rep_indr_block_unbind,
						    mlx5e_rep_indr_block_unbind,
						    f, netdev, data, rpriv,
						    f, netdev, sch, data, rpriv,
						    cleanup);
						    cleanup);
		if (IS_ERR(block_cb)) {
		if (IS_ERR(block_cb)) {
			list_del(&indr_priv->list);
			list_del(&indr_priv->list);
@@ -472,18 +472,18 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev,
}
}


static
static
int mlx5e_rep_indr_setup_cb(struct net_device *netdev, void *cb_priv,
int mlx5e_rep_indr_setup_cb(struct net_device *netdev, struct Qdisc *sch, void *cb_priv,
			    enum tc_setup_type type, void *type_data,
			    enum tc_setup_type type, void *type_data,
			    void *data,
			    void *data,
			    void (*cleanup)(struct flow_block_cb *block_cb))
			    void (*cleanup)(struct flow_block_cb *block_cb))
{
{
	switch (type) {
	switch (type) {
	case TC_SETUP_BLOCK:
	case TC_SETUP_BLOCK:
		return mlx5e_rep_indr_setup_block(netdev, cb_priv, type_data,
		return mlx5e_rep_indr_setup_block(netdev, sch, cb_priv, type_data,
						  mlx5e_rep_indr_setup_tc_cb,
						  mlx5e_rep_indr_setup_tc_cb,
						  data, cleanup);
						  data, cleanup);
	case TC_SETUP_FT:
	case TC_SETUP_FT:
		return mlx5e_rep_indr_setup_block(netdev, cb_priv, type_data,
		return mlx5e_rep_indr_setup_block(netdev, sch, cb_priv, type_data,
						  mlx5e_rep_indr_setup_ft_cb,
						  mlx5e_rep_indr_setup_ft_cb,
						  data, cleanup);
						  data, cleanup);
	default:
	default:
+1 −1
Original line number Original line Diff line number Diff line
@@ -458,7 +458,7 @@ void nfp_flower_qos_cleanup(struct nfp_app *app);
int nfp_flower_setup_qos_offload(struct nfp_app *app, struct net_device *netdev,
int nfp_flower_setup_qos_offload(struct nfp_app *app, struct net_device *netdev,
				 struct tc_cls_matchall_offload *flow);
				 struct tc_cls_matchall_offload *flow);
void nfp_flower_stats_rlim_reply(struct nfp_app *app, struct sk_buff *skb);
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,
int nfp_flower_indr_setup_tc_cb(struct net_device *netdev, struct Qdisc *sch, void *cb_priv,
				enum tc_setup_type type, void *type_data,
				enum tc_setup_type type, void *type_data,
				void *data,
				void *data,
				void (*cleanup)(struct flow_block_cb *block_cb));
				void (*cleanup)(struct flow_block_cb *block_cb));
+4 −4
Original line number Original line Diff line number Diff line
@@ -1646,7 +1646,7 @@ void nfp_flower_setup_indr_tc_release(void *cb_priv)
}
}


static int
static int
nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct Qdisc *sch, struct nfp_app *app,
			       struct flow_block_offload *f, void *data,
			       struct flow_block_offload *f, void *data,
			       void (*cleanup)(struct flow_block_cb *block_cb))
			       void (*cleanup)(struct flow_block_cb *block_cb))
{
{
@@ -1680,7 +1680,7 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
		block_cb = flow_indr_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,
						    cb_priv, cb_priv,
						    nfp_flower_setup_indr_tc_release,
						    nfp_flower_setup_indr_tc_release,
						    f, netdev, data, app, cleanup);
						    f, netdev, sch, data, app, cleanup);
		if (IS_ERR(block_cb)) {
		if (IS_ERR(block_cb)) {
			list_del(&cb_priv->list);
			list_del(&cb_priv->list);
			kfree(cb_priv);
			kfree(cb_priv);
@@ -1711,7 +1711,7 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
}
}


int
int
nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,
nfp_flower_indr_setup_tc_cb(struct net_device *netdev, struct Qdisc *sch, void *cb_priv,
			    enum tc_setup_type type, void *type_data,
			    enum tc_setup_type type, void *type_data,
			    void *data,
			    void *data,
			    void (*cleanup)(struct flow_block_cb *block_cb))
			    void (*cleanup)(struct flow_block_cb *block_cb))
@@ -1721,7 +1721,7 @@ nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,


	switch (type) {
	switch (type) {
	case TC_SETUP_BLOCK:
	case TC_SETUP_BLOCK:
		return nfp_flower_setup_indr_tc_block(netdev, cb_priv,
		return nfp_flower_setup_indr_tc_block(netdev, sch, cb_priv,
						      type_data, data, cleanup);
						      type_data, data, cleanup);
	default:
	default:
		return -EOPNOTSUPP;
		return -EOPNOTSUPP;
+6 −3
Original line number Original line Diff line number Diff line
@@ -444,6 +444,7 @@ struct flow_block_offload {
	struct list_head cb_list;
	struct list_head cb_list;
	struct list_head *driver_block_list;
	struct list_head *driver_block_list;
	struct netlink_ext_ack *extack;
	struct netlink_ext_ack *extack;
	struct Qdisc *sch;
};
};


enum tc_setup_type;
enum tc_setup_type;
@@ -455,6 +456,7 @@ struct flow_block_cb;
struct flow_block_indr {
struct flow_block_indr {
	struct list_head		list;
	struct list_head		list;
	struct net_device		*dev;
	struct net_device		*dev;
	struct Qdisc			*sch;
	enum flow_block_binder_type	binder_type;
	enum flow_block_binder_type	binder_type;
	void				*data;
	void				*data;
	void				*cb_priv;
	void				*cb_priv;
@@ -479,7 +481,8 @@ struct flow_block_cb *flow_indr_block_cb_alloc(flow_setup_cb_t *cb,
					       void *cb_ident, void *cb_priv,
					       void *cb_ident, void *cb_priv,
					       void (*release)(void *cb_priv),
					       void (*release)(void *cb_priv),
					       struct flow_block_offload *bo,
					       struct flow_block_offload *bo,
					       struct net_device *dev, void *data,
					       struct net_device *dev,
					       struct Qdisc *sch, void *data,
					       void *indr_cb_priv,
					       void *indr_cb_priv,
					       void (*cleanup)(struct flow_block_cb *block_cb));
					       void (*cleanup)(struct flow_block_cb *block_cb));
void flow_block_cb_free(struct flow_block_cb *block_cb);
void flow_block_cb_free(struct flow_block_cb *block_cb);
@@ -553,7 +556,7 @@ static inline void flow_block_init(struct flow_block *flow_block)
	INIT_LIST_HEAD(&flow_block->cb_list);
	INIT_LIST_HEAD(&flow_block->cb_list);
}
}


typedef int flow_indr_block_bind_cb_t(struct net_device *dev, void *cb_priv,
typedef int flow_indr_block_bind_cb_t(struct net_device *dev, struct Qdisc *sch, void *cb_priv,
				      enum tc_setup_type type, void *type_data,
				      enum tc_setup_type type, void *type_data,
				      void *data,
				      void *data,
				      void (*cleanup)(struct flow_block_cb *block_cb));
				      void (*cleanup)(struct flow_block_cb *block_cb));
@@ -561,7 +564,7 @@ typedef int flow_indr_block_bind_cb_t(struct net_device *dev, void *cb_priv,
int flow_indr_dev_register(flow_indr_block_bind_cb_t *cb, void *cb_priv);
int flow_indr_dev_register(flow_indr_block_bind_cb_t *cb, void *cb_priv);
void flow_indr_dev_unregister(flow_indr_block_bind_cb_t *cb, void *cb_priv,
void flow_indr_dev_unregister(flow_indr_block_bind_cb_t *cb, void *cb_priv,
			      void (*release)(void *cb_priv));
			      void (*release)(void *cb_priv));
int flow_indr_dev_setup_offload(struct net_device *dev,
int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch,
				enum tc_setup_type type, void *data,
				enum tc_setup_type type, void *data,
				struct flow_block_offload *bo,
				struct flow_block_offload *bo,
				void (*cleanup)(struct flow_block_cb *block_cb));
				void (*cleanup)(struct flow_block_cb *block_cb));
Loading