Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 745482e0 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'sched-tp_q-remove'



Jiri Pirko <jiri@mellanox.com>

====================
net: sched: remove some tp->q usage

In order to prepare for block sharing, tcf_proto instances need to be
independent on particular qdisc instances. This patchset takes care of
removal of couple occurrences of tp->q usage.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 32302902 a10fa201
Loading
Loading
Loading
Loading
+40 −12
Original line number Diff line number Diff line
@@ -22,15 +22,26 @@ struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
				bool create);
void tcf_chain_put(struct tcf_chain *chain);
int tcf_block_get(struct tcf_block **p_block,
		  struct tcf_proto __rcu **p_filter_chain);
		  struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q);
void tcf_block_put(struct tcf_block *block);

static inline struct Qdisc *tcf_block_q(struct tcf_block *block)
{
	return block->q;
}

static inline struct net_device *tcf_block_dev(struct tcf_block *block)
{
	return tcf_block_q(block)->dev_queue->dev;
}

int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
		 struct tcf_result *res, bool compat_mode);

#else
static inline
int tcf_block_get(struct tcf_block **p_block,
		  struct tcf_proto __rcu **p_filter_chain)
		  struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q)
{
	return 0;
}
@@ -39,6 +50,16 @@ static inline void tcf_block_put(struct tcf_block *block)
{
}

static inline struct Qdisc *tcf_block_q(struct tcf_block *block)
{
	return NULL;
}

static inline struct net_device *tcf_block_dev(struct tcf_block *block)
{
	return NULL;
}

static inline int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
			       struct tcf_result *res, bool compat_mode)
{
@@ -53,36 +74,43 @@ __cls_set_class(unsigned long *clp, unsigned long cl)
}

static inline unsigned long
cls_set_class(struct tcf_proto *tp, unsigned long *clp, 
	unsigned long cl)
cls_set_class(struct Qdisc *q, unsigned long *clp, unsigned long cl)
{
	unsigned long old_cl;

	tcf_tree_lock(tp);
	sch_tree_lock(q);
	old_cl = __cls_set_class(clp, cl);
	tcf_tree_unlock(tp);
 
	sch_tree_unlock(q);
	return old_cl;
}

static inline void
tcf_bind_filter(struct tcf_proto *tp, struct tcf_result *r, unsigned long base)
{
	struct Qdisc *q = tp->chain->block->q;
	unsigned long cl;

	cl = tp->q->ops->cl_ops->bind_tcf(tp->q, base, r->classid);
	cl = cls_set_class(tp, &r->class, cl);
	/* Check q as it is not set for shared blocks. In that case,
	 * setting class is not supported.
	 */
	if (!q)
		return;
	cl = q->ops->cl_ops->bind_tcf(q, base, r->classid);
	cl = cls_set_class(q, &r->class, cl);
	if (cl)
		tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
		q->ops->cl_ops->unbind_tcf(q, cl);
}

static inline void
tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r)
{
	struct Qdisc *q = tp->chain->block->q;
	unsigned long cl;

	if (!q)
		return;
	if ((cl = __cls_set_class(&r->class, 0)) != 0)
		tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
		q->ops->cl_ops->unbind_tcf(q, cl);
}

struct tcf_exts {
+7 −0
Original line number Diff line number Diff line
@@ -4,7 +4,9 @@
#include <linux/jiffies.h>
#include <linux/ktime.h>
#include <linux/if_vlan.h>
#include <linux/netdevice.h>
#include <net/sch_generic.h>
#include <net/net_namespace.h>
#include <uapi/linux/pkt_sched.h>

#define DEFAULT_TX_QUEUE_LEN	1000
@@ -146,4 +148,9 @@ static inline bool is_classid_clsact_egress(u32 classid)
	       TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_EGRESS);
}

static inline struct net *qdisc_net(struct Qdisc *q)
{
	return dev_net(q->dev_queue->dev);
}

#endif
+2 −3
Original line number Diff line number Diff line
@@ -270,6 +270,8 @@ struct tcf_chain {

struct tcf_block {
	struct list_head chain_list;
	struct net *net;
	struct Qdisc *q;
};

static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
@@ -357,9 +359,6 @@ static inline void sch_tree_unlock(const struct Qdisc *q)
	spin_unlock_bh(qdisc_root_sleeping_lock(q));
}

#define tcf_tree_lock(tp)	sch_tree_lock((tp)->q)
#define tcf_tree_unlock(tp)	sch_tree_unlock((tp)->q)

extern struct Qdisc noop_qdisc;
extern struct Qdisc_ops noop_qdisc_ops;
extern struct Qdisc_ops pfifo_fast_ops;
+38 −21
Original line number Diff line number Diff line
@@ -241,7 +241,7 @@ tcf_chain_filter_chain_ptr_set(struct tcf_chain *chain,
}

