All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] net_sched: misc cleanups and improvements
@ 2014-11-04 17:56 Cong Wang
  2014-11-04 17:56 ` [PATCH 01/13] net_sched: refactor out tcf_exts Cong Wang
                   ` (13 more replies)
  0 siblings, 14 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev

Minor code cleanups for TC qdiscs and filters, each patch has
more details.

Cong Wang (13):
      net_sched: refactor out tcf_exts
      net_sched: introduce qdisc_peek() helper function
      net_sched: rename ->gso_skb to ->dequeued_skb
      net_sched: rename qdisc_drop() to qdisc_drop_skb()
      net_sched: introduce qdisc_drop() helper function
      net_sched: move some qdisc flag into qdisc ops
      net_sched: move TCQ_F_MQROOT into qdisc ops
      net_sched: use a flag to indicate fifo qdiscs instead of the name
      net_sched: redefine qdisc_create_dflt()
      net_sched: forbid setting default qdisc to inappropriate ones
      net_sched: remove hashmask from Qdisc_class_hash
      net_sched: remove useless qdisc_stab_lock
      net_sched: return NULL instead of ERR_PTR for qdisc_alloc()

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 01/13] net_sched: refactor out tcf_exts
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
@ 2014-11-04 17:56 ` Cong Wang
  2014-11-04 17:56 ` [PATCH 02/13] net_sched: introduce qdisc_peek() helper function Cong Wang
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang, Jamal Hadi Salim, John Fastabend, David S. Miller

As Jamal pointed it out, tcf_exts is really unnecessary,
we can definitely refactor it out without losing any functionality.
This could also remove an indirect layer which makes the code
much easier to read.

This patch:

1) moves exts->action and exts->police into tp->ops, since they
are statically assigned

2) moves exts->actions list head out

3) removes exts->type, act->type does the same thing

4) renames tcf_exts_*() functions to tcf_act_*()

Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: John Fastabend <john.r.fastabend@intel.com>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 include/net/pkt_cls.h     | 80 ++++++++++++++++++-----------------------------
 include/net/sch_generic.h |  2 ++
 net/sched/act_api.c       |  9 ++++--
 net/sched/cls_api.c       | 78 +++++++++++++++++++++++----------------------
 net/sched/cls_basic.c     | 23 +++++++-------
 net/sched/cls_bpf.c       | 24 +++++++-------
 net/sched/cls_cgroup.c    | 23 +++++++-------
 net/sched/cls_flow.c      | 23 +++++++-------
 net/sched/cls_fw.c        | 27 ++++++++--------
 net/sched/cls_route.c     | 25 ++++++++-------
 net/sched/cls_rsvp.h      | 27 ++++++++--------
 net/sched/cls_tcindex.c   | 36 ++++++++++-----------
 net/sched/cls_u32.c       | 26 +++++++--------
 13 files changed, 198 insertions(+), 205 deletions(-)

diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index bc49967..383353a 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -56,88 +56,68 @@ tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r)
 		tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
 }
 
-struct tcf_exts {
-#ifdef CONFIG_NET_CLS_ACT
-	__u32	type; /* for backward compat(TCA_OLD_COMPAT) */
-	struct list_head actions;
-#endif
-	/* Map to export classifier specific extension TLV types to the
-	 * generic extensions API. Unsupported extensions must be set to 0.
-	 */
-	int action;
-	int police;
-};
-
-static inline void tcf_exts_init(struct tcf_exts *exts, int action, int police)
-{
-#ifdef CONFIG_NET_CLS_ACT
-	exts->type = 0;
-	INIT_LIST_HEAD(&exts->actions);
-#endif
-	exts->action = action;
-	exts->police = police;
-}
-
 /**
- * tcf_exts_is_predicative - check if a predicative extension is present
- * @exts: tc filter extensions handle
+ * tcf_act_is_predicative - check if a predicative action is present
+ * @actions: tc filter actions
  *
- * Returns 1 if a predicative extension is present, i.e. an extension which
+ * Returns 1 if a predicative action is present, i.e. an action which
  * might cause further actions and thus overrule the regular tcf_result.
  */
 static inline int
-tcf_exts_is_predicative(struct tcf_exts *exts)
+tcf_act_is_predicative(struct list_head *actions)
 {
 #ifdef CONFIG_NET_CLS_ACT
-	return !list_empty(&exts->actions);
+	return !list_empty(actions);
 #else
 	return 0;
 #endif
 }
 
 /**
- * tcf_exts_is_available - check if at least one extension is present
- * @exts: tc filter extensions handle
+ * tcf_act_is_available - check if at least one action is present
+ * @actions: tc filter actions
  *
- * Returns 1 if at least one extension is present.
+ * Returns 1 if at least one action is present.
  */
 static inline int
-tcf_exts_is_available(struct tcf_exts *exts)
+tcf_act_is_available(struct list_head *actions)
 {
-	/* All non-predicative extensions must be added here. */
-	return tcf_exts_is_predicative(exts);
+	/* All non-predicative actions must be added here. */
+	return tcf_act_is_predicative(actions);
 }
 
 /**
- * tcf_exts_exec - execute tc filter extensions
+ * tcf_act_exec - execute tc filter actions
  * @skb: socket buffer
- * @exts: tc filter extensions handle
+ * @actions: list of actions
  * @res: desired result
  *
- * Executes all configured extensions. Returns 0 on a normal execution,
+ * Executes all configured actions. Returns 0 on a normal execution,
  * a negative number if the filter must be considered unmatched or
  * a positive action code (TC_ACT_*) which must be returned to the
  * underlying layer.
  */
-static inline int
-tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
-	       struct tcf_result *res)
-{
 #ifdef CONFIG_NET_CLS_ACT
-	if (!list_empty(&exts->actions))
-		return tcf_action_exec(skb, &exts->actions, res);
-#endif
+int tcf_act_exec(struct sk_buff *skb, struct list_head *actions,
+		 struct tcf_result *res);
+#else
+static inline
+int tcf_act_exec(struct sk_buff *skb, struct list_head *actions,
+		 struct tcf_result *res)
+{
 	return 0;
 }
+#endif
 
-int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
+int tcf_act_validate(struct net *net, struct tcf_proto *tp,
 		      struct nlattr **tb, struct nlattr *rate_tlv,
-		      struct tcf_exts *exts, bool ovr);
-void tcf_exts_destroy(struct tcf_exts *exts);
-void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
-		     struct tcf_exts *src);
-int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts);
-int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts);
+		      struct list_head *actions, bool ovr);
+void tcf_act_destroy(struct list_head *actions);
+void tcf_act_change(struct tcf_proto *tp, struct list_head *dst,
+		     struct list_head *src);
+int tcf_act_dump(struct sk_buff *skb, const struct tcf_proto *tp,
+		 struct list_head *actions);
+int tcf_act_dump_stats(struct sk_buff *skb, struct list_head *actions);
 
 /**
  * struct tcf_pkt_info - packet information
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index d17ed6f..3d9fac9 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -211,6 +211,8 @@ struct tcf_result {
 struct tcf_proto_ops {
 	struct list_head	head;
 	char			kind[IFNAMSIZ];
+	int			action;
+	int			police;
 
 	int			(*classify)(struct sk_buff *,
 					    const struct tcf_proto *,
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 3d43e49..a350598 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -378,12 +378,15 @@ static struct tc_action_ops *tc_lookup_action(struct nlattr *kind)
 	return res;
 }
 
-int tcf_action_exec(struct sk_buff *skb, const struct list_head *actions,
-		    struct tcf_result *res)
+int tcf_act_exec(struct sk_buff *skb, const struct list_head *actions,
+		 struct tcf_result *res)
 {
 	const struct tc_action *a;
 	int ret = -1;
 
+	if (list_empty(actions))
+		return 0;
+
 	if (skb->tc_verd & TC_NCLS) {
 		skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
 		ret = TC_ACT_OK;
@@ -405,7 +408,7 @@ int tcf_action_exec(struct sk_buff *skb, const struct list_head *actions,
 exec_done:
 	return ret;
 }
-EXPORT_SYMBOL(tcf_action_exec);
+EXPORT_SYMBOL(tcf_act_exec);
 
 int tcf_action_destroy(struct list_head *actions, int bind)
 {
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index aad6a67..d6f0059 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -496,90 +496,94 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
 	return skb->len;
 }
 
-void tcf_exts_destroy(struct tcf_exts *exts)
+void tcf_act_destroy(struct list_head *actions)
 {
 #ifdef CONFIG_NET_CLS_ACT
-	tcf_action_destroy(&exts->actions, TCA_ACT_UNBIND);
-	INIT_LIST_HEAD(&exts->actions);
+	tcf_action_destroy(actions, TCA_ACT_UNBIND);
+	INIT_LIST_HEAD(actions);
 #endif
 }
-EXPORT_SYMBOL(tcf_exts_destroy);
+EXPORT_SYMBOL(tcf_act_destroy);
 
-int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
-		  struct nlattr *rate_tlv, struct tcf_exts *exts, bool ovr)
+int tcf_act_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
+		     struct nlattr *rate_tlv, struct list_head *actions,
+		     bool ovr)
 {
+	int police = tp->ops->police;
+	int action = tp->ops->action;
+
 #ifdef CONFIG_NET_CLS_ACT
 	{
 		struct tc_action *act;
 
-		INIT_LIST_HEAD(&exts->actions);
-		if (exts->police && tb[exts->police]) {
-			act = tcf_action_init_1(net, tb[exts->police], rate_tlv,
+		INIT_LIST_HEAD(actions);
+		if (police && tb[police]) {
+			act = tcf_action_init_1(net, tb[police], rate_tlv,
 						"police", ovr,
 						TCA_ACT_BIND);
 			if (IS_ERR(act))
 				return PTR_ERR(act);
 
-			act->type = exts->type = TCA_OLD_COMPAT;
-			list_add(&act->list, &exts->actions);
-		} else if (exts->action && tb[exts->action]) {
+			act->type = TCA_OLD_COMPAT;
+			list_add(&act->list, actions);
+		} else if (action && tb[action]) {
 			int err;
-			err = tcf_action_init(net, tb[exts->action], rate_tlv,
+			err = tcf_action_init(net, tb[action], rate_tlv,
 					      NULL, ovr,
-					      TCA_ACT_BIND, &exts->actions);
+					      TCA_ACT_BIND, actions);
 			if (err)
 				return err;
 		}
 	}
 #else
-	if ((exts->action && tb[exts->action]) ||
-	    (exts->police && tb[exts->police]))
+	if ((action && tb[action]) ||
+	    (police && tb[police]))
 		return -EOPNOTSUPP;
 #endif
 
 	return 0;
 }
-EXPORT_SYMBOL(tcf_exts_validate);
+EXPORT_SYMBOL(tcf_act_validate);
 
-void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
-		     struct tcf_exts *src)
+void tcf_act_change(struct tcf_proto *tp, struct list_head *dst,
+		    struct list_head *src)
 {
 #ifdef CONFIG_NET_CLS_ACT
 	LIST_HEAD(tmp);
 	tcf_tree_lock(tp);
-	list_splice_init(&dst->actions, &tmp);
-	list_splice(&src->actions, &dst->actions);
-	dst->type = src->type;
+	list_splice_init(dst, &tmp);
+	list_splice(src, dst);
 	tcf_tree_unlock(tp);
 	tcf_action_destroy(&tmp, TCA_ACT_UNBIND);
 #endif
 }
-EXPORT_SYMBOL(tcf_exts_change);
+EXPORT_SYMBOL(tcf_act_change);
 
-#define tcf_exts_first_act(ext) \
-		list_first_entry(&(exts)->actions, struct tc_action, list)
+#define tcf_act_first_act(actions) \
+		list_first_entry(actions, struct tc_action, list)
 
-int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts)
+int tcf_act_dump(struct sk_buff *skb, const struct tcf_proto *tp,
+		 struct list_head *actions)
 {
 #ifdef CONFIG_NET_CLS_ACT
 	struct nlattr *nest;
 
-	if (exts->action && !list_empty(&exts->actions)) {
+	if (tp->ops->action && !list_empty(actions)) {
+		struct tc_action *act = tcf_act_first_act(actions);
 		/*
 		 * again for backward compatible mode - we want
 		 * to work with both old and new modes of entering
 		 * tc data even if iproute2  was newer - jhs
 		 */
-		if (exts->type != TCA_OLD_COMPAT) {
-			nest = nla_nest_start(skb, exts->action);
+		if (act->type != TCA_OLD_COMPAT) {
+			nest = nla_nest_start(skb, tp->ops->action);
 			if (nest == NULL)
 				goto nla_put_failure;
-			if (tcf_action_dump(skb, &exts->actions, 0, 0) < 0)
+			if (tcf_action_dump(skb, actions, 0, 0) < 0)
 				goto nla_put_failure;
 			nla_nest_end(skb, nest);
-		} else if (exts->police) {
-			struct tc_action *act = tcf_exts_first_act(exts);
-			nest = nla_nest_start(skb, exts->police);
+		} else if (tp->ops->police) {
+			nest = nla_nest_start(skb, tp->ops->police);
 			if (nest == NULL || !act)
 				goto nla_put_failure;
 			if (tcf_action_dump_old(skb, act, 0, 0) < 0)
@@ -596,19 +600,19 @@ int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts)
 	return 0;
 #endif
 }
-EXPORT_SYMBOL(tcf_exts_dump);
+EXPORT_SYMBOL(tcf_act_dump);
 
 
-int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts)
+int tcf_act_dump_stats(struct sk_buff *skb, struct list_head *actions)
 {
 #ifdef CONFIG_NET_CLS_ACT
-	struct tc_action *a = tcf_exts_first_act(exts);
+	struct tc_action *a = tcf_act_first_act(actions);
 	if (tcf_action_copy_stats(skb, a, 1) < 0)
 		return -1;
 #endif
 	return 0;
 }