int tcf_block_get(struct tcf_block **p_block,
		  struct tcf_proto __rcu **p_filter_chain)
		  struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q)
{
	struct tcf_block *block = kzalloc(sizeof(*block), GFP_KERNEL);
	struct tcf_chain *chain;
@@ -257,6 +257,8 @@ int tcf_block_get(struct tcf_block **p_block,
		goto err_chain_create;
	}
	tcf_chain_filter_chain_ptr_set(chain, p_filter_chain);
	block->net = qdisc_net(q);
	block->q = q;
	*p_block = block;
	return 0;

@@ -418,8 +420,8 @@ static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain,
}

static int tcf_fill_node(struct net *net, struct sk_buff *skb,
			 struct tcf_proto *tp, void *fh, u32 portid,
			 u32 seq, u16 flags, int event)
			 struct tcf_proto *tp, struct Qdisc *q, u32 parent,
			 void *fh, u32 portid, u32 seq, u16 flags, int event)
{
	struct tcmsg *tcm;
	struct nlmsghdr  *nlh;
@@ -432,8 +434,8 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb,
	tcm->tcm_family = AF_UNSPEC;
	tcm->tcm__pad1 = 0;
	tcm->tcm__pad2 = 0;
	tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex;
	tcm->tcm_parent = tp->classid;
	tcm->tcm_ifindex = qdisc_dev(q)->ifindex;
	tcm->tcm_parent = parent;
	tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
	if (nla_put_string(skb, TCA_KIND, tp->ops->kind))
		goto nla_put_failure;
@@ -456,6 +458,7 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb,

static int tfilter_notify(struct net *net, struct sk_buff *oskb,
			  struct nlmsghdr *n, struct tcf_proto *tp,
			  struct Qdisc *q, u32 parent,
			  void *fh, int event, bool unicast)
{
	struct sk_buff *skb;
@@ -465,7 +468,7 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb,
	if (!skb)
		return -ENOBUFS;

	if (tcf_fill_node(net, skb, tp, fh, portid, n->nlmsg_seq,
	if (tcf_fill_node(net, skb, tp, q, parent, fh, portid, n->nlmsg_seq,
			  n->nlmsg_flags, event) <= 0) {
		kfree_skb(skb);
		return -EINVAL;
@@ -480,6 +483,7 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb,

static int tfilter_del_notify(struct net *net, struct sk_buff *oskb,
			      struct nlmsghdr *n, struct tcf_proto *tp,
			      struct Qdisc *q, u32 parent,
			      void *fh, bool unicast, bool *last)
{
	struct sk_buff *skb;
@@ -490,7 +494,7 @@ static int tfilter_del_notify(struct net *net, struct sk_buff *oskb,
	if (!skb)
		return -ENOBUFS;

	if (tcf_fill_node(net, skb, tp, fh, portid, n->nlmsg_seq,
	if (tcf_fill_node(net, skb, tp, q, parent, fh, portid, n->nlmsg_seq,
			  n->nlmsg_flags, RTM_DELTFILTER) <= 0) {
		kfree_skb(skb);
		return -EINVAL;
@@ -510,6 +514,7 @@ static int tfilter_del_notify(struct net *net, struct sk_buff *oskb,
}

static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb,
				 struct Qdisc *q, u32 parent,
				 struct nlmsghdr *n,
				 struct tcf_chain *chain, int event)
{
@@ -517,7 +522,7 @@ static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb,

	for (tp = rtnl_dereference(chain->filter_chain);
	     tp; tp = rtnl_dereference(tp->next))
		tfilter_notify(net, oskb, n, tp, 0, event, false);
		tfilter_notify(net, oskb, n, tp, q, parent, 0, event, false);
}

/* Add/change/delete/get a filter node */
@@ -636,7 +641,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
	}

	if (n->nlmsg_type == RTM_DELTFILTER && prio == 0) {
		tfilter_notify_chain(net, skb, n, chain, RTM_DELTFILTER);
		tfilter_notify_chain(net, skb, q, parent, n,
				     chain, RTM_DELTFILTER);
		tcf_chain_flush(chain);
		err = 0;
		goto errout;
@@ -683,7 +689,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
	if (!fh) {
		if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
			tcf_chain_tp_remove(chain, &chain_info, tp);
			tfilter_notify(net, skb, n, tp, fh,
			tfilter_notify(net, skb, n, tp, q, parent, fh,
				       RTM_DELTFILTER, false);
			tcf_proto_destroy(tp);
			err = 0;
@@ -708,8 +714,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
			}
			break;
		case RTM_DELTFILTER:
			err = tfilter_del_notify(net, skb, n, tp, fh, false,
						 &last);
			err = tfilter_del_notify(net, skb, n, tp, q, parent,
						 fh, false, &last);
			if (err)
				goto errout;
			if (last) {
@@ -718,7 +724,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
			}
			goto errout;
		case RTM_GETTFILTER:
			err = tfilter_notify(net, skb, n, tp, fh,
			err = tfilter_notify(net, skb, n, tp, q, parent, fh,
					     RTM_NEWTFILTER, true);
			goto errout;
		default:
@@ -732,7 +738,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
	if (err == 0) {
		if (tp_created)
			tcf_chain_tp_insert(chain, &chain_info, tp);
		tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER, false);
		tfilter_notify(net, skb, n, tp, q, parent, fh,
			       RTM_NEWTFILTER, false);
	} else {
		if (tp_created)
			tcf_proto_destroy(tp);
@@ -751,6 +758,8 @@ struct tcf_dump_args {
	struct tcf_walker w;
	struct sk_buff *skb;
	struct netlink_callback *cb;
	struct Qdisc *q;
	u32 parent;
};

static int tcf_node_dump(struct tcf_proto *tp, void *n, struct tcf_walker *arg)
@@ -758,13 +767,14 @@ static int tcf_node_dump(struct tcf_proto *tp, void *n, struct tcf_walker *arg)
	struct tcf_dump_args *a = (void *)arg;
	struct net *net = sock_net(a->skb->sk);

	return tcf_fill_node(net, a->skb, tp, n, NETLINK_CB(a->cb->skb).portid,
	return tcf_fill_node(net, a->skb, tp, a->q, a->parent,
			     n, NETLINK_CB(a->cb->skb).portid,
			     a->cb->nlh->nlmsg_seq, NLM_F_MULTI,
			     RTM_NEWTFILTER);
}

static bool tcf_chain_dump(struct tcf_chain *chain, struct sk_buff *skb,
			   struct netlink_callback *cb,
static bool tcf_chain_dump(struct tcf_chain *chain, struct Qdisc *q, u32 parent,
			   struct sk_buff *skb, struct netlink_callback *cb,
			   long index_start, long *p_index)
{
	struct net *net = sock_net(skb->sk);
@@ -786,7 +796,7 @@ static bool tcf_chain_dump(struct tcf_chain *chain, struct sk_buff *skb,
			memset(&cb->args[1], 0,
			       sizeof(cb->args) - sizeof(cb->args[0]));
		if (cb->args[1] == 0) {
			if (tcf_fill_node(net, skb, tp, 0,
			if (tcf_fill_node(net, skb, tp, q, parent, 0,
					  NETLINK_CB(cb->skb).portid,
					  cb->nlh->nlmsg_seq, NLM_F_MULTI,
					  RTM_NEWTFILTER) <= 0)
@@ -799,6 +809,8 @@ static bool tcf_chain_dump(struct tcf_chain *chain, struct sk_buff *skb,
		arg.w.fn = tcf_node_dump;
		arg.skb = skb;
		arg.cb = cb;
		arg.q = q;
		arg.parent = parent;
		arg.w.stop = 0;
		arg.w.skip = cb->args[1] - 1;
		arg.w.count = 0;
@@ -824,6 +836,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
	const struct Qdisc_class_ops *cops;
	long index_start;
	long index;
	u32 parent;
	int err;

	if (nlmsg_len(cb->nlh) < sizeof(*tcm))
@@ -837,10 +850,13 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
	if (!dev)
		return skb->len;

	if (!tcm->tcm_parent)
	parent = tcm->tcm_parent;
	if (!parent) {
		q = dev->qdisc;
	else
		parent = q->handle;
	} else {
		q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent));
	}
	if (!q)
		goto out;
	cops = q->ops->cl_ops;
@@ -864,7 +880,8 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
		if (tca[TCA_CHAIN] &&
		    nla_get_u32(tca[TCA_CHAIN]) != chain->index)
			continue;
		if (!tcf_chain_dump(chain, skb, cb, index_start, &index))
		if (!tcf_chain_dump(chain, q, parent, skb, cb,
				    index_start, &index))
			break;
	}

+5 −2
Original line number Diff line number Diff line
@@ -491,8 +491,11 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
			perturb_period = nla_get_u32(tb[TCA_FLOW_PERTURB]) * HZ;
		}

		if (TC_H_MAJ(baseclass) == 0)
			baseclass = TC_H_MAKE(tp->q->handle, baseclass);
		if (TC_H_MAJ(baseclass) == 0) {
			struct Qdisc *q = tcf_block_q(tp->chain->block);

			baseclass = TC_H_MAKE(q->handle, baseclass);
		}
		if (TC_H_MIN(baseclass) == 0)
			baseclass = TC_H_MAKE(baseclass, 1);

Loading