-EXPORT_SYMBOL(tcf_exts_dump_stats);
+EXPORT_SYMBOL(tcf_act_dump_stats);
 
 static int __init tc_filter_init(void)
 {
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index cd61280..fd856f7 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -29,7 +29,7 @@ struct basic_head {
 
 struct basic_filter {
 	u32			handle;
-	struct tcf_exts		exts;
+	struct list_head	actions;
 	struct tcf_ematch_tree	ematches;
 	struct tcf_result	res;
 	struct tcf_proto	*tp;
@@ -48,7 +48,7 @@ static int basic_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 		if (!tcf_em_tree_match(skb, &f->ematches, NULL))
 			continue;
 		*res = f->res;
-		r = tcf_exts_exec(skb, &f->exts, res);
+		r = tcf_act_exec(skb, &f->actions, res);
 		if (r < 0)
 			continue;
 		return r;
@@ -92,7 +92,7 @@ static void basic_delete_filter(struct rcu_head *head)
 {
 	struct basic_filter *f = container_of(head, struct basic_filter, rcu);
 
-	tcf_exts_destroy(&f->exts);
+	tcf_act_destroy(&f->actions);
 	tcf_em_tree_destroy(&f->ematches);
 	kfree(f);
 }
@@ -138,11 +138,10 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp,
 			   struct nlattr *est, bool ovr)
 {
 	int err;
-	struct tcf_exts e;
 	struct tcf_ematch_tree t;
+	struct list_head actions;
 
-	tcf_exts_init(&e, TCA_BASIC_ACT, TCA_BASIC_POLICE);
-	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
+	err = tcf_act_validate(net, tp, tb, est, &actions, ovr);
 	if (err < 0)
 		return err;
 
@@ -155,13 +154,13 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp,
 		tcf_bind_filter(tp, &f->res, base);
 	}
 
-	tcf_exts_change(tp, &f->exts, &e);
+	tcf_act_change(tp, &f->actions, &actions);
 	tcf_em_tree_change(tp, &f->ematches, &t);
 	f->tp = tp;
 
 	return 0;
 errout:
-	tcf_exts_destroy(&e);
+	tcf_act_destroy(&actions);
 	return err;
 }
 
@@ -193,7 +192,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb,
 	if (fnew == NULL)
 		goto errout;
 
-	tcf_exts_init(&fnew->exts, TCA_BASIC_ACT, TCA_BASIC_POLICE);
+	INIT_LIST_HEAD(&fnew->actions);
 	err = -EINVAL;
 	if (handle) {
 		fnew->handle = handle;
@@ -271,13 +270,13 @@ static int basic_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 	    nla_put_u32(skb, TCA_BASIC_CLASSID, f->res.classid))
 		goto nla_put_failure;
 
-	if (tcf_exts_dump(skb, &f->exts) < 0 ||
+	if (tcf_act_dump(skb, tp, &f->actions) < 0 ||
 	    tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0)
 		goto nla_put_failure;
 
 	nla_nest_end(skb, nest);
 
-	if (tcf_exts_dump_stats(skb, &f->exts) < 0)
+	if (tcf_act_dump_stats(skb, &f->actions) < 0)
 		goto nla_put_failure;
 
 	return skb->len;
@@ -289,6 +288,8 @@ static int basic_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 
 static struct tcf_proto_ops cls_basic_ops __read_mostly = {
 	.kind		=	"basic",
+	.police		=	TCA_BASIC_POLICE,
+	.action		=	TCA_BASIC_ACT,
 	.classify	=	basic_classify,
 	.init		=	basic_init,
 	.destroy	=	basic_destroy,
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index eed49d1..df0efc4 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -33,7 +33,7 @@ struct cls_bpf_head {
 struct cls_bpf_prog {
 	struct bpf_prog *filter;
 	struct sock_filter *bpf_ops;
-	struct tcf_exts exts;
+	struct list_head actions;
 	struct tcf_result res;
 	struct list_head link;
 	u32 handle;
@@ -66,7 +66,7 @@ static int cls_bpf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 		if (filter_res != -1)
 			res->classid = filter_res;
 
-		ret = tcf_exts_exec(skb, &prog->exts, res);
+		ret = tcf_act_exec(skb, &prog->actions, res);
 		if (ret < 0)
 			continue;
 
@@ -92,8 +92,7 @@ static int cls_bpf_init(struct tcf_proto *tp)
 
 static void cls_bpf_delete_prog(struct tcf_proto *tp, struct cls_bpf_prog *prog)
 {
-	tcf_exts_destroy(&prog->exts);
-
+	tcf_act_destroy(&prog->actions);
 	bpf_prog_destroy(prog->filter);
 
 	kfree(prog->bpf_ops);
@@ -168,7 +167,7 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
 				   struct nlattr *est, bool ovr)
 {
 	struct sock_filter *bpf_ops;
-	struct tcf_exts exts;
+	struct list_head actions;
 	struct sock_fprog_kern tmp;
 	struct bpf_prog *fp;
 	u16 bpf_size, bpf_len;
@@ -178,8 +177,7 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
 	if (!tb[TCA_BPF_OPS_LEN] || !tb[TCA_BPF_OPS] || !tb[TCA_BPF_CLASSID])
 		return -EINVAL;
 
-	tcf_exts_init(&exts, TCA_BPF_ACT, TCA_BPF_POLICE);
-	ret = tcf_exts_validate(net, tp, tb, est, &exts, ovr);
+	ret = tcf_act_validate(net, tp, tb, est, &actions, ovr);
 	if (ret < 0)
 		return ret;
 
@@ -212,13 +210,13 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
 	prog->res.classid = classid;
 
 	tcf_bind_filter(tp, &prog->res, base);
-	tcf_exts_change(tp, &prog->exts, &exts);
+	tcf_act_change(tp, &prog->actions, &actions);
 
 	return 0;
 errout_free:
 	kfree(bpf_ops);
 errout:
-	tcf_exts_destroy(&exts);
+	tcf_act_destroy(&actions);
 	return ret;
 }
 
@@ -259,7 +257,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
 	if (!prog)
 		return -ENOBUFS;
 
-	tcf_exts_init(&prog->exts, TCA_BPF_ACT, TCA_BPF_POLICE);
+	INIT_LIST_HEAD(&prog->actions);
 
 	if (oldprog) {
 		if (handle && oldprog->handle != handle) {
@@ -324,12 +322,12 @@ static int cls_bpf_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 
 	memcpy(nla_data(nla), prog->bpf_ops, nla_len(nla));
 
-	if (tcf_exts_dump(skb, &prog->exts) < 0)
+	if (tcf_act_dump(skb, tp, &prog->actions) < 0)
 		goto nla_put_failure;
 
 	nla_nest_end(skb, nest);
 
-	if (tcf_exts_dump_stats(skb, &prog->exts) < 0)
+	if (tcf_act_dump_stats(skb, &prog->actions) < 0)
 		goto nla_put_failure;
 
 	return skb->len;
@@ -358,6 +356,8 @@ static void cls_bpf_walk(struct tcf_proto *tp, struct tcf_walker *arg)
 
 static struct tcf_proto_ops cls_bpf_ops __read_mostly = {
 	.kind		=	"bpf",
+	.action		=	TCA_BPF_ACT,
+	.police		=	TCA_BPF_POLICE,
 	.owner		=	THIS_MODULE,
 	.classify	=	cls_bpf_classify,
 	.init		=	cls_bpf_init,
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index d61a801..5a50670 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -20,7 +20,7 @@
 
 struct cls_cgroup_head {
 	u32			handle;
-	struct tcf_exts		exts;
+	struct list_head	actions;
 	struct tcf_ematch_tree	ematches;
 	struct tcf_proto	*tp;
 	struct rcu_head		rcu;
@@ -59,7 +59,7 @@ static int cls_cgroup_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 
 	res->classid = classid;
 	res->class = 0;
-	return tcf_exts_exec(skb, &head->exts, res);
+	return tcf_act_exec(skb, &head->actions, res);
 }
 
 static unsigned long cls_cgroup_get(struct tcf_proto *tp, u32 handle)
@@ -86,7 +86,7 @@ static void cls_cgroup_destroy_rcu(struct rcu_head *root)
 						    struct cls_cgroup_head,
 						    rcu);
 
-	tcf_exts_destroy(&head->exts);
+	tcf_act_destroy(&head->actions);
 	tcf_em_tree_destroy(&head->ematches);
 	kfree(head);
 }
@@ -100,7 +100,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 	struct cls_cgroup_head *head = rtnl_dereference(tp->root);
 	struct cls_cgroup_head *new;
 	struct tcf_ematch_tree t;
-	struct tcf_exts e;
+	struct list_head actions;
 	int err;
 
 	if (!tca[TCA_OPTIONS])
@@ -116,7 +116,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 	if (!new)
 		return -ENOBUFS;
 
-	tcf_exts_init(&new->exts, TCA_CGROUP_ACT, TCA_CGROUP_POLICE);
+	INIT_LIST_HEAD(&new->actions);
 	if (head)
 		new->handle = head->handle;
 	else
@@ -128,18 +128,17 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 	if (err < 0)
 		goto errout;
 
-	tcf_exts_init(&e, TCA_CGROUP_ACT, TCA_CGROUP_POLICE);
-	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
+	err = tcf_act_validate(net, tp, tb, tca[TCA_RATE], &actions, ovr);
 	if (err < 0)
 		goto errout;
 
 	err = tcf_em_tree_validate(tp, tb[TCA_CGROUP_EMATCHES], &t);
 	if (err < 0) {
-		tcf_exts_destroy(&e);
+		tcf_act_destroy(&actions);
 		goto errout;
 	}
 
-	tcf_exts_change(tp, &new->exts, &e);
+	tcf_act_change(tp, &new->actions, &actions);
 	tcf_em_tree_change(tp, &new->ematches, &t);
 
 	rcu_assign_pointer(tp->root, new);
@@ -194,13 +193,13 @@ static int cls_cgroup_dump(struct net *net, struct tcf_proto *tp, unsigned long
 	if (nest == NULL)
 		goto nla_put_failure;
 
-	if (tcf_exts_dump(skb, &head->exts) < 0 ||
+	if (tcf_act_dump(skb, tp, &head->actions) < 0 ||
 	    tcf_em_tree_dump(skb, &head->ematches, TCA_CGROUP_EMATCHES) < 0)
 		goto nla_put_failure;
 
 	nla_nest_end(skb, nest);
 
-	if (tcf_exts_dump_stats(skb, &head->exts) < 0)
+	if (tcf_act_dump_stats(skb, &head->actions) < 0)
 		goto nla_put_failure;
 
 	return skb->len;
@@ -212,6 +211,8 @@ static int cls_cgroup_dump(struct net *net, struct tcf_proto *tp, unsigned long
 
 static struct tcf_proto_ops cls_cgroup_ops __read_mostly = {
 	.kind		=	"cgroup",
+	.action		=	TCA_CGROUP_ACT,
+	.police		=	TCA_CGROUP_POLICE,
 	.init		=	cls_cgroup_init,
 	.change		=	cls_cgroup_change,
 	.classify	=	cls_cgroup_classify,
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 4ac515f..ae9a6e5 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -39,7 +39,7 @@ struct flow_head {
 
 struct flow_filter {
 	struct list_head	list;
-	struct tcf_exts		exts;
+	struct list_head	actions;
 	struct tcf_ematch_tree	ematches;
 	struct tcf_proto	*tp;
 	struct timer_list	perturb_timer;
@@ -317,7 +317,7 @@ static int flow_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 		res->class   = 0;
 		res->classid = TC_H_MAKE(f->baseclass, f->baseclass + classid);
 
-		r = tcf_exts_exec(skb, &f->exts, res);
+		r = tcf_act_exec(skb, &f->actions, res);
 		if (r < 0)
 			continue;
 		return r;
@@ -354,7 +354,7 @@ static void flow_destroy_filter(struct rcu_head *head)
 	struct flow_filter *f = container_of(head, struct flow_filter, rcu);
 
 	del_timer_sync(&f->perturb_timer);
-	tcf_exts_destroy(&f->exts);
+	tcf_act_destroy(&f->actions);
 	tcf_em_tree_destroy(&f->ematches);
 	kfree(f);
 }
@@ -368,7 +368,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 	struct flow_filter *fold, *fnew;
 	struct nlattr *opt = tca[TCA_OPTIONS];
 	struct nlattr *tb[TCA_FLOW_MAX + 1];
-	struct tcf_exts e;
+	struct list_head actions;
 	struct tcf_ematch_tree t;
 	unsigned int nkeys = 0;
 	unsigned int perturb_period = 0;
@@ -405,8 +405,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 			return -EOPNOTSUPP;
 	}
 
-	tcf_exts_init(&e, TCA_FLOW_ACT, TCA_FLOW_POLICE);
-	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
+	err = tcf_act_validate(net, tp, tb, tca[TCA_RATE], &actions, ovr);
 	if (err < 0)
 		return err;
 
@@ -483,14 +482,14 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 		fnew->mask  = ~0U;
 		fnew->tp = tp;
 		get_random_bytes(&fnew->hashrnd, 4);
-		tcf_exts_init(&fnew->exts, TCA_FLOW_ACT, TCA_FLOW_POLICE);
+		INIT_LIST_HEAD(&fnew->actions);
 	}
 
 	fnew->perturb_timer.function = flow_perturbation;
 	fnew->perturb_timer.data = (unsigned long)fnew;
 	init_timer_deferrable(&fnew->perturb_timer);
 
-	tcf_exts_change(tp, &fnew->exts, &e);
+	tcf_act_change(tp, &fnew->actions, &actions);
 	tcf_em_tree_change(tp, &fnew->ematches, &t);
 
 	netif_keep_dst(qdisc_dev(tp->q));
@@ -535,7 +534,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 	tcf_em_tree_destroy(&t);
 	kfree(fnew);
 err1:
-	tcf_exts_destroy(&e);
+	tcf_act_destroy(&actions);
 	return err;
 }
 
@@ -630,7 +629,7 @@ static int flow_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 	    nla_put_u32(skb, TCA_FLOW_PERTURB, f->perturb_period / HZ))
 		goto nla_put_failure;
 
-	if (tcf_exts_dump(skb, &f->exts) < 0)
+	if (tcf_act_dump(skb, tp, &f->actions) < 0)
 		goto nla_put_failure;
 #ifdef CONFIG_NET_EMATCH
 	if (f->ematches.hdr.nmatches &&
@@ -639,7 +638,7 @@ static int flow_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 #endif
 	nla_nest_end(skb, nest);
 
-	if (tcf_exts_dump_stats(skb, &f->exts) < 0)
+	if (tcf_act_dump_stats(skb, &f->actions) < 0)
 		goto nla_put_failure;
 
 	return skb->len;
@@ -668,6 +667,8 @@ static void flow_walk(struct tcf_proto *tp, struct tcf_walker *arg)
 
 static struct tcf_proto_ops cls_flow_ops __read_mostly = {
 	.kind		= "flow",
+	.action		= TCA_FLOW_ACT,
+	.police		= TCA_FLOW_POLICE,
 	.classify	= flow_classify,
 	.init		= flow_init,
 	.destroy	= flow_destroy,
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index dbfdfd1..63d8d79 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -44,7 +44,7 @@ struct fw_filter {
 #ifdef CONFIG_NET_CLS_IND
 	int			ifindex;
 #endif /* CONFIG_NET_CLS_IND */
-	struct tcf_exts		exts;
+	struct list_head	actions;
 	struct tcf_proto	*tp;
 	struct rcu_head		rcu;
 };
@@ -75,7 +75,7 @@ static int fw_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 				if (!tcf_match_indev(skb, f->ifindex))
 					continue;
 #endif /* CONFIG_NET_CLS_IND */
-				r = tcf_exts_exec(skb, &f->exts, res);
+				r = tcf_act_exec(skb, &f->actions, res);
 				if (r < 0)
 					continue;
 
@@ -124,7 +124,7 @@ static void fw_delete_filter(struct rcu_head *head)
 {
 	struct fw_filter *f = container_of(head, struct fw_filter, rcu);
 
-	tcf_exts_destroy(&f->exts);
+	tcf_act_destroy(&f->actions);
 	kfree(f);
 }
 
@@ -185,12 +185,11 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f,
 	struct nlattr **tb, struct nlattr **tca, unsigned long base, bool ovr)
 {
 	struct fw_head *head = rtnl_dereference(tp->root);
-	struct tcf_exts e;
+	struct list_head actions;
 	u32 mask;
 	int err;
 
-	tcf_exts_init(&e, TCA_FW_ACT, TCA_FW_POLICE);
-	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
+	err = tcf_act_validate(net, tp, tb, tca[TCA_RATE], &actions, ovr);
 	if (err < 0)
 		return err;
 
@@ -219,11 +218,11 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f,
 	} else if (head->mask != 0xFFFFFFFF)
 		goto errout;
 
-	tcf_exts_change(tp, &f->exts, &e);
+	tcf_act_change(tp, &f->actions, &actions);
 
 	return 0;
 errout:
-	tcf_exts_destroy(&e);
+	tcf_act_destroy(&actions);
 	return err;
 }
 
@@ -264,7 +263,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,
 #endif /* CONFIG_NET_CLS_IND */
 		fnew->tp = f->tp;
 
-		tcf_exts_init(&fnew->exts, TCA_FW_ACT, TCA_FW_POLICE);
+		INIT_LIST_HEAD(&fnew->actions);
 
 		err = fw_change_attrs(net, tp, fnew, tb, tca, base, ovr);
 		if (err < 0) {
@@ -307,7 +306,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,
 	if (f == NULL)
 		return -ENOBUFS;
 
-	tcf_exts_init(&f->exts, TCA_FW_ACT, TCA_FW_POLICE);
+	INIT_LIST_HEAD(&f->actions);
 	f->id = handle;
 	f->tp = tp;
 
@@ -368,7 +367,7 @@ static int fw_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 
 	t->tcm_handle = f->id;
 
-	if (!f->res.classid && !tcf_exts_is_available(&f->exts))
+	if (!f->res.classid && !tcf_act_is_available(&f->actions))
 		return skb->len;
 
 	nest = nla_nest_start(skb, TCA_OPTIONS);
@@ -390,12 +389,12 @@ static int fw_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 	    nla_put_u32(skb, TCA_FW_MASK, head->mask))
 		goto nla_put_failure;
 
-	if (tcf_exts_dump(skb, &f->exts) < 0)
+	if (tcf_act_dump(skb, tp, &f->actions) < 0)
 		goto nla_put_failure;
 
 	nla_nest_end(skb, nest);
 
-	if (tcf_exts_dump_stats(skb, &f->exts) < 0)
+	if (tcf_act_dump_stats(skb, &f->actions) < 0)
 		goto nla_put_failure;
 
 	return skb->len;
@@ -407,6 +406,8 @@ static int fw_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 
 static struct tcf_proto_ops cls_fw_ops __read_mostly = {
 	.kind		=	"fw",
+	.action		=	TCA_FW_ACT,
+	.police		=	TCA_FW_POLICE,
 	.classify	=	fw_classify,
 	.init		=	fw_init,
 	.destroy	=	fw_destroy,
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 109a329..8879658 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -53,7 +53,7 @@ struct route4_filter {
 	int			iif;
 
 	struct tcf_result	res;
-	struct tcf_exts		exts;
+	struct list_head	actions;
 	u32			handle;
 	struct route4_bucket	*bkt;
 	struct tcf_proto	*tp;
@@ -113,8 +113,8 @@ static inline int route4_hash_wild(void)
 #define ROUTE4_APPLY_RESULT()					\
 {								\
 	*res = f->res;						\
-	if (tcf_exts_is_available(&f->exts)) {			\
-		int r = tcf_exts_exec(skb, &f->exts, res);	\
+	if (tcf_act_is_available(&f->actions)) {		\
+		int r = tcf_act_exec(skb, &f->actions, res);	\
 		if (r < 0) {					\
 			dont_cache = 1;				\
 			continue;				\
@@ -270,7 +270,7 @@ route4_delete_filter(struct rcu_head *head)
 {
 	struct route4_filter *f = container_of(head, struct route4_filter, rcu);
 
-	tcf_exts_destroy(&f->exts);
+	tcf_act_destroy(&f->actions);
 	kfree(f);
 }
 
@@ -377,10 +377,9 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
 	struct route4_filter *fp;
 	unsigned int h1;
 	struct route4_bucket *b;
-	struct tcf_exts e;
+	struct list_head actions;
 
-	tcf_exts_init(&e, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE);
-	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
+	err = tcf_act_validate(net, tp, tb, est, &actions, ovr);
 	if (err < 0)
 		return err;
 
@@ -452,11 +451,11 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
 		tcf_bind_filter(tp, &f->res, base);
 	}
 
-	tcf_exts_change(tp, &f->exts, &e);
+	tcf_act_change(tp, &f->actions, &actions);
 
 	return 0;
 errout:
-	tcf_exts_destroy(&e);
+	tcf_act_destroy(&actions);
 	return err;
 }
 
@@ -499,7 +498,7 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
 	if (!f)
 		goto errout;
 
-	tcf_exts_init(&f->exts, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE);
+	INIT_LIST_HEAD(&f->actions);
 	if (fold) {
 		f->id = fold->id;
 		f->iif = fold->iif;
@@ -628,12 +627,12 @@ static int route4_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 	    nla_put_u32(skb, TCA_ROUTE4_CLASSID, f->res.classid))
 		goto nla_put_failure;
 
-	if (tcf_exts_dump(skb, &f->exts) < 0)
+	if (tcf_act_dump(skb, tp, &f->actions) < 0)
 		goto nla_put_failure;
 
 	nla_nest_end(skb, nest);
 
-	if (tcf_exts_dump_stats(skb, &f->exts) < 0)
+	if (tcf_act_dump_stats(skb, &f->actions) < 0)
 		goto nla_put_failure;
 
 	return skb->len;
@@ -645,6 +644,8 @@ static int route4_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 
 static struct tcf_proto_ops cls_route4_ops __read_mostly = {
 	.kind		=	"route",
+	.action		=	TCA_ROUTE4_ACT,
+	.police		=	TCA_ROUTE4_POLICE,
 	.classify	=	route4_classify,
 	.init		=	route4_init,
 	.destroy	=	route4_destroy,
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 6bb55f2..64e5b31 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -93,7 +93,7 @@ struct rsvp_filter {
 	u8				tunnelhdr;
 
 	struct tcf_result		res;
-	struct tcf_exts			exts;
+	struct list_head		actions;
 
 	u32				handle;
 	struct rsvp_session		*sess;
@@ -121,7 +121,7 @@ static inline unsigned int hash_src(__be32 *src)
 
 #define RSVP_APPLY_RESULT()				\
 {							\
-	int r = tcf_exts_exec(skb, &f->exts, res);	\
+	int r = tcf_act_exec(skb, &f->actions, res);	\
 	if (r < 0)					\
 		continue;				\
 	else if (r > 0)					\
@@ -291,7 +291,7 @@ static void
 rsvp_delete_filter(struct tcf_proto *tp, struct rsvp_filter *f)
 {
 	tcf_unbind_filter(tp, &f->res);
-	tcf_exts_destroy(&f->exts);
+	tcf_act_destroy(&f->actions);
 	kfree_rcu(f, rcu);
 }
 
@@ -461,7 +461,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb,
 	struct tc_rsvp_pinfo *pinfo = NULL;
 	struct nlattr *opt = tca[TCA_OPTIONS];
 	struct nlattr *tb[TCA_RSVP_MAX + 1];
-	struct tcf_exts e;
+	struct list_head actions;
 	unsigned int h1, h2;
 	__be32 *dst;
 	int err;
@@ -473,8 +473,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb,
 	if (err < 0)
 		return err;
 
-	tcf_exts_init(&e, TCA_RSVP_ACT, TCA_RSVP_POLICE);
-	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
+	err = tcf_act_validate(net, tp, tb, tca[TCA_RATE], &actions, ovr);
 	if (err < 0)
 		return err;
 
@@ -492,14 +491,14 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb,
 			goto errout2;
 		}
 
-		tcf_exts_init(&n->exts, TCA_RSVP_ACT, TCA_RSVP_POLICE);
+		INIT_LIST_HEAD(&n->actions);
 
 		if (tb[TCA_RSVP_CLASSID]) {
 			n->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID]);
 			tcf_bind_filter(tp, &n->res, base);
 		}
 
-		tcf_exts_change(tp, &n->exts, &e);
+		tcf_act_change(tp, &n->actions, &actions);
 		rsvp_replace(tp, n, handle);
 		return 0;
 	}
@@ -516,7 +515,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb,
 	if (f == NULL)
 		goto errout2;
 
-	tcf_exts_init(&f->exts, TCA_RSVP_ACT, TCA_RSVP_POLICE);
+	INIT_LIST_HEAD(&f->actions);
 	h2 = 16;
 	if (tb[TCA_RSVP_SRC]) {
 		memcpy(f->src, nla_data(tb[TCA_RSVP_SRC]), sizeof(f->src));
@@ -570,7 +569,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb,
 			if (f->tunnelhdr == 0)
 				tcf_bind_filter(tp, &f->res, base);
 
-			tcf_exts_change(tp, &f->exts, &e);
+			tcf_act_change(tp, &f->actions, &actions);
 
 			fp = &s->ht[h2];
 			for (nfp = rtnl_dereference(*fp); nfp;
@@ -615,7 +614,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb,
 errout:
 	kfree(f);
 errout2:
-	tcf_exts_destroy(&e);
+	tcf_act_destroy(&actions);
 	return err;
 }
 
@@ -688,12 +687,12 @@ static int rsvp_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 	    nla_put(skb, TCA_RSVP_SRC, sizeof(f->src), f->src))
 		goto nla_put_failure;
 
-	if (tcf_exts_dump(skb, &f->exts) < 0)
+	if (tcf_act_dump(skb, tp, &f->actions) < 0)
 		goto nla_put_failure;
 
 	nla_nest_end(skb, nest);
 
-	if (tcf_exts_dump_stats(skb, &f->exts) < 0)
+	if (tcf_act_dump_stats(skb, &f->actions) < 0)
 		goto nla_put_failure;
 	return skb->len;
 
@@ -704,6 +703,8 @@ static int rsvp_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 
 static struct tcf_proto_ops RSVP_OPS __read_mostly = {
 	.kind		=	RSVP_ID,
+	.action		=	TCA_RSVP_ACT,
+	.police		=	TCA_RSVP_POLICE,
 	.classify	=	rsvp_classify,
 	.init		=	rsvp_init,
 	.destroy	=	rsvp_destroy,
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 30f10fb..c584195 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -25,7 +25,7 @@
 
 
 struct tcindex_filter_result {
-	struct tcf_exts		exts;
+	struct list_head	actions;
 	struct tcf_result	res;
 };
 
@@ -52,7 +52,7 @@ struct tcindex_data {
 static inline int
 tcindex_filter_is_set(struct tcindex_filter_result *r)
 {
-	return tcf_exts_is_predicative(&r->exts) || r->res.classid;
+	return tcf_act_is_predicative(&r->actions) || r->res.classid;
 }
 
 static struct tcindex_filter_result *
@@ -100,7 +100,7 @@ static int tcindex_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 	*res = f->res;
 	pr_debug("map 0x%x\n", res->classid);
 
-	return tcf_exts_exec(skb, &f->exts, res);
+	return tcf_act_exec(skb, &f->actions, res);
 }
 
 
@@ -169,7 +169,7 @@ tcindex_delete(struct tcf_proto *tp, unsigned long arg)
 		rcu_assign_pointer(*walk, rtnl_dereference(f->next));
 	}
 	tcf_unbind_filter(tp, &r->res);
-	tcf_exts_destroy(&r->exts);
+	tcf_act_destroy(&r->actions);
 	if (f)
 		kfree_rcu(f, rcu);
 	return 0;
@@ -208,7 +208,7 @@ static const struct nla_policy tcindex_policy[TCA_TCINDEX_MAX + 1] = {
 static void tcindex_filter_result_init(struct tcindex_filter_result *r)
 {
 	memset(r, 0, sizeof(*r));
-	tcf_exts_init(&r->exts, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
+	INIT_LIST_HEAD(&r->actions);
 }
 
 static void __tcindex_partial_destroy(struct rcu_head *head)
@@ -230,10 +230,9 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 	struct tcindex_filter_result cr;
 	struct tcindex_data *cp, *oldp;
 	struct tcindex_filter *f = NULL; /* make gcc behave */
-	struct tcf_exts e;
+	struct list_head actions;
 
-	tcf_exts_init(&e, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
-	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
+	err = tcf_act_validate(net, tp, tb, est, &actions, ovr);
 	if (err < 0)
 		return err;
 
@@ -261,8 +260,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 		if (!cp->perfect)
 			goto errout;
 		for (i = 0; i < cp->hash; i++)
-			tcf_exts_init(&cp->perfect[i].exts,
-				      TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
+			INIT_LIST_HEAD(&cp->perfect[i].actions);
 		balloc = 1;
 	}
 	cp->h = p->h;
@@ -330,9 +328,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 			if (!cp->perfect)
 				goto errout_alloc;
 			for (i = 0; i < cp->hash; i++)
-				tcf_exts_init(&cp->perfect[i].exts,
-					      TCA_TCINDEX_ACT,
-					      TCA_TCINDEX_POLICE);
+				INIT_LIST_HEAD(&cp->perfect[i].actions);
 			balloc = 1;
 		} else {
 			struct tcindex_filter __rcu **hash;
@@ -369,9 +365,9 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 	}
 
 	if (old_r)
-		tcf_exts_change(tp, &r->exts, &e);
+		tcf_act_change(tp, &r->actions, &actions);
 	else
-		tcf_exts_change(tp, &cr.exts, &e);
+		tcf_act_change(tp, &cr.actions, &actions);
 
 	if (old_r && old_r != r)
 		tcindex_filter_result_init(old_r);
@@ -384,7 +380,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 		struct tcindex_filter *nfp;
 		struct tcindex_filter __rcu **fp;
 
-		tcf_exts_change(tp, &f->result.exts, &r->exts);
+		tcf_act_change(tp, &f->result.actions, &r->actions);
 
 		fp = cp->h + (handle % cp->hash);
 		for (nfp = rtnl_dereference(*fp);
@@ -406,7 +402,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 		kfree(cp->h);
 errout:
 	kfree(cp);
-	tcf_exts_destroy(&e);
+	tcf_act_destroy(&actions);
 	return err;
 }
 
@@ -539,11 +535,11 @@ static int tcindex_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 		    nla_put_u32(skb, TCA_TCINDEX_CLASSID, r->res.classid))
 			goto nla_put_failure;
 
-		if (tcf_exts_dump(skb, &r->exts) < 0)
+		if (tcf_act_dump(skb, tp, &r->actions) < 0)
 			goto nla_put_failure;
 		nla_nest_end(skb, nest);
 
-		if (tcf_exts_dump_stats(skb, &r->exts) < 0)
+		if (tcf_act_dump_stats(skb, &r->actions) < 0)
 			goto nla_put_failure;
 	}
 
@@ -556,6 +552,8 @@ static int tcindex_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 
 static struct tcf_proto_ops cls_tcindex_ops __read_mostly = {
 	.kind		=	"tcindex",
+	.action		=	TCA_TCINDEX_ACT,
+	.police		=	TCA_TCINDEX_POLICE,
 	.classify	=	tcindex_classify,
 	.init		=	tcindex_init,
 	.destroy	=	tcindex_destroy,
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 0472909..973e7f3 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -48,7 +48,7 @@ struct tc_u_knode {
 	struct tc_u_knode __rcu	*next;
 	u32			handle;
 	struct tc_u_hnode __rcu	*ht_up;
-	struct tcf_exts		exts;
+	struct list_head	actions;
 #ifdef CONFIG_NET_CLS_IND
 	int			ifindex;
 #endif
@@ -173,7 +173,7 @@ static int u32_classify(struct sk_buff *skb, const struct tcf_proto *tp, struct
 #ifdef CONFIG_CLS_U32_PERF
 				__this_cpu_inc(n->pf->rhit);
 #endif
-				r = tcf_exts_exec(skb, &n->exts, res);
+				r = tcf_act_exec(skb, &n->actions, res);
 				if (r < 0) {
 					n = rcu_dereference_bh(n->next);
 					goto next_knode;
@@ -358,7 +358,7 @@ static int u32_destroy_key(struct tcf_proto *tp,
 			   struct tc_u_knode *n,
 			   bool free_pf)
 {
-	tcf_exts_destroy(&n->exts);
+	tcf_act_destroy(&n->actions);
 	if (n->ht_down)
 		n->ht_down->refcnt--;
 #ifdef CONFIG_CLS_U32_PERF
@@ -560,10 +560,9 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp,
 			 struct nlattr *est, bool ovr)
 {
 	int err;
-	struct tcf_exts e;
+	struct list_head actions;
 
-	tcf_exts_init(&e, TCA_U32_ACT, TCA_U32_POLICE);
-	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
+	err = tcf_act_validate(net, tp, tb, est, &actions, ovr);
 	if (err < 0)
 		return err;
 
@@ -603,11 +602,11 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp,
 		n->ifindex = ret;
 	}
 #endif
-	tcf_exts_change(tp, &n->exts, &e);
+	tcf_act_change(tp, &n->actions, &actions);
 
 	return 0;
 errout:
-	tcf_exts_destroy(&e);
+	tcf_act_destroy(&actions);
 	return err;
 }
 
@@ -681,8 +680,7 @@ static struct tc_u_knode *u32_init_knode(struct tcf_proto *tp,
 #endif
 	new->tp = tp;
 	memcpy(&new->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key));
-
-	tcf_exts_init(&new->exts, TCA_U32_ACT, TCA_U32_POLICE);
+	INIT_LIST_HEAD(&new->actions);
 
 	return new;
 }
@@ -810,7 +808,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
 	RCU_INIT_POINTER(n->ht_up, ht);
 	n->handle = handle;
 	n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0;
-	tcf_exts_init(&n->exts, TCA_U32_ACT, TCA_U32_POLICE);
+	INIT_LIST_HEAD(&n->actions);
 	n->tp = tp;
 
 #ifdef CONFIG_CLS_U32_MARK
@@ -965,7 +963,7 @@ static int u32_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 		}
 #endif
 
-		if (tcf_exts_dump(skb, &n->exts) < 0)
+		if (tcf_act_dump(skb, tp, &n->actions) < 0)
 			goto nla_put_failure;
 
 #ifdef CONFIG_NET_CLS_IND
@@ -1006,7 +1004,7 @@ static int u32_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 	nla_nest_end(skb, nest);
 
 	if (TC_U32_KEY(n->handle))
-		if (tcf_exts_dump_stats(skb, &n->exts) < 0)
+		if (tcf_act_dump_stats(skb, &n->actions) < 0)
 			goto nla_put_failure;
 	return skb->len;
 
@@ -1017,6 +1015,8 @@ static int u32_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 
 static struct tcf_proto_ops cls_u32_ops __read_mostly = {
 	.kind		=	"u32",
+	.action		=	TCA_U32_ACT,
+	.police		=	TCA_U32_POLICE,
 	.classify	=	u32_classify,
 	.init		=	u32_init,
 	.destroy	=	u32_destroy,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 02/13] net_sched: introduce qdisc_peek() helper function
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
  2014-11-04 17:56 ` [PATCH 01/13] net_sched: refactor out tcf_exts Cong Wang
@ 2014-11-04 17:56 ` Cong Wang
  2014-11-04 18:45   ` Stephen Hemminger
  2014-11-04 17:56 ` [PATCH 03/13] net_sched: rename ->gso_skb to ->dequeued_skb Cong Wang
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang

Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 include/net/pkt_sched.h   |  1 -
 include/net/sch_generic.h | 19 +++++++++++++++++++
 net/sched/sch_api.c       | 10 ----------
 net/sched/sch_atm.c       |  4 ++--
 net/sched/sch_drr.c       |  6 ++----
 net/sched/sch_dsmark.c    |  2 +-
 net/sched/sch_hfsc.c      |  8 +++-----
 net/sched/sch_htb.c       |  2 +-
 net/sched/sch_multiq.c    |  2 +-
 net/sched/sch_prio.c      |  2 +-
 net/sched/sch_qfq.c       | 10 ++++------
 net/sched/sch_red.c       |  2 +-
 net/sched/sch_sfb.c       |  2 +-
 net/sched/sch_tbf.c       |  2 +-
 14 files changed, 37 insertions(+), 35 deletions(-)

diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 27a3383..f224b7c 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -96,7 +96,6 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
 					struct nlattr *tab);
 void qdisc_put_rtab(struct qdisc_rate_table *tab);
 void qdisc_put_stab(struct qdisc_size_table *tab);
-void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc);
 int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
 		    struct net_device *dev, struct netdev_queue *txq,
 		    spinlock_t *root_lock, bool validate);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 3d9fac9..a690e6f 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -518,6 +518,25 @@ static inline bool qdisc_is_percpu_stats(const struct Qdisc *q)
 	return q->flags & TCQ_F_CPUSTATS;
 }
 
+static inline void qdisc_warn_nonwc(void *func, struct Qdisc *qdisc)
+{
+	if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
+		pr_warn("%pf: %s qdisc %X: is non-work-conserving?\n",
+			func, qdisc->ops->id, qdisc->handle >> 16);
+		qdisc->flags |= TCQ_F_WARN_NONWC;
+	}
+}
+
+static inline struct sk_buff *qdisc_peek(struct Qdisc *sch, bool warn)
+{
+	struct sk_buff *skb;
+
+	skb = sch->ops->peek(sch);
+	if (!skb && warn)
+		qdisc_warn_nonwc(__builtin_return_address(0), sch);
+	return skb;
+}
+
 static inline void bstats_update(struct gnet_stats_basic_packed *bstats,
 				 const struct sk_buff *skb)
 {
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 76f402e..2276b15 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -563,16 +563,6 @@ void __qdisc_calculate_pkt_len(struct sk_buff *skb, const struct qdisc_size_tabl
 }
 EXPORT_SYMBOL(__qdisc_calculate_pkt_len);
 
-void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc)
-{
-	if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
-		pr_warn("%s: %s qdisc %X: is non-work-conserving?\n",
-			txt, qdisc->ops->id, qdisc->handle >> 16);
-		qdisc->flags |= TCQ_F_WARN_NONWC;
-	}
-}
-EXPORT_SYMBOL(qdisc_warn_nonwc);
-
 static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
 {
 	struct qdisc_watchdog *wd = container_of(timer, struct qdisc_watchdog,
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index e3e2cc5..1d3fb22 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -462,7 +462,7 @@ static void sch_atm_dequeue(unsigned long data)
 		 * If traffic is properly shaped, this won't generate nasty
 		 * little bursts. Otherwise, it may ... (but that's okay)
 		 */
-		while ((skb = flow->q->ops->peek(flow->q))) {
+		while ((skb = qdisc_peek(flow->q, false))) {
 			if (!atm_may_send(flow->vcc, skb->truesize))
 				break;
 
@@ -516,7 +516,7 @@ static struct sk_buff *atm_tc_peek(struct Qdisc *sch)
 
 	pr_debug("atm_tc_peek(sch %p,[qdisc %p])\n", sch, p);
 
-	return p->link.q->ops->peek(p->link.q);
+	return qdisc_peek(p->link.q ,false);
 }
 
 static unsigned int atm_tc_drop(struct Qdisc *sch)
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 3387060..a367fea 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -393,11 +393,9 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch)
 		goto out;
 	while (1) {
 		cl = list_first_entry(&q->active, struct drr_class, alist);
-		skb = cl->qdisc->ops->peek(cl->qdisc);
-		if (skb == NULL) {
-			qdisc_warn_nonwc(__func__, cl->qdisc);
+		skb = qdisc_peek(cl->qdisc, true);
+		if (skb == NULL)
 			goto out;
-		}
 
 		len = qdisc_pkt_len(skb);
 		if (len <= cl->deficit) {
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 227114f..7bdf7e0 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -319,7 +319,7 @@ static struct sk_buff *dsmark_peek(struct Qdisc *sch)
 
 	pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p);
 
-	return p->q->ops->peek(p->q);
+	return qdisc_peek(p->q, false);
 }
 
 static unsigned int dsmark_drop(struct Qdisc *sch)
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index e6c7416..7086ead 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -881,11 +881,9 @@ qdisc_peek_len(struct Qdisc *sch)
 	struct sk_buff *skb;
 	unsigned int len;
 
-	skb = sch->ops->peek(sch);
-	if (skb == NULL) {
-		qdisc_warn_nonwc("qdisc_peek_len", sch);
+	skb = qdisc_peek(sch, true);
+	if (skb == NULL)
 		return 0;
-	}
 	len = qdisc_pkt_len(skb);
 
 	return len;
@@ -1650,7 +1648,7 @@ hfsc_dequeue(struct Qdisc *sch)
 
 	skb = qdisc_dequeue_peeked(cl->qdisc);
 	if (skb == NULL) {
-		qdisc_warn_nonwc("HFSC", cl->qdisc);
+		qdisc_warn_nonwc(__builtin_return_address(0), cl->qdisc);
 		return NULL;
 	}
 
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index f1acb0f..28b6929 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -850,7 +850,7 @@ static struct sk_buff *htb_dequeue_tree(struct htb_sched *q, const int prio,
 		if (likely(skb != NULL))
 			break;
 
-		qdisc_warn_nonwc("htb", cl->un.leaf.q);
+		qdisc_warn_nonwc(__builtin_return_address(0), cl->un.leaf.q);
 		htb_next_rb_node(level ? &cl->parent->un.inner.clprio[prio].ptr:
 					 &q->hlevel[0].hprio[prio].ptr);
 		cl = htb_lookup_leaf(hprio, prio);
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 42dd218..1458aa3 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -142,7 +142,7 @@ static struct sk_buff *multiq_peek(struct Qdisc *sch)
 		if (!netif_xmit_stopped(
 		    netdev_get_tx_queue(qdisc_dev(sch), curband))) {
 			qdisc = q->queues[curband];
-			skb = qdisc->ops->peek(qdisc);
+			skb = qdisc_peek(qdisc, false);
 			if (skb)
 				return skb;
 		}
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 8e5cd34..0e06d14 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -100,7 +100,7 @@ static struct sk_buff *prio_peek(struct Qdisc *sch)
 
 	for (prio = 0; prio < q->bands; prio++) {
 		struct Qdisc *qdisc = q->queues[prio];
-		struct sk_buff *skb = qdisc->ops->peek(qdisc);
+		struct sk_buff *skb = qdisc_peek(qdisc, false);
 		if (skb)
 			return skb;
 	}
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index 3ec7e88..9c9a5f3 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -1006,7 +1006,7 @@ static void agg_dequeue(struct qfq_aggregate *agg,
 
 	if (cl->qdisc->q.qlen == 0) /* no more packets, remove from list */
 		list_del(&cl->alist);
-	else if (cl->deficit < qdisc_pkt_len(cl->qdisc->ops->peek(cl->qdisc))) {
+	else if (cl->deficit < qdisc_pkt_len(qdisc_peek(cl->qdisc, false))) {
 		cl->deficit += agg->lmax;
 		list_move_tail(&cl->alist, &agg->active);
 	}
@@ -1019,10 +1019,8 @@ static inline struct sk_buff *qfq_peek_skb(struct qfq_aggregate *agg,
 	struct sk_buff *skb;
 
 	*cl = list_first_entry(&agg->active, struct qfq_class, alist);
-	skb = (*cl)->qdisc->ops->peek((*cl)->qdisc);
-	if (skb == NULL)
-		WARN_ONCE(1, "qfq_dequeue: non-workconserving leaf\n");
-	else
+	skb = qdisc_peek((*cl)->qdisc, true);
+	if (skb != NULL)
 		*len = qdisc_pkt_len(skb);
 
 	return skb;
@@ -1260,7 +1258,7 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	agg = cl->agg;
 	/* if the queue was not empty, then done here */
 	if (cl->qdisc->q.qlen != 1) {
-		if (unlikely(skb == cl->qdisc->ops->peek(cl->qdisc)) &&
+		if (unlikely(skb == qdisc_peek(cl->qdisc, false)) &&
 		    list_first_entry(&agg->active, struct qfq_class, alist)
 		    == cl && cl->deficit < qdisc_pkt_len(skb))
 			list_move_tail(&cl->alist, &agg->active);
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 6c0534c..8fd96ae 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -131,7 +131,7 @@ static struct sk_buff *red_peek(struct Qdisc *sch)
 	struct red_sched_data *q = qdisc_priv(sch);
 	struct Qdisc *child = q->qdisc;
 
-	return child->ops->peek(child);
+	return qdisc_peek(child, false);
 }
 
 static unsigned int red_drop(struct Qdisc *sch)
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index 5819dd8..08c318e 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -447,7 +447,7 @@ static struct sk_buff *sfb_peek(struct Qdisc *sch)
 	struct sfb_sched_data *q = qdisc_priv(sch);
 	struct Qdisc *child = q->qdisc;
 
-	return child->ops->peek(child);
+	return qdisc_peek(child, false);
 }
 
 /* No sfb_drop -- impossible since the child doesn't return the dropped skb. */
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index a4afde1..1f63a71 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -231,7 +231,7 @@ static struct sk_buff *tbf_dequeue(struct Qdisc *sch)
 	struct tbf_sched_data *q = qdisc_priv(sch);
 	struct sk_buff *skb;
 
-	skb = q->qdisc->ops->peek(q->qdisc);
+	skb = qdisc_peek(q->qdisc, false);
 
 	if (skb) {
 		s64 now;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 03/13] net_sched: rename ->gso_skb to ->dequeued_skb
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
  2014-11-04 17:56 ` [PATCH 01/13] net_sched: refactor out tcf_exts Cong Wang
  2014-11-04 17:56 ` [PATCH 02/13] net_sched: introduce qdisc_peek() helper function Cong Wang
@ 2014-11-04 17:56 ` Cong Wang
  2014-11-04 17:56 ` [PATCH 04/13] net_sched: rename qdisc_drop() to qdisc_drop_skb() Cong Wang
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang

Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 include/net/sch_generic.h | 16 ++++++++--------
 net/sched/sch_generic.c   | 14 +++++++-------
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index a690e6f..6320c18 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -80,7 +80,7 @@ struct Qdisc {
 
 	struct gnet_stats_rate_est64	rate_est;
 	struct Qdisc		*next_sched;
-	struct sk_buff		*gso_skb;
+	struct sk_buff		*dequeued_skb;
 	/*
 	 * For performance sake on SMP, we put highly modified fields at the end
 	 */
@@ -671,24 +671,24 @@ static inline struct sk_buff *qdisc_peek_head(struct Qdisc *sch)
 /* generic pseudo peek method for non-work-conserving qdisc */
 static inline struct sk_buff *qdisc_peek_dequeued(struct Qdisc *sch)
 {
-	/* we can reuse ->gso_skb because peek isn't called for root qdiscs */
-	if (!sch->gso_skb) {
-		sch->gso_skb = sch->dequeue(sch);
-		if (sch->gso_skb)
+	/* we can reuse ->dequeued_skb because peek isn't called for root qdiscs */
+	if (!sch->dequeued_skb) {
+		sch->dequeued_skb = sch->dequeue(sch);
+		if (sch->dequeued_skb)
 			/* it's still part of the queue */
 			sch->q.qlen++;
 	}
 
-	return sch->gso_skb;
+	return sch->dequeued_skb;
 }
 
 /* use instead of qdisc->dequeue() for all qdiscs queried with ->peek() */
 static inline struct sk_buff *qdisc_dequeue_peeked(struct Qdisc *sch)
 {
-	struct sk_buff *skb = sch->gso_skb;
+	struct sk_buff *skb = sch->dequeued_skb;
 
 	if (skb) {
-		sch->gso_skb = NULL;
+		sch->dequeued_skb = NULL;
 		sch->q.qlen--;
 	} else {
 		skb = sch->dequeue(sch);
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 6efca30..9feeb5c 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -47,7 +47,7 @@ EXPORT_SYMBOL(default_qdisc_ops);
 
 static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
 {
-	q->gso_skb = skb;
+	q->dequeued_skb = skb;
 	q->qstats.requeues++;
 	q->q.qlen++;	/* it's still part of the queue */
 	__netif_schedule(q);
@@ -82,7 +82,7 @@ static void try_bulk_dequeue_skb(struct Qdisc *q,
 static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
 				   int *packets)
 {
-	struct sk_buff *skb = q->gso_skb;
+	struct sk_buff *skb = q->dequeued_skb;
 	const struct netdev_queue *txq = q->dev_queue;
 
 	*packets = 1;
@@ -91,7 +91,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
 		/* check the reason of requeuing without tx lock first */
 		txq = skb_get_tx_queue(txq->dev, skb);
 		if (!netif_xmit_frozen_or_stopped(txq)) {
-			q->gso_skb = NULL;
+			q->dequeued_skb = NULL;
 			q->q.qlen--;
 		} else
 			skb = NULL;
@@ -654,9 +654,9 @@ void qdisc_reset(struct Qdisc *qdisc)
 	if (ops->reset)
 		ops->reset(qdisc);
 
-	if (qdisc->gso_skb) {
-		kfree_skb_list(qdisc->gso_skb);
-		qdisc->gso_skb = NULL;
+	if (qdisc->dequeued_skb) {
+		kfree_skb_list(qdisc->dequeued_skb);
+		qdisc->dequeued_skb = NULL;
 		qdisc->q.qlen = 0;
 	}
 }
@@ -694,7 +694,7 @@ void qdisc_destroy(struct Qdisc *qdisc)
 	module_put(ops->owner);
 	dev_put(qdisc_dev(qdisc));
 
-	kfree_skb_list(qdisc->gso_skb);
+	kfree_skb_list(qdisc->dequeued_skb);
 	/*
 	 * gen_estimator est_timer() might access qdisc->q.lock,
 	 * wait a RCU grace period before freeing qdisc.
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 04/13] net_sched: rename qdisc_drop() to qdisc_drop_skb()
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
                   ` (2 preceding siblings ...)
  2014-11-04 17:56 ` [PATCH 03/13] net_sched: rename ->gso_skb to ->dequeued_skb Cong Wang
@ 2014-11-04 17:56 ` Cong Wang
  2014-11-04 17:56 ` [PATCH 05/13] net_sched: introduce qdisc_drop() helper function Cong Wang
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang

qdisc_drop() will be used by the following patch.

Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 include/net/codel.h       | 4 ++--
 include/net/sch_generic.h | 2 +-
 net/sched/sch_blackhole.c | 2 +-
 net/sched/sch_choke.c     | 8 ++++----
 net/sched/sch_codel.c     | 4 ++--
 net/sched/sch_dsmark.c    | 2 +-
 net/sched/sch_fq.c        | 4 ++--
 net/sched/sch_generic.c   | 2 +-
 net/sched/sch_gred.c      | 6 +++---
 net/sched/sch_htb.c       | 2 +-
 net/sched/sch_netem.c     | 2 +-
 net/sched/sch_pie.c       | 4 ++--
 net/sched/sch_red.c       | 2 +-
 net/sched/sch_sfb.c       | 2 +-
 net/sched/sch_sfq.c       | 6 +++---
 net/sched/sch_teql.c      | 2 +-
 16 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/include/net/codel.h b/include/net/codel.h
index aeee280..510d5da 100644
--- a/include/net/codel.h
+++ b/include/net/codel.h
@@ -297,7 +297,7 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch,
 								  vars->rec_inv_sqrt);
 					goto end;
 				}
-				qdisc_drop(skb, sch);
+				qdisc_drop_skb(skb, sch);
 				stats->drop_count++;
 				skb = dequeue_func(vars, sch);
 				if (!codel_should_drop(skb, sch,
@@ -319,7 +319,7 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch,
 		if (params->ecn && INET_ECN_set_ce(skb)) {
 			stats->ecn_mark++;
 		} else {
-			qdisc_drop(skb, sch);
+			qdisc_drop_skb(skb, sch);
 			stats->drop_count++;
 
 			skb = dequeue_func(vars, sch);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 6320c18..21df9fb 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -732,7 +732,7 @@ static inline unsigned int qdisc_queue_drop(struct Qdisc *sch)
 	return __qdisc_queue_drop(sch, &sch->q);
 }
 
-static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch)
+static inline int qdisc_drop_skb(struct sk_buff *skb, struct Qdisc *sch)
 {
 	kfree_skb(skb);
 	qdisc_qstats_drop(sch);
diff --git a/net/sched/sch_blackhole.c b/net/sched/sch_blackhole.c
index 094a874..137b5d7 100644
--- a/net/sched/sch_blackhole.c
+++ b/net/sched/sch_blackhole.c
@@ -19,7 +19,7 @@
 
 static int blackhole_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
-	qdisc_drop(skb, sch);
+	qdisc_drop_skb(skb, sch);
 	return NET_XMIT_SUCCESS;
 }
 
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c
index c009eb9..fac3db3 100644
--- a/net/sched/sch_choke.c
+++ b/net/sched/sch_choke.c
@@ -128,7 +128,7 @@ static void choke_drop_by_idx(struct Qdisc *sch, unsigned int idx)
 		choke_zap_tail_holes(q);
 
 	qdisc_qstats_backlog_dec(sch, skb);
-	qdisc_drop(skb, sch);
+	qdisc_drop_skb(skb, sch);
 	qdisc_tree_decrease_qlen(sch, 1);
 	--sch->q.qlen;
 }
@@ -337,10 +337,10 @@ static int choke_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	}
 
 	q->stats.pdrop++;
-	return qdisc_drop(skb, sch);
+	return qdisc_drop_skb(skb, sch);
 
 congestion_drop:
-	qdisc_drop(skb, sch);
+	qdisc_drop_skb(skb, sch);
 	return NET_XMIT_CN;
 
 other_drop:
@@ -462,7 +462,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt)
 				}
 				qdisc_qstats_backlog_dec(sch, skb);
 				--sch->q.qlen;
-				qdisc_drop(skb, sch);
+				qdisc_drop_skb(skb, sch);
 			}
 			qdisc_tree_decrease_qlen(sch, oqlen - sch->q.qlen);
 			q->head = 0;
diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c
index de28f8e..3ce45b8 100644
--- a/net/sched/sch_codel.c
+++ b/net/sched/sch_codel.c
@@ -101,7 +101,7 @@ static int codel_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	}
 	q = qdisc_priv(sch);
 	q->drop_overlimit++;
-	return qdisc_drop(skb, sch);
+	return qdisc_drop_skb(skb, sch);
 }
 
 static const struct nla_policy codel_policy[TCA_CODEL_MAX + 1] = {
@@ -150,7 +150,7 @@ static int codel_change(struct Qdisc *sch, struct nlattr *opt)
 		struct sk_buff *skb = __skb_dequeue(&sch->q);
 
 		qdisc_qstats_backlog_dec(sch, skb);
-		qdisc_drop(skb, sch);
+		qdisc_drop_skb(skb, sch);
 	}
 	qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen);
 
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 7bdf7e0..a450c53 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -267,7 +267,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	return NET_XMIT_SUCCESS;
 
 drop:
-	qdisc_drop(skb, sch);
+	qdisc_drop_skb(skb, sch);
 	return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
 }
 
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
index cbd7e1f..34ec70c 100644
--- a/net/sched/sch_fq.c
+++ b/net/sched/sch_fq.c
@@ -360,12 +360,12 @@ static int fq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	struct fq_flow *f;
 
 	if (unlikely(sch->q.qlen >= sch->limit))
-		return qdisc_drop(skb, sch);
+		return qdisc_drop_skb(skb, sch);
 
 	f = fq_classify(skb, q);
 	if (unlikely(f->qlen >= q->flow_plimit && f != &q->internal)) {
 		q->stat_flows_plimit++;
-		return qdisc_drop(skb, sch);
+		return qdisc_drop_skb(skb, sch);
 	}
 
 	f->qlen++;
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 9feeb5c..cd4ba53 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -489,7 +489,7 @@ static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc)
 		return __qdisc_enqueue_tail(skb, qdisc, list);
 	}
 
-	return qdisc_drop(skb, qdisc);
+	return qdisc_drop_skb(skb, qdisc);
 }
 
 static struct sk_buff *pfifo_fast_dequeue(struct Qdisc *qdisc)
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index a4ca451..60da79a 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -236,10 +236,10 @@ static int gred_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 
 	q->stats.pdrop++;
 drop:
-	return qdisc_drop(skb, sch);
+	return qdisc_drop_skb(skb, sch);
 
 congestion_drop:
-	qdisc_drop(skb, sch);
+	qdisc_drop_skb(skb, sch);
 	return NET_XMIT_CN;
 }
 
@@ -302,7 +302,7 @@ static unsigned int gred_drop(struct Qdisc *sch)
 			}
 		}
 
-		qdisc_drop(skb, sch);
+		qdisc_drop_skb(skb, sch);
 		return len;
 	}
 
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 28b6929..89d15e8 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -581,7 +581,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 			__skb_queue_tail(&q->direct_queue, skb);
 			q->direct_pkts++;
 		} else {
-			return qdisc_drop(skb, sch);
+			return qdisc_drop_skb(skb, sch);
 		}
 #ifdef CONFIG_NET_CLS_ACT
 	} else if (!cl) {
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 179f1c8..1eb917e 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -456,7 +456,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 		if (!(skb = skb_unshare(skb, GFP_ATOMIC)) ||
 		    (skb->ip_summed == CHECKSUM_PARTIAL &&
 		     skb_checksum_help(skb)))
-			return qdisc_drop(skb, sch);
+			return qdisc_drop_skb(skb, sch);
 
 		skb->data[prandom_u32() % skb_headlen(skb)] ^=
 			1<<(prandom_u32() % 8);
diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c
index b783a44..6095777 100644
--- a/net/sched/sch_pie.c
+++ b/net/sched/sch_pie.c
@@ -166,7 +166,7 @@ static int pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 
 out:
 	q->stats.dropped++;
-	return qdisc_drop(skb, sch);
+	return qdisc_drop_skb(skb, sch);
 }
 
 static const struct nla_policy pie_policy[TCA_PIE_MAX + 1] = {
@@ -233,7 +233,7 @@ static int pie_change(struct Qdisc *sch, struct nlattr *opt)
 		struct sk_buff *skb = __skb_dequeue(&sch->q);
 
 		qdisc_qstats_backlog_dec(sch, skb);
-		qdisc_drop(skb, sch);
+		qdisc_drop_skb(skb, sch);
 	}
 	qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen);
 
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 8fd96ae..c19587d 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -105,7 +105,7 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	return ret;
 
 congestion_drop:
-	qdisc_drop(skb, sch);
+	qdisc_drop_skb(skb, sch);
 	return NET_XMIT_CN;
 }
 
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index 08c318e..7eea588 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -416,7 +416,7 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	return ret;
 
 drop:
-	qdisc_drop(skb, sch);
+	qdisc_drop_skb(skb, sch);
 	return NET_XMIT_CN;
 other_drop:
 	if (ret & __NET_XMIT_BYPASS)
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index b877140..6212652 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -390,7 +390,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	if (x == SFQ_EMPTY_SLOT) {
 		x = q->dep[0].next; /* get a free slot */
 		if (x >= SFQ_MAX_FLOWS)
-			return qdisc_drop(skb, sch);
+			return qdisc_drop_skb(skb, sch);
 		q->ht[hash] = x;
 		slot = &q->slots[x];
 		slot->hash = hash;
@@ -447,14 +447,14 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	if (slot->qlen >= q->maxdepth) {
 congestion_drop:
 		if (!sfq_headdrop(q))
-			return qdisc_drop(skb, sch);
+			return qdisc_drop_skb(skb, sch);
 
 		/* We know we have at least one packet in queue */
 		head = slot_dequeue_head(slot);
 		delta = qdisc_pkt_len(head) - qdisc_pkt_len(skb);
 		sch->qstats.backlog -= delta;
 		slot->backlog -= delta;
-		qdisc_drop(head, sch);
+		qdisc_drop_skb(head, sch);
 
 		slot_queue_add(slot, skb);
 		return NET_XMIT_CN;
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 6ada423..fc13451 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -87,7 +87,7 @@ teql_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 		return NET_XMIT_SUCCESS;
 	}
 
-	return qdisc_drop(skb, sch);
+	return qdisc_drop_skb(skb, sch);
 }
 
 static struct sk_buff *
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 05/13] net_sched: introduce qdisc_drop() helper function
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
                   ` (3 preceding siblings ...)
  2014-11-04 17:56 ` [PATCH 04/13] net_sched: rename qdisc_drop() to qdisc_drop_skb() Cong Wang
@ 2014-11-04 17:56 ` Cong Wang
  2014-11-04 17:56 ` [PATCH 06/13] net_sched: move some qdisc flag into qdisc ops Cong Wang
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang

Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 include/net/sch_generic.h |  8 ++++++++
 net/sched/sch_atm.c       |  2 +-
 net/sched/sch_cbq.c       |  7 +++----
 net/sched/sch_drr.c       | 14 ++++++--------
 net/sched/sch_dsmark.c    |  5 +----
 net/sched/sch_hfsc.c      |  3 +--
 net/sched/sch_htb.c       |  3 +--
 net/sched/sch_multiq.c    | 10 ++++------
 net/sched/sch_netem.c     |  4 ++--
 net/sched/sch_prio.c      |  2 +-
 net/sched/sch_qfq.c       |  6 +-----
 net/sched/sch_red.c       |  2 +-
 net/sched/sch_tbf.c       |  2 +-
 13 files changed, 31 insertions(+), 37 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 21df9fb..119e129 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -740,6 +740,14 @@ static inline int qdisc_drop_skb(struct sk_buff *skb, struct Qdisc *sch)
 	return NET_XMIT_DROP;
 }
 
+static inline unsigned int qdisc_drop(struct Qdisc *sch)
+{
+	if (sch->ops->drop)
+		return sch->ops->drop(sch);
+	else
+		return 0;
+}
+
 static inline int qdisc_reshape_fail(struct sk_buff *skb, struct Qdisc *sch)
 {
 	qdisc_qstats_drop(sch);
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index 1d3fb22..a26e503 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -527,7 +527,7 @@ static unsigned int atm_tc_drop(struct Qdisc *sch)
 
 	pr_debug("atm_tc_drop(sch %p,[qdisc %p])\n", sch, p);
 	list_for_each_entry(flow, &p->flows, list) {
-		if (flow->q->ops->drop && (len = flow->q->ops->drop(flow->q)))
+		if ((len = qdisc_drop(flow->q)))
 			return len;
 	}
 	return 0;
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index beeb75f..ad2905a 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -542,9 +542,8 @@ static void cbq_ovl_lowprio(struct cbq_class *cl)
 
 static void cbq_ovl_drop(struct cbq_class *cl)
 {
-	if (cl->q->ops->drop)
-		if (cl->q->ops->drop(cl->q))
-			cl->qdisc->q.qlen--;
+	if (qdisc_drop(cl->q))
+		cl->qdisc->q.qlen--;
 	cl->xstats.overactions++;
 	cbq_ovl_classic(cl);
 }
@@ -1180,7 +1179,7 @@ static unsigned int cbq_drop(struct Qdisc *sch)
 
 		cl = cl_head;
 		do {
-			if (cl->q->ops->drop && (len = cl->q->ops->drop(cl->q))) {
+			if ((len = qdisc_drop(cl->q))) {
 				sch->q.qlen--;
 				if (!cl->q->q.qlen)
 					cbq_deactivate_class(cl);
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index a367fea..4007e40 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -424,14 +424,12 @@ static unsigned int drr_drop(struct Qdisc *sch)
 	unsigned int len;
 
 	list_for_each_entry(cl, &q->active, alist) {
-		if (cl->qdisc->ops->drop) {
-			len = cl->qdisc->ops->drop(cl->qdisc);
-			if (len > 0) {
-				sch->q.qlen--;
-				if (cl->qdisc->q.qlen == 0)
-					list_del(&cl->alist);
-				return len;
-			}
+		len = qdisc_drop(cl->qdisc);
+		if (len > 0) {
+			sch->q.qlen--;
+			if (cl->qdisc->q.qlen == 0)
+				list_del(&cl->alist);
+			return len;
 		}
 	}
 	return 0;
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index a450c53..0a20722 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -329,10 +329,7 @@ static unsigned int dsmark_drop(struct Qdisc *sch)
 
 	pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p);
 
-	if (p->q->ops->drop == NULL)
-		return 0;
-
-	len = p->q->ops->drop(p->q);
+	len = qdisc_drop(p->q);
 	if (len)
 		sch->q.qlen--;
 
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 7086ead..3cc44a8 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1686,8 +1686,7 @@ hfsc_drop(struct Qdisc *sch)
 	unsigned int len;
 
 	list_for_each_entry(cl, &q->droplist, dlist) {
-		if (cl->qdisc->ops->drop != NULL &&
-		    (len = cl->qdisc->ops->drop(cl->qdisc)) > 0) {
+		if ((len = qdisc_drop(cl->qdisc)) > 0) {
 			if (cl->qdisc->q.qlen == 0) {
 				update_vf(cl, 0, 0);
 				set_passive(cl);
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 89d15e8..b88a159 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -953,8 +953,7 @@ static unsigned int htb_drop(struct Qdisc *sch)
 			struct htb_class *cl = list_entry(p, struct htb_class,
 							  un.leaf.drop_list);
 			unsigned int len;
-			if (cl->un.leaf.q->ops->drop &&
-			    (len = cl->un.leaf.q->ops->drop(cl->un.leaf.q))) {
+			if ((len = qdisc_drop(cl->un.leaf.q))) {
 				sch->q.qlen--;
 				if (!cl->un.leaf.q->q.qlen)
 					htb_deactivate(q, cl);
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 1458aa3..af52ec8 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -160,12 +160,10 @@ static unsigned int multiq_drop(struct Qdisc *sch)
 
 	for (band = q->bands - 1; band >= 0; band--) {
 		qdisc = q->queues[band];
-		if (qdisc->ops->drop) {
-			len = qdisc->ops->drop(qdisc);
-			if (len != 0) {
-				sch->q.qlen--;
-				return len;
-			}
+		len = qdisc_drop(qdisc);
+		if (len != 0) {
+			sch->q.qlen--;
+			return len;
 		}
 	}
 	return 0;
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 1eb917e..0161193 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -540,8 +540,8 @@ static unsigned int netem_drop(struct Qdisc *sch)
 			kfree_skb(skb);
 		}
 	}
-	if (!len && q->qdisc && q->qdisc->ops->drop)
-	    len = q->qdisc->ops->drop(q->qdisc);
+	if (!len && q->qdisc)
+	    len = qdisc_drop(q->qdisc);
 	if (len)
 		qdisc_qstats_drop(sch);
 
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 0e06d14..200b3b0 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -134,7 +134,7 @@ static unsigned int prio_drop(struct Qdisc *sch)
 
 	for (prio = q->bands-1; prio >= 0; prio--) {
 		qdisc = q->queues[prio];
-		if (qdisc->ops->drop && (len = qdisc->ops->drop(qdisc)) != 0) {
+		if ((len = qdisc_drop(qdisc)) != 0) {
 			sch->q.qlen--;
 			return len;
 		}
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index 9c9a5f3..a847e3a 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -1432,11 +1432,7 @@ static unsigned int qfq_drop_from_slot(struct qfq_sched *q,
 
 	hlist_for_each_entry(agg, slot, next) {
 		list_for_each_entry(cl, &agg->active, alist) {
-
-			if (!cl->qdisc->ops->drop)
-				continue;
-
-			len = cl->qdisc->ops->drop(cl->qdisc);
+			len = qdisc_drop(cl->qdisc);
 			if (len > 0) {
 				if (cl->qdisc->q.qlen == 0)
 					qfq_deactivate_class(q, cl);
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index c19587d..5ea7306 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -140,7 +140,7 @@ static unsigned int red_drop(struct Qdisc *sch)
 	struct Qdisc *child = q->qdisc;
 	unsigned int len;
 
-	if (child->ops->drop && (len = child->ops->drop(child)) > 0) {
+	if ((len = qdisc_drop(child)) > 0) {
 		q->stats.other++;
 		qdisc_qstats_drop(sch);
 		sch->q.qlen--;
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 1f63a71..786e7d6 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -214,7 +214,7 @@ static unsigned int tbf_drop(struct Qdisc *sch)
 	struct tbf_sched_data *q = qdisc_priv(sch);
 	unsigned int len = 0;
 
-	if (q->qdisc->ops->drop && (len = q->qdisc->ops->drop(q->qdisc)) != 0) {
+	if ((len = qdisc_drop(q->qdisc)) != 0) {
 		sch->q.qlen--;
 		qdisc_qstats_drop(sch);
 	}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 06/13] net_sched: move some qdisc flag into qdisc ops
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
                   ` (4 preceding siblings ...)
  2014-11-04 17:56 ` [PATCH 05/13] net_sched: introduce qdisc_drop() helper function Cong Wang
@ 2014-11-04 17:56 ` Cong Wang
  2014-11-04 17:56 ` [PATCH 07/13] net_sched: move TCQ_F_MQROOT " Cong Wang
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang, David S. Miller, Jamal Hadi Salim

For those static flags, that is never changed dynamically,
we could just move them into qdisc->ops. This will be used
by some following patch.

Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 include/net/sch_generic.h |  3 ++-
 net/sched/sch_api.c       |  4 ++--
 net/sched/sch_generic.c   | 10 +++++-----
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 119e129..f552c4c 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -48,7 +48,6 @@ struct Qdisc {
 	int 			(*enqueue)(struct sk_buff *skb, struct Qdisc *dev);
 	struct sk_buff *	(*dequeue)(struct Qdisc *dev);
 	unsigned int		flags;
-#define TCQ_F_BUILTIN		1
 #define TCQ_F_INGRESS		2
 #define TCQ_F_CAN_BYPASS	4
 #define TCQ_F_MQROOT		8
@@ -184,6 +183,8 @@ struct Qdisc_ops {
 	const struct Qdisc_class_ops	*cl_ops;
 	char			id[IFNAMSIZ];
 	int			priv_size;
+#define QDISC_F_BUILTIN		1
+	unsigned int		flags;
 
 	int 			(*enqueue)(struct sk_buff *, struct Qdisc *);
 	struct sk_buff *	(*dequeue)(struct Qdisc *);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 2276b15..b6cad91 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -260,7 +260,7 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
 {
 	struct Qdisc *q;
 
-	if (!(root->flags & TCQ_F_BUILTIN) &&
+	if (!(root->ops->flags & QDISC_F_BUILTIN) &&
 	    root->handle == handle)
 		return root;
 
@@ -1372,7 +1372,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
 
 static bool tc_qdisc_dump_ignore(struct Qdisc *q)
 {
-	return (q->flags & TCQ_F_BUILTIN) ? true : false;
+	return (q->ops->flags & QDISC_F_BUILTIN) ? true : false;
 }
 
 static int qdisc_notify(struct net *net, struct sk_buff *oskb,
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index cd4ba53..3ab44a2 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -392,6 +392,7 @@ static struct sk_buff *noop_dequeue(struct Qdisc *qdisc)
 
 struct Qdisc_ops noop_qdisc_ops __read_mostly = {
 	.id		=	"noop",
+	.flags		=	QDISC_F_BUILTIN,
 	.priv_size	=	0,
 	.enqueue	=	noop_enqueue,
 	.dequeue	=	noop_dequeue,
@@ -407,7 +408,6 @@ static struct netdev_queue noop_netdev_queue = {
 struct Qdisc noop_qdisc = {
 	.enqueue	=	noop_enqueue,
 	.dequeue	=	noop_dequeue,
-	.flags		=	TCQ_F_BUILTIN,
 	.ops		=	&noop_qdisc_ops,
 	.list		=	LIST_HEAD_INIT(noop_qdisc.list),
 	.q.lock		=	__SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock),
@@ -418,6 +418,7 @@ EXPORT_SYMBOL(noop_qdisc);
 
 static struct Qdisc_ops noqueue_qdisc_ops __read_mostly = {
 	.id		=	"noqueue",
+	.flags		=	QDISC_F_BUILTIN,
 	.priv_size	=	0,
 	.enqueue	=	noop_enqueue,
 	.dequeue	=	noop_dequeue,
@@ -434,7 +435,6 @@ static struct netdev_queue noqueue_netdev_queue = {
 static struct Qdisc noqueue_qdisc = {
 	.enqueue	=	NULL,
 	.dequeue	=	noop_dequeue,
-	.flags		=	TCQ_F_BUILTIN,
 	.ops		=	&noqueue_qdisc_ops,
 	.list		=	LIST_HEAD_INIT(noqueue_qdisc.list),
 	.q.lock		=	__SPIN_LOCK_UNLOCKED(noqueue_qdisc.q.lock),
@@ -676,7 +676,7 @@ void qdisc_destroy(struct Qdisc *qdisc)
 {
 	const struct Qdisc_ops  *ops = qdisc->ops;
 
-	if (qdisc->flags & TCQ_F_BUILTIN ||
+	if (ops->flags & QDISC_F_BUILTIN ||
 	    !atomic_dec_and_test(&qdisc->refcnt))
 		return;
 
@@ -775,7 +775,7 @@ static void transition_one_qdisc(struct net_device *dev,
 	struct Qdisc *new_qdisc = dev_queue->qdisc_sleeping;
 	int *need_watchdog_p = _need_watchdog;
 
-	if (!(new_qdisc->flags & TCQ_F_BUILTIN))
+	if (!(new_qdisc->ops->flags & QDISC_F_BUILTIN))
 		clear_bit(__QDISC_STATE_DEACTIVATED, &new_qdisc->state);
 
 	rcu_assign_pointer(dev_queue->qdisc, new_qdisc);
@@ -824,7 +824,7 @@ static void dev_deactivate_queue(struct net_device *dev,
 	if (qdisc) {
 		spin_lock_bh(qdisc_lock(qdisc));
 
-		if (!(qdisc->flags & TCQ_F_BUILTIN))
+		if (!(qdisc->ops->flags & QDISC_F_BUILTIN))
 			set_bit(__QDISC_STATE_DEACTIVATED, &qdisc->state);
 
 		rcu_assign_pointer(dev_queue->qdisc, qdisc_default);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 07/13] net_sched: move TCQ_F_MQROOT into qdisc ops
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
                   ` (5 preceding siblings ...)
  2014-11-04 17:56 ` [PATCH 06/13] net_sched: move some qdisc flag into qdisc ops Cong Wang
@ 2014-11-04 17:56 ` Cong Wang
  2014-11-04 17:56 ` [PATCH 08/13] net_sched: use a flag to indicate fifo qdiscs instead of the name Cong Wang
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang, David S. Miller, Jamal Hadi Salim

It is just another static flag.

Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 include/net/sch_generic.h | 2 +-
 net/sched/sch_api.c       | 6 +++---
 net/sched/sch_mq.c        | 2 +-
 net/sched/sch_mqprio.c    | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index f552c4c..852f0c5 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -50,7 +50,6 @@ struct Qdisc {
 	unsigned int		flags;
 #define TCQ_F_INGRESS		2
 #define TCQ_F_CAN_BYPASS	4
-#define TCQ_F_MQROOT		8
 #define TCQ_F_ONETXQUEUE	0x10 /* dequeue_skb() can assume all skbs are for
 				      * q->dev_queue : It can test
 				      * netif_xmit_frozen_or_stopped() before
@@ -184,6 +183,7 @@ struct Qdisc_ops {
 	char			id[IFNAMSIZ];
 	int			priv_size;
 #define QDISC_F_BUILTIN		1
+#define QDISC_F_MQ		2
 	unsigned int		flags;
 
 	int 			(*enqueue)(struct sk_buff *, struct Qdisc *);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index b6cad91..98b315f 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -958,12 +958,12 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
 			spinlock_t *root_lock;
 
 			err = -EOPNOTSUPP;
-			if (sch->flags & TCQ_F_MQROOT)
+			if (sch->ops->flags & QDISC_F_MQ)
 				goto err_out4;
 
 			if ((sch->parent != TC_H_ROOT) &&
 			    !(sch->flags & TCQ_F_INGRESS) &&
-			    (!p || !(p->flags & TCQ_F_MQROOT)))
+			    (!p || !(p->ops->flags & QDISC_F_MQ)))
 				root_lock = qdisc_root_sleeping_lock(sch);
 			else
 				root_lock = qdisc_lock(sch);
@@ -1029,7 +1029,7 @@ static int qdisc_change(struct Qdisc *sch, struct nlattr **tca)
 	if (tca[TCA_RATE]) {
 		/* NB: ignores errors from replace_estimator
 		   because change can't be undone. */
-		if (sch->flags & TCQ_F_MQROOT)
+		if (sch->ops->flags & QDISC_F_MQ)
 			goto out;
 		gen_replace_estimator(&sch->bstats,
 				      sch->cpu_bstats,
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index f3cbaec..cab9fc2 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -66,7 +66,6 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt)
 		qdisc->flags |= TCQ_F_ONETXQUEUE;
 	}
 
-	sch->flags |= TCQ_F_MQROOT;
 	return 0;
 
 err:
@@ -237,6 +236,7 @@ static const struct Qdisc_class_ops mq_class_ops = {
 struct Qdisc_ops mq_qdisc_ops __read_mostly = {
 	.cl_ops		= &mq_class_ops,
 	.id		= "mq",
+	.flags		= QDISC_F_MQ,
 	.priv_size	= sizeof(struct mq_sched),
 	.init		= mq_init,
 	.destroy	= mq_destroy,
diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
index 3811a74..dc208c2 100644
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
@@ -155,7 +155,6 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt)
 	for (i = 0; i < TC_BITMASK + 1; i++)
 		netdev_set_prio_tc_map(dev, i, qopt->prio_tc_map[i]);
 
-	sch->flags |= TCQ_F_MQROOT;
 	return 0;
 
 err:
@@ -404,6 +403,7 @@ static const struct Qdisc_class_ops mqprio_class_ops = {
 static struct Qdisc_ops mqprio_qdisc_ops __read_mostly = {
 	.cl_ops		= &mqprio_class_ops,
 	.id		= "mqprio",
+	.flags		= QDISC_F_MQ,
 	.priv_size	= sizeof(struct mqprio_sched),
 	.init		= mqprio_init,
 	.destroy	= mqprio_destroy,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 08/13] net_sched: use a flag to indicate fifo qdiscs instead of the name
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
                   ` (6 preceding siblings ...)
  2014-11-04 17:56 ` [PATCH 07/13] net_sched: move TCQ_F_MQROOT " Cong Wang
@ 2014-11-04 17:56 ` Cong Wang
  2014-11-04 17:56 ` [PATCH 09/13] net_sched: redefine qdisc_create_dflt() Cong Wang
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang, David S. Miller, Jamal Hadi Salim

Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 include/net/sch_generic.h | 1 +
 net/sched/sch_fifo.c      | 6 ++++--
 net/sched/sch_generic.c   | 1 +
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 852f0c5..e02d250 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -184,6 +184,7 @@ struct Qdisc_ops {
 	int			priv_size;
 #define QDISC_F_BUILTIN		1
 #define QDISC_F_MQ		2
+#define QDISC_F_FIFO		4
 	unsigned int		flags;
 
 	int 			(*enqueue)(struct sk_buff *, struct Qdisc *);
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index 2e2398c..55f5212 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -96,6 +96,7 @@ static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
 struct Qdisc_ops pfifo_qdisc_ops __read_mostly = {
 	.id		=	"pfifo",
 	.priv_size	=	0,
+	.flags 		=	QDISC_F_FIFO,
 	.enqueue	=	pfifo_enqueue,
 	.dequeue	=	qdisc_dequeue_head,
 	.peek		=	qdisc_peek_head,
@@ -111,6 +112,7 @@ EXPORT_SYMBOL(pfifo_qdisc_ops);
 struct Qdisc_ops bfifo_qdisc_ops __read_mostly = {
 	.id		=	"bfifo",
 	.priv_size	=	0,
+	.flags 		=	QDISC_F_FIFO,
 	.enqueue	=	bfifo_enqueue,
 	.dequeue	=	qdisc_dequeue_head,
 	.peek		=	qdisc_peek_head,
@@ -126,6 +128,7 @@ EXPORT_SYMBOL(bfifo_qdisc_ops);
 struct Qdisc_ops pfifo_head_drop_qdisc_ops __read_mostly = {
 	.id		=	"pfifo_head_drop",
 	.priv_size	=	0,
+	.flags 		=	QDISC_F_FIFO,
 	.enqueue	=	pfifo_tail_enqueue,
 	.dequeue	=	qdisc_dequeue_head,
 	.peek		=	qdisc_peek_head,
@@ -143,8 +146,7 @@ int fifo_set_limit(struct Qdisc *q, unsigned int limit)
 	struct nlattr *nla;
 	int ret = -ENOMEM;
 
-	/* Hack to avoid sending change message to non-FIFO */
-	if (strncmp(q->ops->id + 1, "fifo", 4) != 0)
+	if (!(q->ops->flags & QDISC_F_FIFO))
 		return 0;
 
 	nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 3ab44a2..4550a46 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -567,6 +567,7 @@ static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
 struct Qdisc_ops pfifo_fast_ops __read_mostly = {
 	.id		=	"pfifo_fast",
 	.priv_size	=	sizeof(struct pfifo_fast_priv),
+	.flags		=	QDISC_F_FIFO,
 	.enqueue	=	pfifo_fast_enqueue,
 	.dequeue	=	pfifo_fast_dequeue,
 	.peek		=	pfifo_fast_peek,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 09/13] net_sched: redefine qdisc_create_dflt()
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
                   ` (7 preceding siblings ...)
  2014-11-04 17:56 ` [PATCH 08/13] net_sched: use a flag to indicate fifo qdiscs instead of the name Cong Wang
@ 2014-11-04 17:56 ` Cong Wang
  2014-11-04 17:56 ` [PATCH 10/13] net_sched: forbid setting default qdisc to inappropriate ones Cong Wang
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang, David S. Miller, stephen hemminger

After commit 6da7c8fcbcbdb50ec68c61 (qdisc: allow
setting default queuing discipline) we can set default qdisc now.
The API qdisc_create_dflt() is now confusing since it doesn't
create the default one, instead it create a specified one. Rename
it to qdisc_create_internal(), and let qdisc_create_dflt() really
create a default one.

Cc: David S. Miller <davem@davemloft.net>
Cc: stephen hemminger <stephen@networkplumber.org>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 include/net/sch_generic.h | 11 +++++++++--
 net/sched/sch_atm.c       |  6 +++---
 net/sched/sch_cbq.c       | 11 ++++++-----
 net/sched/sch_drr.c       |  9 +++++----
 net/sched/sch_dsmark.c    |  6 +++---
 net/sched/sch_fifo.c      |  2 +-
 net/sched/sch_generic.c   | 13 ++++++-------
 net/sched/sch_hfsc.c      | 12 ++++++------
 net/sched/sch_htb.c       | 12 ++++++------
 net/sched/sch_mq.c        |  2 +-
 net/sched/sch_mqprio.c    |  2 +-
 net/sched/sch_multiq.c    |  6 +++---
 net/sched/sch_prio.c      |  6 +++---
 net/sched/sch_qfq.c       |  8 ++++----
 14 files changed, 57 insertions(+), 49 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index e02d250..ba3b6bf 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -403,13 +403,20 @@ void qdisc_destroy(struct Qdisc *qdisc);
 void qdisc_tree_decrease_qlen(struct Qdisc *qdisc, unsigned int n);
 struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
 			  const struct Qdisc_ops *ops);
-struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
-				const struct Qdisc_ops *ops, u32 parentid);
+struct Qdisc *qdisc_create_internal(struct netdev_queue *dev_queue,
+				    const struct Qdisc_ops *ops, u32 parentid);
 void __qdisc_calculate_pkt_len(struct sk_buff *skb,
 			       const struct qdisc_size_table *stab);
 void tcf_destroy(struct tcf_proto *tp);
 void tcf_destroy_chain(struct tcf_proto __rcu **fl);
 
+static inline
+struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
+				unsigned int parentid)
+{
+	return qdisc_create_internal(dev_queue, default_qdisc_ops, parentid);
+}
+
 /* Reset all TX qdiscs greater then index of a device.  */
 static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i)
 {
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index a26e503..29f7067 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -274,7 +274,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
 		goto err_out;
 	}
 	RCU_INIT_POINTER(flow->filter_list, NULL);
-	flow->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid);
+	flow->q = qdisc_create_internal(sch->dev_queue, &pfifo_qdisc_ops, classid);
 	if (!flow->q)
 		flow->q = &noop_qdisc;
 	pr_debug("atm_tc_change: qdisc %p\n", flow->q);
@@ -541,8 +541,8 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt)
 	INIT_LIST_HEAD(&p->flows);
 	INIT_LIST_HEAD(&p->link.list);
 	list_add(&p->link.list, &p->flows);
-	p->link.q = qdisc_create_dflt(sch->dev_queue,
-				      &pfifo_qdisc_ops, sch->handle);
+	p->link.q = qdisc_create_internal(sch->dev_queue,
+					  &pfifo_qdisc_ops, sch->handle);
 	if (!p->link.q)
 		p->link.q = &noop_qdisc;
 	pr_debug("atm_tc_init: link (%p) qdisc %p\n", &p->link, p->link.q);
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index ad2905a..af9eaef 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1366,8 +1366,8 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt)
 	q->link.sibling = &q->link;
 	q->link.common.classid = sch->handle;
 	q->link.qdisc = sch;
-	q->link.q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
-				      sch->handle);
+	q->link.q = qdisc_create_internal(sch->dev_queue, &pfifo_qdisc_ops,
+					  sch->handle);
 	if (!q->link.q)
 		q->link.q = &noop_qdisc;
 
@@ -1613,8 +1613,9 @@ static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 	struct cbq_class *cl = (struct cbq_class *)arg;
 
 	if (new == NULL) {
-		new = qdisc_create_dflt(sch->dev_queue,
-					&pfifo_qdisc_ops, cl->common.classid);
+		new = qdisc_create_internal(sch->dev_queue,
+					    &pfifo_qdisc_ops,
+					    cl->common.classid);
 		if (new == NULL)
 			return -ENOBUFS;
 	} else {
@@ -1863,7 +1864,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 	cl->R_tab = rtab;
 	rtab = NULL;
 	cl->refcnt = 1;
-	cl->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid);
+	cl->q = qdisc_create_internal(sch->dev_queue, &pfifo_qdisc_ops, classid);
 	if (!cl->q)
 		cl->q = &noop_qdisc;
 	cl->common.classid = classid;
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 4007e40..c289528 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -111,8 +111,8 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 	cl->refcnt	   = 1;
 	cl->common.classid = classid;
 	cl->quantum	   = quantum;
-	cl->qdisc	   = qdisc_create_dflt(sch->dev_queue,
-					       &pfifo_qdisc_ops, classid);
+	cl->qdisc	   = qdisc_create_internal(sch->dev_queue,
+						   &pfifo_qdisc_ops, classid);
 	if (cl->qdisc == NULL)
 		cl->qdisc = &noop_qdisc;
 
@@ -220,8 +220,9 @@ static int drr_graft_class(struct Qdisc *sch, unsigned long arg,
 	struct drr_class *cl = (struct drr_class *)arg;
 
 	if (new == NULL) {
-		new = qdisc_create_dflt(sch->dev_queue,
-					&pfifo_qdisc_ops, cl->common.classid);
+		new = qdisc_create_internal(sch->dev_queue,
+					    &pfifo_qdisc_ops,
+					    cl->common.classid);
 		if (new == NULL)
 			new = &noop_qdisc;
 	}
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 0a20722..a11a5b9 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -61,8 +61,8 @@ static int dsmark_graft(struct Qdisc *sch, unsigned long arg,
 		 __func__, sch, p, new, old);
 
 	if (new == NULL) {
-		new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
-					sch->handle);
+		new = qdisc_create_internal(sch->dev_queue, &pfifo_qdisc_ops,
+					    sch->handle);
 		if (new == NULL)
 			new = &noop_qdisc;
 	}
@@ -379,7 +379,7 @@ static int dsmark_init(struct Qdisc *sch, struct nlattr *opt)
 	p->default_index = default_index;
 	p->set_tc_index = nla_get_flag(tb[TCA_DSMARK_SET_TC_INDEX]);
 
-	p->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle);
+	p->q = qdisc_create_internal(sch->dev_queue, &pfifo_qdisc_ops, sch->handle);
 	if (p->q == NULL)
 		p->q = &noop_qdisc;
 
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index 55f5212..c21a037 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -168,7 +168,7 @@ struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops,
 	struct Qdisc *q;
 	int err = -ENOMEM;
 
-	q = qdisc_create_dflt(sch->dev_queue, ops, TC_H_MAKE(sch->handle, 1));
+	q = qdisc_create_internal(sch->dev_queue, ops, TC_H_MAKE(sch->handle, 1));
 	if (q) {
 		err = fifo_set_limit(q, limit);
 		if (err < 0) {
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 4550a46..2b1931d 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -623,9 +623,9 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
 	return ERR_PTR(err);
 }
 
-struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
-				const struct Qdisc_ops *ops,
-				unsigned int parentid)
+struct Qdisc *qdisc_create_internal(struct netdev_queue *dev_queue,
+				    const struct Qdisc_ops *ops,
+				    unsigned int parentid)
 {
 	struct Qdisc *sch;
 
@@ -644,7 +644,7 @@ struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
 errout:
 	return NULL;
 }
-EXPORT_SYMBOL(qdisc_create_dflt);
+EXPORT_SYMBOL(qdisc_create_internal);
 
 /* Under qdisc_lock(qdisc) and BH! */
 
@@ -737,8 +737,7 @@ static void attach_one_default_qdisc(struct net_device *dev,
 	struct Qdisc *qdisc = &noqueue_qdisc;
 
 	if (dev->tx_queue_len) {
-		qdisc = qdisc_create_dflt(dev_queue,
-					  default_qdisc_ops, TC_H_ROOT);
+		qdisc = qdisc_create_dflt(dev_queue, TC_H_ROOT);
 		if (!qdisc) {
 			netdev_info(dev, "activation failed\n");
 			return;
@@ -761,7 +760,7 @@ static void attach_default_qdiscs(struct net_device *dev)
 		dev->qdisc = txq->qdisc_sleeping;
 		atomic_inc(&dev->qdisc->refcnt);
 	} else {
-		qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops, TC_H_ROOT);
+		qdisc = qdisc_create_internal(txq, &mq_qdisc_ops, TC_H_ROOT);
 		if (qdisc) {
 			dev->qdisc = qdisc;
 			qdisc->ops->attach(qdisc);
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 3cc44a8..5741e39 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1084,8 +1084,8 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 	cl->refcnt    = 1;
 	cl->sched     = q;
 	cl->cl_parent = parent;
-	cl->qdisc = qdisc_create_dflt(sch->dev_queue,
-				      &pfifo_qdisc_ops, classid);
+	cl->qdisc = qdisc_create_internal(sch->dev_queue,
+					  &pfifo_qdisc_ops, classid);
 	if (cl->qdisc == NULL)
 		cl->qdisc = &noop_qdisc;
 	INIT_LIST_HEAD(&cl->children);
@@ -1207,8 +1207,8 @@ hfsc_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 	if (cl->level > 0)
 		return -EINVAL;
 	if (new == NULL) {
-		new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
-					cl->cl_common.classid);
+		new = qdisc_create_internal(sch->dev_queue, &pfifo_qdisc_ops,
+					    cl->cl_common.classid);
 		if (new == NULL)
 			new = &noop_qdisc;
 	}
@@ -1449,8 +1449,8 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
 	q->root.cl_common.classid = sch->handle;
 	q->root.refcnt  = 1;
 	q->root.sched   = q;
-	q->root.qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
-					  sch->handle);
+	q->root.qdisc = qdisc_create_internal(sch->dev_queue, &pfifo_qdisc_ops,
+					      sch->handle);
 	if (q->root.qdisc == NULL)
 		q->root.qdisc = &noop_qdisc;
 	INIT_LIST_HEAD(&q->root.children);
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index b88a159..288e6c2 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1160,8 +1160,8 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 	if (cl->level)
 		return -EINVAL;
 	if (new == NULL &&
-	    (new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
-				     cl->common.classid)) == NULL)
+	    (new = qdisc_create_internal(sch->dev_queue, &pfifo_qdisc_ops,
+					 cl->common.classid)) == NULL)
 		return -ENOBUFS;
 
 	sch_tree_lock(sch);
@@ -1285,8 +1285,8 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
 		return -EBUSY;
 
 	if (!cl->level && htb_parent_last_child(cl)) {
-		new_q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
-					  cl->parent->common.classid);
+		new_q = qdisc_create_internal(sch->dev_queue, &pfifo_qdisc_ops,
+					      cl->parent->common.classid);
 		last_child = 1;
 	}
 
@@ -1424,8 +1424,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
 		 * so that can't be used inside of sch_tree_lock
 		 * -- thanks to Karlis Peisenieks
 		 */
-		new_q = qdisc_create_dflt(sch->dev_queue,
-					  &pfifo_qdisc_ops, classid);
+		new_q = qdisc_create_internal(sch->dev_queue,
+					      &pfifo_qdisc_ops, classid);
 		sch_tree_lock(sch);
 		if (parent && !parent->level) {
 			unsigned int qlen = parent->un.leaf.q->q.qlen;
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index cab9fc2..03b8069 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -57,7 +57,7 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt)
 
 	for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
 		dev_queue = netdev_get_tx_queue(dev, ntx);
-		qdisc = qdisc_create_dflt(dev_queue, default_qdisc_ops,
+		qdisc = qdisc_create_dflt(dev_queue,
 					  TC_H_MAKE(TC_H_MAJ(sch->handle),
 						    TC_H_MIN(ntx + 1)));
 		if (qdisc == NULL)
diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
index dc208c2..990368f 100644
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
@@ -124,7 +124,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt)
 
 	for (i = 0; i < dev->num_tx_queues; i++) {
 		dev_queue = netdev_get_tx_queue(dev, i);
-		qdisc = qdisc_create_dflt(dev_queue, default_qdisc_ops,
+		qdisc = qdisc_create_dflt(dev_queue,
 					  TC_H_MAKE(TC_H_MAJ(sch->handle),
 						    TC_H_MIN(i + 1)));
 		if (qdisc == NULL) {
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index af52ec8..1ff48bb 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -226,9 +226,9 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt)
 	for (i = 0; i < q->bands; i++) {
 		if (q->queues[i] == &noop_qdisc) {
 			struct Qdisc *child, *old;
-			child = qdisc_create_dflt(sch->dev_queue,
-						  &pfifo_qdisc_ops,
-						  TC_H_MAKE(sch->handle,
+			child = qdisc_create_internal(sch->dev_queue,
+						      &pfifo_qdisc_ops,
+						      TC_H_MAKE(sch->handle,
 							    i + 1));
 			if (child) {
 				sch_tree_lock(sch);
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 200b3b0..0cf1c6c 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -201,9 +201,9 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
 		if (q->queues[i] == &noop_qdisc) {
 			struct Qdisc *child, *old;
 
-			child = qdisc_create_dflt(sch->dev_queue,
-						  &pfifo_qdisc_ops,
-						  TC_H_MAKE(sch->handle, i + 1));
+			child = qdisc_create_internal(sch->dev_queue,
+						      &pfifo_qdisc_ops,
+						      TC_H_MAKE(sch->handle, i + 1));
 			if (child) {
 				sch_tree_lock(sch);
 				old = q->queues[i];
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index a847e3a..7eb38b0 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -479,8 +479,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 	cl->common.classid = classid;
 	cl->deficit = lmax;
 
-	cl->qdisc = qdisc_create_dflt(sch->dev_queue,
-				      &pfifo_qdisc_ops, classid);
+	cl->qdisc = qdisc_create_internal(sch->dev_queue,
+					  &pfifo_qdisc_ops, classid);
 	if (cl->qdisc == NULL)
 		cl->qdisc = &noop_qdisc;
 
@@ -613,8 +613,8 @@ static int qfq_graft_class(struct Qdisc *sch, unsigned long arg,
 	struct qfq_class *cl = (struct qfq_class *)arg;
 
 	if (new == NULL) {
-		new = qdisc_create_dflt(sch->dev_queue,
-					&pfifo_qdisc_ops, cl->common.classid);
+		new = qdisc_create_internal(sch->dev_queue,
+					    &pfifo_qdisc_ops, cl->common.classid);
 		if (new == NULL)
 			new = &noop_qdisc;
 	}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 10/13] net_sched: forbid setting default qdisc to inappropriate ones
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
                   ` (8 preceding siblings ...)
  2014-11-04 17:56 ` [PATCH 09/13] net_sched: redefine qdisc_create_dflt() Cong Wang
@ 2014-11-04 17:56 ` Cong Wang
  2014-11-04 17:56 ` [PATCH 11/13] net_sched: remove hashmask from Qdisc_class_hash Cong Wang
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang, Stephen Hemminger, Eric Dumazet, David S. Miller

Instead of just documentation, we should explicitly prohibit
setting the default qdisc to inappropriate ones. That is,
setting a flag for appropriate ones.

Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: Eric Dumazet <edumazet@google.com>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 include/net/sch_generic.h |  1 +
 net/sched/sch_api.c       | 12 ++++++++++--
 net/sched/sch_fifo.c      |  6 +++---
 net/sched/sch_fq.c        |  1 +
 net/sched/sch_fq_codel.c  |  1 +
 net/sched/sch_generic.c   |  2 +-
 net/sched/sch_mq.c        |  2 +-
 net/sched/sch_sfq.c       |  1 +
 8 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index ba3b6bf..89c3f37 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -185,6 +185,7 @@ struct Qdisc_ops {
 #define QDISC_F_BUILTIN		1
 #define QDISC_F_MQ		2
 #define QDISC_F_FIFO		4
+#define QDISC_F_PARAM_LESS	8
 	unsigned int		flags;
 
 	int 			(*enqueue)(struct sk_buff *, struct Qdisc *);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 98b315f..f57d3c6 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -227,6 +227,7 @@ static struct Qdisc_ops *qdisc_lookup_default(const char *name)
 int qdisc_set_default(const char *name)
 {
 	const struct Qdisc_ops *ops;
+	int err = 0;
 
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
@@ -243,13 +244,20 @@ int qdisc_set_default(const char *name)
 	}
 
 	if (ops) {
+		if (!(ops->flags & QDISC_F_PARAM_LESS)) {
+			err = -EINVAL;
+			goto unlock;
+		}
 		/* Set new default */
 		module_put(default_qdisc_ops->owner);
 		default_qdisc_ops = ops;
+	} else {
+		err = -ENOENT;
 	}
-	write_unlock(&qdisc_mod_lock);
 
-	return ops ? 0 : -ENOENT;
+unlock:
+	write_unlock(&qdisc_mod_lock);
+	return err;
 }
 
 /* We know handle. Find qdisc among all qdisc's attached to device
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index c21a037..6bed08b 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -96,7 +96,7 @@ static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
 struct Qdisc_ops pfifo_qdisc_ops __read_mostly = {
 	.id		=	"pfifo",
 	.priv_size	=	0,
-	.flags 		=	QDISC_F_FIFO,
+	.flags 		=	QDISC_F_FIFO | QDISC_F_PARAM_LESS,
 	.enqueue	=	pfifo_enqueue,
 	.dequeue	=	qdisc_dequeue_head,
 	.peek		=	qdisc_peek_head,
@@ -112,7 +112,7 @@ EXPORT_SYMBOL(pfifo_qdisc_ops);
 struct Qdisc_ops bfifo_qdisc_ops __read_mostly = {
 	.id		=	"bfifo",
 	.priv_size	=	0,
-	.flags 		=	QDISC_F_FIFO,
+	.flags 		=	QDISC_F_FIFO | QDISC_F_PARAM_LESS,
 	.enqueue	=	bfifo_enqueue,
 	.dequeue	=	qdisc_dequeue_head,
 	.peek		=	qdisc_peek_head,
@@ -128,7 +128,7 @@ EXPORT_SYMBOL(bfifo_qdisc_ops);
 struct Qdisc_ops pfifo_head_drop_qdisc_ops __read_mostly = {
 	.id		=	"pfifo_head_drop",
 	.priv_size	=	0,
-	.flags 		=	QDISC_F_FIFO,
+	.flags 		=	QDISC_F_FIFO | QDISC_F_PARAM_LESS,
 	.enqueue	=	pfifo_tail_enqueue,
 	.dequeue	=	qdisc_dequeue_head,
 	.peek		=	qdisc_peek_head,
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
index 34ec70c..7c359b2 100644
--- a/net/sched/sch_fq.c
+++ b/net/sched/sch_fq.c
@@ -805,6 +805,7 @@ static int fq_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
 
 static struct Qdisc_ops fq_qdisc_ops __read_mostly = {
 	.id		=	"fq",
+	.flags		=	QDISC_F_PARAM_LESS,
 	.priv_size	=	sizeof(struct fq_sched_data),
 
 	.enqueue	=	fq_enqueue,
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index b9ca32e..acc06bf 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -594,6 +594,7 @@ static const struct Qdisc_class_ops fq_codel_class_ops = {
 static struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = {
 	.cl_ops		=	&fq_codel_class_ops,
 	.id		=	"fq_codel",
+	.flags		=	QDISC_F_PARAM_LESS,
 	.priv_size	=	sizeof(struct fq_codel_sched_data),
 	.enqueue	=	fq_codel_enqueue,
 	.dequeue	=	fq_codel_dequeue,
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 2b1931d..29db9c8 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -567,7 +567,7 @@ static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
 struct Qdisc_ops pfifo_fast_ops __read_mostly = {
 	.id		=	"pfifo_fast",
 	.priv_size	=	sizeof(struct pfifo_fast_priv),
-	.flags		=	QDISC_F_FIFO,
+	.flags		=	QDISC_F_FIFO | QDISC_F_PARAM_LESS,
 	.enqueue	=	pfifo_fast_enqueue,
 	.dequeue	=	pfifo_fast_dequeue,
 	.peek		=	pfifo_fast_peek,
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index 03b8069..43f9dc8 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -236,7 +236,7 @@ static const struct Qdisc_class_ops mq_class_ops = {
 struct Qdisc_ops mq_qdisc_ops __read_mostly = {
 	.cl_ops		= &mq_class_ops,
 	.id		= "mq",
-	.flags		= QDISC_F_MQ,
+	.flags		= QDISC_F_MQ | QDISC_F_PARAM_LESS,
 	.priv_size	= sizeof(struct mq_sched),
 	.init		= mq_init,
 	.destroy	= mq_destroy,
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 6212652..0d88d52 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -913,6 +913,7 @@ static const struct Qdisc_class_ops sfq_class_ops = {
 static struct Qdisc_ops sfq_qdisc_ops __read_mostly = {
 	.cl_ops		=	&sfq_class_ops,
 	.id		=	"sfq",
+	.flags		=	QDISC_F_PARAM_LESS,
 	.priv_size	=	sizeof(struct sfq_sched_data),
 	.enqueue	=	sfq_enqueue,
 	.dequeue	=	sfq_dequeue,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 11/13] net_sched: remove hashmask from Qdisc_class_hash
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
                   ` (9 preceding siblings ...)
  2014-11-04 17:56 ` [PATCH 10/13] net_sched: forbid setting default qdisc to inappropriate ones Cong Wang
@ 2014-11-04 17:56 ` Cong Wang
  2014-11-04 17:56 ` [PATCH 12/13] net_sched: remove useless qdisc_stab_lock Cong Wang
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang

Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 include/net/sch_generic.h | 8 +++++---
 net/sched/sch_api.c       | 9 +++------
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 89c3f37..1f30524 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -359,12 +359,14 @@ struct Qdisc_class_common {
 struct Qdisc_class_hash {
 	struct hlist_head	*hash;
 	unsigned int		hashsize;
-	unsigned int		hashmask;
 	unsigned int		hashelems;
 };
 
-static inline unsigned int qdisc_class_hash(u32 id, u32 mask)
+static inline
+unsigned int qdisc_class_hash(unsigned int id, unsigned int hashsize)
 {
+	unsigned int mask = hashsize- 1;
+
 	id ^= id >> 8;
 	id ^= id >> 4;
 	return id & mask;
@@ -376,7 +378,7 @@ qdisc_class_find(const struct Qdisc_class_hash *hash, u32 id)
 	struct Qdisc_class_common *cl;
 	unsigned int h;
 
-	h = qdisc_class_hash(id, hash->hashmask);
+	h = qdisc_class_hash(id, hash->hashsize);
 	hlist_for_each_entry(cl, &hash->hash[h], hnode) {
 		if (cl->classid == id)
 			return cl;
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index f57d3c6..efc60d6 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -647,14 +647,13 @@ void qdisc_class_hash_grow(struct Qdisc *sch, struct Qdisc_class_hash *clhash)
 	struct Qdisc_class_common *cl;
 	struct hlist_node *next;
 	struct hlist_head *nhash, *ohash;
-	unsigned int nsize, nmask, osize;
+	unsigned int nsize, osize;
 	unsigned int i, h;
 
 	/* Rehash when load factor exceeds 0.75 */
 	if (clhash->hashelems * 4 <= clhash->hashsize * 3)
 		return;
 	nsize = clhash->hashsize * 2;
-	nmask = nsize - 1;
 	nhash = qdisc_class_hash_alloc(nsize);
 	if (nhash == NULL)
 		return;
@@ -665,13 +664,12 @@ void qdisc_class_hash_grow(struct Qdisc *sch, struct Qdisc_class_hash *clhash)
 	sch_tree_lock(sch);
 	for (i = 0; i < osize; i++) {
 		hlist_for_each_entry_safe(cl, next, &ohash[i], hnode) {
-			h = qdisc_class_hash(cl->classid, nmask);
+			h = qdisc_class_hash(cl->classid, nsize);
 			hlist_add_head(&cl->hnode, &nhash[h]);
 		}
 	}
 	clhash->hash     = nhash;
 	clhash->hashsize = nsize;
-	clhash->hashmask = nmask;
 	sch_tree_unlock(sch);
 
 	qdisc_class_hash_free(ohash, osize);
@@ -686,7 +684,6 @@ int qdisc_class_hash_init(struct Qdisc_class_hash *clhash)
 	if (clhash->hash == NULL)
 		return -ENOMEM;
 	clhash->hashsize  = size;
-	clhash->hashmask  = size - 1;
 	clhash->hashelems = 0;
 	return 0;
 }
@@ -704,7 +701,7 @@ void qdisc_class_hash_insert(struct Qdisc_class_hash *clhash,
 	unsigned int h;
 
 	INIT_HLIST_NODE(&cl->hnode);
-	h = qdisc_class_hash(cl->classid, clhash->hashmask);
+	h = qdisc_class_hash(cl->classid, clhash->hashsize);
 	hlist_add_head(&cl->hnode, &clhash->hash[h]);
 	clhash->hashelems++;
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 12/13] net_sched: remove useless qdisc_stab_lock
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
                   ` (10 preceding siblings ...)
  2014-11-04 17:56 ` [PATCH 11/13] net_sched: remove hashmask from Qdisc_class_hash Cong Wang
@ 2014-11-04 17:56 ` Cong Wang
  2014-11-04 17:56 ` [PATCH 13/13] net_sched: return NULL instead of ERR_PTR for qdisc_alloc() Cong Wang
  2014-11-04 18:20 ` [PATCH 00/13] net_sched: misc cleanups and improvements Eric Dumazet
  13 siblings, 0 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang

We always acquire rtnl lock when we get or put stab,
so there is no need to use another spinlock.

Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 net/sched/sch_api.c | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index efc60d6..38c42bd 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -441,7 +441,6 @@ void qdisc_put_rtab(struct qdisc_rate_table *tab)
 EXPORT_SYMBOL(qdisc_put_rtab);
 
 static LIST_HEAD(qdisc_stab_list);
-static DEFINE_SPINLOCK(qdisc_stab_lock);
 
 static const struct nla_policy stab_policy[TCA_STAB_MAX + 1] = {
 	[TCA_STAB_BASE]	= { .len = sizeof(struct tc_sizespec) },
@@ -457,6 +456,8 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
 	u16 *tab = NULL;
 	int err;
 
+	ASSERT_RTNL();
+
 	err = nla_parse_nested(tb, TCA_STAB_MAX, opt, stab_policy);
 	if (err < 0)
 		return ERR_PTR(err);
@@ -475,20 +476,15 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
 	if (tsize != s->tsize || (!tab && tsize > 0))
 		return ERR_PTR(-EINVAL);
 
-	spin_lock(&qdisc_stab_lock);
-
 	list_for_each_entry(stab, &qdisc_stab_list, list) {
 		if (memcmp(&stab->szopts, s, sizeof(*s)))
 			continue;
 		if (tsize > 0 && memcmp(stab->data, tab, tsize * sizeof(u16)))
 			continue;
 		stab->refcnt++;
-		spin_unlock(&qdisc_stab_lock);
 		return stab;
 	}
 
-	spin_unlock(&qdisc_stab_lock);
-
 	stab = kmalloc(sizeof(*stab) + tsize * sizeof(u16), GFP_KERNEL);
 	if (!stab)
 		return ERR_PTR(-ENOMEM);
@@ -498,10 +494,7 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
 	if (tsize > 0)
 		memcpy(stab->data, tab, tsize * sizeof(u16));
 
-	spin_lock(&qdisc_stab_lock);
 	list_add_tail(&stab->list, &qdisc_stab_list);
-	spin_unlock(&qdisc_stab_lock);
-
 	return stab;
 }
 
@@ -512,17 +505,15 @@ static void stab_kfree_rcu(struct rcu_head *head)
 
 void qdisc_put_stab(struct qdisc_size_table *tab)
 {
+	ASSERT_RTNL();
+
 	if (!tab)
 		return;
 
-	spin_lock(&qdisc_stab_lock);
-
 	if (--tab->refcnt == 0) {
 		list_del(&tab->list);
 		call_rcu_bh(&tab->rcu, stab_kfree_rcu);
 	}
-
-	spin_unlock(&qdisc_stab_lock);
 }
 EXPORT_SYMBOL(qdisc_put_stab);
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 13/13] net_sched: return NULL instead of ERR_PTR for qdisc_alloc()
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
                   ` (11 preceding siblings ...)
  2014-11-04 17:56 ` [PATCH 12/13] net_sched: remove useless qdisc_stab_lock Cong Wang
@ 2014-11-04 17:56 ` Cong Wang
  2014-11-04 18:20 ` [PATCH 00/13] net_sched: misc cleanups and improvements Eric Dumazet
  13 siblings, 0 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-04 17:56 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang

It always returns ENOFBUFS so we can return NULL
and let its callers set this errno.

Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 net/sched/sch_api.c     | 4 ++--
 net/sched/sch_generic.c | 5 ++---
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 38c42bd..27bfd75 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -905,8 +905,8 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
 		goto err_out;
 
 	sch = qdisc_alloc(dev_queue, ops);
-	if (IS_ERR(sch)) {
-		err = PTR_ERR(sch);
+	if (!sch) {
+		err = -ENOBUFS;
 		goto err_out2;
 	}
 
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 29db9c8..b474fbb 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -585,7 +585,6 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
 	void *p;
 	struct Qdisc *sch;
 	unsigned int size = QDISC_ALIGN(sizeof(*sch)) + ops->priv_size;
-	int err = -ENOBUFS;
 	struct net_device *dev = dev_queue->dev;
 
 	p = kzalloc_node(size, GFP_KERNEL,
@@ -620,7 +619,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
 
 	return sch;
 errout:
-	return ERR_PTR(err);
+	return NULL;
 }
 
 struct Qdisc *qdisc_create_internal(struct netdev_queue *dev_queue,
@@ -633,7 +632,7 @@ struct Qdisc *qdisc_create_internal(struct netdev_queue *dev_queue,
 		goto errout;
 
 	sch = qdisc_alloc(dev_queue, ops);
-	if (IS_ERR(sch))
+	if (!sch)
 		goto errout;
 	sch->parent = parentid;
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH 00/13] net_sched: misc cleanups and improvements
  2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
                   ` (12 preceding siblings ...)
  2014-11-04 17:56 ` [PATCH 13/13] net_sched: return NULL instead of ERR_PTR for qdisc_alloc() Cong Wang
@ 2014-11-04 18:20 ` Eric Dumazet
  2014-11-04 19:56   ` David Miller
  2014-11-05  1:25   ` Cong Wang
  13 siblings, 2 replies; 27+ messages in thread
From: Eric Dumazet @ 2014-11-04 18:20 UTC (permalink / raw)
  To: Cong Wang; +Cc: netdev, Jamal Hadi Salim

On Tue, 2014-11-04 at 09:56 -0800, Cong Wang wrote:
> Minor code cleanups for TC qdiscs and filters, each patch has
> more details.
> 
> Cong Wang (13):
>       net_sched: refactor out tcf_exts
>       net_sched: introduce qdisc_peek() helper function
>       net_sched: rename ->gso_skb to ->dequeued_skb
>       net_sched: rename qdisc_drop() to qdisc_drop_skb()
>       net_sched: introduce qdisc_drop() helper function
>       net_sched: move some qdisc flag into qdisc ops
>       net_sched: move TCQ_F_MQROOT into qdisc ops
>       net_sched: use a flag to indicate fifo qdiscs instead of the name
>       net_sched: redefine qdisc_create_dflt()
>       net_sched: forbid setting default qdisc to inappropriate ones
>       net_sched: remove hashmask from Qdisc_class_hash
>       net_sched: remove useless qdisc_stab_lock
>       net_sched: return NULL instead of ERR_PTR for qdisc_alloc()
> 

NACK for the whole serie.

I am tired of your inexistent changelogs and code churn in qdisc.

If you do not care of writing good changelogs and explain why you want
all this, why should I care spending time to review all this stuff ?

What is the plan, beyond all this code churn ?

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 02/13] net_sched: introduce qdisc_peek() helper function
  2014-11-04 17:56 ` [PATCH 02/13] net_sched: introduce qdisc_peek() helper function Cong Wang
@ 2014-11-04 18:45   ` Stephen Hemminger
  2014-11-05  1:05     ` Cong Wang
  0 siblings, 1 reply; 27+ messages in thread
From: Stephen Hemminger @ 2014-11-04 18:45 UTC (permalink / raw)
  To: Cong Wang; +Cc: netdev

On Tue,  4 Nov 2014 09:56:25 -0800
Cong Wang <xiyou.wangcong@gmail.com> wrote:

> +static inline void qdisc_warn_nonwc(void *func, struct Qdisc *qdisc)
> +{
> +	if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
> +		pr_warn("%pf: %s qdisc %X: is non-work-conserving?\n",
> +			func, qdisc->ops->id, qdisc->handle >> 16);
> +		qdisc->flags |= TCQ_F_WARN_NONWC;
> +	}
> +}
> +

Inilining this and creating N copies of same message is not a step forward.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 00/13] net_sched: misc cleanups and improvements
  2014-11-04 18:20 ` [PATCH 00/13] net_sched: misc cleanups and improvements Eric Dumazet
@ 2014-11-04 19:56   ` David Miller
  2014-11-05  1:25   ` Cong Wang
  1 sibling, 0 replies; 27+ messages in thread
From: David Miller @ 2014-11-04 19:56 UTC (permalink / raw)
  To: eric.dumazet; +Cc: xiyou.wangcong, netdev, jhs

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 04 Nov 2014 10:20:50 -0800

> On Tue, 2014-11-04 at 09:56 -0800, Cong Wang wrote:
>> Minor code cleanups for TC qdiscs and filters, each patch has
>> more details.
>> 
>> Cong Wang (13):
>>       net_sched: refactor out tcf_exts
>>       net_sched: introduce qdisc_peek() helper function
>>       net_sched: rename ->gso_skb to ->dequeued_skb
>>       net_sched: rename qdisc_drop() to qdisc_drop_skb()
>>       net_sched: introduce qdisc_drop() helper function
>>       net_sched: move some qdisc flag into qdisc ops
>>       net_sched: move TCQ_F_MQROOT into qdisc ops
>>       net_sched: use a flag to indicate fifo qdiscs instead of the name
>>       net_sched: redefine qdisc_create_dflt()
>>       net_sched: forbid setting default qdisc to inappropriate ones
>>       net_sched: remove hashmask from Qdisc_class_hash
>>       net_sched: remove useless qdisc_stab_lock
>>       net_sched: return NULL instead of ERR_PTR for qdisc_alloc()
>> 
> 
> NACK for the whole serie.
> 
> I am tired of your inexistent changelogs and code churn in qdisc.
> 
> If you do not care of writing good changelogs and explain why you want
> all this, why should I care spending time to review all this stuff ?
> 
> What is the plan, beyond all this code churn ?

+1

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 02/13] net_sched: introduce qdisc_peek() helper function
  2014-11-04 18:45   ` Stephen Hemminger
@ 2014-11-05  1:05     ` Cong Wang
  2014-11-05  3:49       ` Herbert Xu
  0 siblings, 1 reply; 27+ messages in thread
From: Cong Wang @ 2014-11-05  1:05 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Linux Kernel Network Developers

On Tue, Nov 4, 2014 at 10:45 AM, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> On Tue,  4 Nov 2014 09:56:25 -0800
> Cong Wang <xiyou.wangcong@gmail.com> wrote:
>
>> +static inline void qdisc_warn_nonwc(void *func, struct Qdisc *qdisc)
>> +{
>> +     if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
>> +             pr_warn("%pf: %s qdisc %X: is non-work-conserving?\n",
>> +                     func, qdisc->ops->id, qdisc->handle >> 16);
>> +             qdisc->flags |= TCQ_F_WARN_NONWC;
>> +     }
>> +}
>> +
>
> Inilining this and creating N copies of same message is not a step forward.

Hmm, I think gcc merges same string literals when building Linux kernel?
But I never verify this.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 00/13] net_sched: misc cleanups and improvements
  2014-11-04 18:20 ` [PATCH 00/13] net_sched: misc cleanups and improvements Eric Dumazet
  2014-11-04 19:56   ` David Miller
@ 2014-11-05  1:25   ` Cong Wang
  2014-11-05  1:47     ` Eric Dumazet
  1 sibling, 1 reply; 27+ messages in thread
From: Cong Wang @ 2014-11-05  1:25 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Linux Kernel Network Developers, Jamal Hadi Salim

On Tue, Nov 4, 2014 at 10:20 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> If you do not care of writing good changelogs and explain why you want
> all this, why should I care spending time to review all this stuff ?
>
> What is the plan, beyond all this code churn ?

Why $subject isn't obvious?

I don't understand why you are only mean to me (and probably David Taht too).

Sit down and search the history, you will find:

commit c6be2a10ac2f810bdd01e978c93a8ef65b46120b
Merge: 7fd2561 44cc8ed
Author: David S. Miller <davem@davemloft.net>
Date:   Wed Oct 29 15:59:43 2014 -0400

    Merge branch 'xen-netback-next'

    David Vrabel says:

    ====================
    xen-netback: minor cleanups

    Two minor xen-netback cleanups originally from Zoltan.
    ====================

    Signed-off-by: David S. Miller <davem@davemloft.net>


Tell me, why this changelog in anyway could be better than me? which
was accepted (of course not by you). You can argue I have 13 patches,
but, there is no big difference between 13 cleanup's and 2 cleanup's,
cleanup's are cleanup's, that's it.

Seriously, think about why it should when it's just cleanup's, be practical.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 00/13] net_sched: misc cleanups and improvements
  2014-11-05  1:25   ` Cong Wang
@ 2014-11-05  1:47     ` Eric Dumazet
  2014-11-06 18:05       ` Cong Wang
  0 siblings, 1 reply; 27+ messages in thread
From: Eric Dumazet @ 2014-11-05  1:47 UTC (permalink / raw)
  To: Cong Wang; +Cc: Linux Kernel Network Developers, Jamal Hadi Salim

On Tue, 2014-11-04 at 17:25 -0800, Cong Wang wrote:

> Seriously, think about why it should when it's just cleanup's, be practical.

I seriously ask you to not do cleanups then.

Some people are working adding real stuff here, this code changing every
month is slowing them a lot.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 02/13] net_sched: introduce qdisc_peek() helper function
  2014-11-05  1:05     ` Cong Wang
@ 2014-11-05  3:49       ` Herbert Xu
  2014-11-06  2:50         ` Cong Wang
  0 siblings, 1 reply; 27+ messages in thread
From: Herbert Xu @ 2014-11-05  3:49 UTC (permalink / raw)
  To: Cong Wang; +Cc: stephen, netdev

Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Tue, Nov 4, 2014 at 10:45 AM, Stephen Hemminger
> <stephen@networkplumber.org> wrote:
>> On Tue,  4 Nov 2014 09:56:25 -0800
>> Cong Wang <xiyou.wangcong@gmail.com> wrote:
>>
>>> +static inline void qdisc_warn_nonwc(void *func, struct Qdisc *qdisc)
>>> +{
>>> +     if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
>>> +             pr_warn("%pf: %s qdisc %X: is non-work-conserving?\n",
>>> +                     func, qdisc->ops->id, qdisc->handle >> 16);
>>> +             qdisc->flags |= TCQ_F_WARN_NONWC;
>>> +     }
>>> +}
>>> +
>>
>> Inilining this and creating N copies of same message is not a step forward.
> 
> Hmm, I think gcc merges same string literals when building Linux kernel?
> But I never verify this.

In general you should try to avoid inlining code that's not in
the fast path as that leads to binary code size bloat.  As errors
shouldn't be in the fast path this function should be inlined.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 02/13] net_sched: introduce qdisc_peek() helper function
  2014-11-05  3:49       ` Herbert Xu
@ 2014-11-06  2:50         ` Cong Wang
  0 siblings, 0 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-06  2:50 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Stephen Hemminger, Linux Kernel Network Developers

On Tue, Nov 4, 2014 at 7:49 PM, Herbert Xu <herbert@gondor.apana.org.au> wrote:
> Cong Wang <xiyou.wangcong@gmail.com> wrote:
>> On Tue, Nov 4, 2014 at 10:45 AM, Stephen Hemminger
>> <stephen@networkplumber.org> wrote:
>>> On Tue,  4 Nov 2014 09:56:25 -0800
>>> Cong Wang <xiyou.wangcong@gmail.com> wrote:
>>>
>>>> +static inline void qdisc_warn_nonwc(void *func, struct Qdisc *qdisc)
>>>> +{
>>>> +     if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
>>>> +             pr_warn("%pf: %s qdisc %X: is non-work-conserving?\n",
>>>> +                     func, qdisc->ops->id, qdisc->handle >> 16);
>>>> +             qdisc->flags |= TCQ_F_WARN_NONWC;
>>>> +     }
>>>> +}
>>>> +
>>>
>>> Inilining this and creating N copies of same message is not a step forward.
>>
>> Hmm, I think gcc merges same string literals when building Linux kernel?
>> But I never verify this.
>
> In general you should try to avoid inlining code that's not in
> the fast path as that leads to binary code size bloat.  As errors
> shouldn't be in the fast path this function should be inlined.

Makes sense.

Thanks!

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 00/13] net_sched: misc cleanups and improvements
  2014-11-05  1:47     ` Eric Dumazet
@ 2014-11-06 18:05       ` Cong Wang
  2014-11-06 18:17         ` Eric Dumazet
                           ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Cong Wang @ 2014-11-06 18:05 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Linux Kernel Network Developers, Jamal Hadi Salim

On Tue, Nov 4, 2014 at 5:47 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Tue, 2014-11-04 at 17:25 -0800, Cong Wang wrote:
>
>> Seriously, think about why it should when it's just cleanup's, be practical.
>
> I seriously ask you to not do cleanups then.

Apparently you didn't say this when the following commits got accepted:

commit 436f7c206860729d543a457aca5887e52039a5f4
Author: Fabian Frederick <fabf@skynet.be>
Date:   Tue Nov 4 20:52:14 2014 +0100

    igmp: remove camel case definitions

    use standard uppercase for definitions

    Signed-off-by: Fabian Frederick <fabf@skynet.be>
    Signed-off-by: David S. Miller <davem@davemloft.net>

commit c18450a52a10a5c4cea3dc426c40447a7152290f
Author: Fabian Frederick <fabf@skynet.be>
Date:   Tue Nov 4 20:48:41 2014 +0100

    udp: remove else after return

commit aa1f731e52807077e9e13a86c0cad12d442c8fd4
Author: Fabian Frederick <fabf@skynet.be>
Date:   Tue Nov 4 20:44:04 2014 +0100

    inet: frags: remove inline on static in c file

    remove __inline__ / inline and let compiler decide what to do
    with static functions

    Inspired-by: "David S. Miller" <davem@davemloft.net>
    Signed-off-by: Fabian Frederick <fabf@skynet.be>
    Signed-off-by: David S. Miller <davem@davemloft.net>

>
> Some people are working adding real stuff here, this code changing every
> month is slowing them a lot.
>

Who works on what? Does he/she at least announce it on netdev?
(If you meant John, I already waited for his rcu stuffs in the last
merge window,
I assumed his works is almost done therefore sent this patchset.)

Since when it becomes a rule that we should yield to something not merged,
not even announced? If so, why not adding it to netdev-FAQ?

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 00/13] net_sched: misc cleanups and improvements
  2014-11-06 18:05       ` Cong Wang
@ 2014-11-06 18:17         ` Eric Dumazet
  2014-11-06 19:03           ` David Miller
  2014-11-06 18:21         ` Eric Dumazet
  2014-11-06 19:02         ` David Miller
  2 siblings, 1 reply; 27+ messages in thread
From: Eric Dumazet @ 2014-11-06 18:17 UTC (permalink / raw)
  To: Cong Wang; +Cc: Linux Kernel Network Developers, Jamal Hadi Salim

On Thu, 2014-11-06 at 10:05 -0800, Cong Wang wrote:
> On Tue, Nov 4, 2014 at 5:47 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> > On Tue, 2014-11-04 at 17:25 -0800, Cong Wang wrote:
> >
> >> Seriously, think about why it should when it's just cleanup's, be practical.
> >
> > I seriously ask you to not do cleanups then.
> 
> Apparently you didn't say this when the following commits got accepted:

There is a difference from newbies and you.

As a community, we welcome new comers and encourage them,
but after a while, people sending mostly cleanups are shifting in a
category which doesn't fit to you.

We expect from you more interesting stuff. You can do it.

I understand you want to fully rewrite net/sched to your ideas of
how the code _should_ be.

Doing so forces other people already knowing all this code to spend time
to understand how things changed. And this is really not nice.

If you want to send cleanups, do this once in a while. Do not send 13
patches and expect us to be happy with that. We are not.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 00/13] net_sched: misc cleanups and improvements
  2014-11-06 18:05       ` Cong Wang
  2014-11-06 18:17         ` Eric Dumazet
@ 2014-11-06 18:21         ` Eric Dumazet
  2014-11-06 19:02         ` David Miller
  2 siblings, 0 replies; 27+ messages in thread
From: Eric Dumazet @ 2014-11-06 18:21 UTC (permalink / raw)
  To: Cong Wang; +Cc: Linux Kernel Network Developers, Jamal Hadi Salim

On Thu, 2014-11-06 at 10:05 -0800, Cong Wang wrote:

> 
> Who works on what? Does he/she at least announce it on netdev?
> (If you meant John, I already waited for his rcu stuffs in the last
> merge window,
> I assumed his works is almost done therefore sent this patchset.)
> 
> Since when it becomes a rule that we should yield to something not merged,
> not even announced? If so, why not adding it to netdev-FAQ?

You really dont get it. You cant understand how it really works.

Most probably I am one of the contributor, and my work depends on the
knowledge I got from studying the code. If you constantly change it, my
knowledge is reduced to useless bits.

Clearly you have to understand how _other_ people work, not assume
everybody is as smart as you are.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 00/13] net_sched: misc cleanups and improvements
  2014-11-06 18:05       ` Cong Wang
  2014-11-06 18:17         ` Eric Dumazet
  2014-11-06 18:21         ` Eric Dumazet
@ 2014-11-06 19:02         ` David Miller
  2 siblings, 0 replies; 27+ messages in thread
From: David Miller @ 2014-11-06 19:02 UTC (permalink / raw)
  To: xiyou.wangcong; +Cc: eric.dumazet, netdev, jhs

From: Cong Wang <xiyou.wangcong@gmail.com>
Date: Thu, 6 Nov 2014 10:05:41 -0800

> On Tue, Nov 4, 2014 at 5:47 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>> On Tue, 2014-11-04 at 17:25 -0800, Cong Wang wrote:
>>
>>> Seriously, think about why it should when it's just cleanup's, be practical.
>>
>> I seriously ask you to not do cleanups then.
> 
> Apparently you didn't say this when the following commits got accepted:

I very strongly encourage you to not go arguing down this road.

The issues with your submissions is the amount of churn as well as the
terseness of explanations.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 00/13] net_sched: misc cleanups and improvements
  2014-11-06 18:17         ` Eric Dumazet
@ 2014-11-06 19:03           ` David Miller
  0 siblings, 0 replies; 27+ messages in thread
From: David Miller @ 2014-11-06 19:03 UTC (permalink / raw)
  To: eric.dumazet; +Cc: xiyou.wangcong, netdev, jhs

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 06 Nov 2014 10:17:53 -0800

> There is a difference from newbies and you.
> 
> As a community, we welcome new comers and encourage them,
> but after a while, people sending mostly cleanups are shifting in a
> category which doesn't fit to you.
> 
> We expect from you more interesting stuff. You can do it.

+1

> If you want to send cleanups, do this once in a while. Do not send 13
> patches and expect us to be happy with that. We are not.

+1

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2014-11-06 19:03 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-04 17:56 [PATCH 00/13] net_sched: misc cleanups and improvements Cong Wang
2014-11-04 17:56 ` [PATCH 01/13] net_sched: refactor out tcf_exts Cong Wang
2014-11-04 17:56 ` [PATCH 02/13] net_sched: introduce qdisc_peek() helper function Cong Wang
2014-11-04 18:45   ` Stephen Hemminger
2014-11-05  1:05     ` Cong Wang
2014-11-05  3:49       ` Herbert Xu
2014-11-06  2:50         ` Cong Wang
2014-11-04 17:56 ` [PATCH 03/13] net_sched: rename ->gso_skb to ->dequeued_skb Cong Wang
2014-11-04 17:56 ` [PATCH 04/13] net_sched: rename qdisc_drop() to qdisc_drop_skb() Cong Wang
2014-11-04 17:56 ` [PATCH 05/13] net_sched: introduce qdisc_drop() helper function Cong Wang
2014-11-04 17:56 ` [PATCH 06/13] net_sched: move some qdisc flag into qdisc ops Cong Wang
2014-11-04 17:56 ` [PATCH 07/13] net_sched: move TCQ_F_MQROOT " Cong Wang
2014-11-04 17:56 ` [PATCH 08/13] net_sched: use a flag to indicate fifo qdiscs instead of the name Cong Wang
2014-11-04 17:56 ` [PATCH 09/13] net_sched: redefine qdisc_create_dflt() Cong Wang
2014-11-04 17:56 ` [PATCH 10/13] net_sched: forbid setting default qdisc to inappropriate ones Cong Wang
2014-11-04 17:56 ` [PATCH 11/13] net_sched: remove hashmask from Qdisc_class_hash Cong Wang
2014-11-04 17:56 ` [PATCH 12/13] net_sched: remove useless qdisc_stab_lock Cong Wang
2014-11-04 17:56 ` [PATCH 13/13] net_sched: return NULL instead of ERR_PTR for qdisc_alloc() Cong Wang
2014-11-04 18:20 ` [PATCH 00/13] net_sched: misc cleanups and improvements Eric Dumazet
2014-11-04 19:56   ` David Miller
2014-11-05  1:25   ` Cong Wang
2014-11-05  1:47     ` Eric Dumazet
2014-11-06 18:05       ` Cong Wang
2014-11-06 18:17         ` Eric Dumazet
2014-11-06 19:03           ` David Miller
2014-11-06 18:21         ` Eric Dumazet
2014-11-06 19:02         ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.