From d84231d3a2b20bea26327d9b83c8bd8ba55dc68c Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Sun, 15 Dec 2013 20:15:04 -0800 Subject: net_sched: remove get_stats from tc_action_ops It is not used. Cc: Jamal Hadi Salim Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/act_api.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/net/act_api.h') diff --git a/include/net/act_api.h b/include/net/act_api.h index 9e90fdff470..04c6825e172 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -72,7 +72,6 @@ struct tc_action_ops { __u32 capab; /* capabilities includes 4 bit version */ struct module *owner; int (*act)(struct sk_buff *, const struct tc_action *, struct tcf_result *); - int (*get_stats)(struct sk_buff *, struct tc_action *); int (*dump)(struct sk_buff *, struct tc_action *, int, int); int (*cleanup)(struct tc_action *, int bind); int (*lookup)(struct tc_action *, u32); -- cgit v1.2.3-70-g09d2 From 33be627159913b094bb578e83e9a7fdc66c10208 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Sun, 15 Dec 2013 20:15:05 -0800 Subject: net_sched: act: use standard struct list_head Currently actions are chained by a singly linked list, therefore it is a bit hard to add and remove a specific entry. Convert it to struct list_head so that in the latter patch we can remove an action without finding its head. Cc: Jamal Hadi Salim Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/act_api.h | 12 +++--- include/net/pkt_cls.h | 16 ++++++-- net/sched/act_api.c | 105 +++++++++++++++++++++--------------------------- net/sched/cls_api.c | 54 ++++++++++++------------- net/sched/cls_basic.c | 1 + net/sched/cls_bpf.c | 1 + net/sched/cls_cgroup.c | 1 + net/sched/cls_flow.c | 1 + net/sched/cls_fw.c | 1 + net/sched/cls_route.c | 1 + net/sched/cls_rsvp.h | 1 + net/sched/cls_tcindex.c | 5 ++- net/sched/cls_u32.c | 1 + 13 files changed, 101 insertions(+), 99 deletions(-) (limited to 'include/net/act_api.h') diff --git a/include/net/act_api.h b/include/net/act_api.h index 04c6825e172..a7264261079 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -60,7 +60,7 @@ struct tc_action { const struct tc_action_ops *ops; __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ __u32 order; - struct tc_action *next; + struct list_head list; }; #define TCA_CAP_NONE 0 @@ -99,16 +99,16 @@ void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo); int tcf_register_action(struct tc_action_ops *a); int tcf_unregister_action(struct tc_action_ops *a); -void tcf_action_destroy(struct tc_action *a, int bind); -int tcf_action_exec(struct sk_buff *skb, const struct tc_action *a, +void tcf_action_destroy(struct list_head *actions, int bind); +int tcf_action_exec(struct sk_buff *skb, const struct list_head *actions, struct tcf_result *res); -struct tc_action *tcf_action_init(struct net *net, struct nlattr *nla, +int tcf_action_init(struct net *net, struct nlattr *nla, struct nlattr *est, char *n, int ovr, - int bind); + int bind, struct list_head *); struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind); -int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int); +int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int); int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int); int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int); int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int); diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 2ebef77a2f9..34fe693ddf9 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -62,7 +62,8 @@ tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r) struct tcf_exts { #ifdef CONFIG_NET_CLS_ACT - struct tc_action *action; + __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ + struct list_head actions; #endif }; @@ -74,6 +75,13 @@ struct tcf_ext_map { int police; }; +static inline void tcf_exts_init(struct tcf_exts *exts) +{ +#ifdef CONFIG_NET_CLS_ACT + INIT_LIST_HEAD(&exts->actions); +#endif +} + /** * tcf_exts_is_predicative - check if a predicative extension is present * @exts: tc filter extensions handle @@ -85,7 +93,7 @@ static inline int tcf_exts_is_predicative(struct tcf_exts *exts) { #ifdef CONFIG_NET_CLS_ACT - return !!exts->action; + return !list_empty(&exts->actions); #else return 0; #endif @@ -120,8 +128,8 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts, struct tcf_result *res) { #ifdef CONFIG_NET_CLS_ACT - if (exts->action) - return tcf_action_exec(skb, exts->action, res); + if (!list_empty(&exts->actions)) + return tcf_action_exec(skb, &exts->actions, res); #endif return 0; } diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 51e28f7a463..7d84183b633 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -379,7 +379,7 @@ static struct tc_action_ops *tc_lookup_action_id(u32 type) } #endif -int tcf_action_exec(struct sk_buff *skb, const struct tc_action *act, +int tcf_action_exec(struct sk_buff *skb, const struct list_head *actions, struct tcf_result *res) { const struct tc_action *a; @@ -390,7 +390,7 @@ int tcf_action_exec(struct sk_buff *skb, const struct tc_action *act, ret = TC_ACT_OK; goto exec_done; } - while ((a = act) != NULL) { + list_for_each_entry(a, actions, list) { repeat: if (a->ops) { ret = a->ops->act(skb, a, res); @@ -404,27 +404,26 @@ repeat: if (ret != TC_ACT_PIPE) goto exec_done; } - act = a->next; } exec_done: return ret; } EXPORT_SYMBOL(tcf_action_exec); -void tcf_action_destroy(struct tc_action *act, int bind) +void tcf_action_destroy(struct list_head *actions, int bind) { - struct tc_action *a; + struct tc_action *a, *tmp; - for (a = act; a; a = act) { + list_for_each_entry_safe(a, tmp, actions, list) { if (a->ops) { if (a->ops->cleanup(a, bind) == ACT_P_DELETED) module_put(a->ops->owner); - act = act->next; + list_del(&a->list); kfree(a); } else { /*FIXME: Remove later - catch insertion bugs*/ WARN(1, "tcf_action_destroy: BUG? destroying NULL ops\n"); - act = act->next; + list_del(&a->list); kfree(a); } } @@ -470,14 +469,13 @@ nla_put_failure: EXPORT_SYMBOL(tcf_action_dump_1); int -tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref) +tcf_action_dump(struct sk_buff *skb, struct list_head *actions, int bind, int ref) { struct tc_action *a; int err = -EINVAL; struct nlattr *nest; - while ((a = act) != NULL) { - act = a->next; + list_for_each_entry(a, actions, list) { nest = nla_nest_start(skb, a->order); if (nest == NULL) goto nla_put_failure; @@ -552,6 +550,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, if (a == NULL) goto err_mod; + INIT_LIST_HEAD(&a->list); /* backward compatibility for policer */ if (name == NULL) err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, a, ovr, bind); @@ -578,37 +577,33 @@ err_out: return ERR_PTR(err); } -struct tc_action *tcf_action_init(struct net *net, struct nlattr *nla, +int tcf_action_init(struct net *net, struct nlattr *nla, struct nlattr *est, char *name, int ovr, - int bind) + int bind, struct list_head *actions) { struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; - struct tc_action *head = NULL, *act, *act_prev = NULL; + struct tc_action *act; int err; int i; err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL); if (err < 0) - return ERR_PTR(err); + return err; for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { act = tcf_action_init_1(net, tb[i], est, name, ovr, bind); - if (IS_ERR(act)) + if (IS_ERR(act)) { + err = PTR_ERR(act); goto err; + } act->order = i; - - if (head == NULL) - head = act; - else - act_prev->next = act; - act_prev = act; + list_add_tail(&act->list, actions); } - return head; + return 0; err: - if (head != NULL) - tcf_action_destroy(head, bind); - return act; + tcf_action_destroy(actions, bind); + return err; } int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a, @@ -653,7 +648,7 @@ errout: } static int -tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 portid, u32 seq, +tca_get_fill(struct sk_buff *skb, struct list_head *actions, u32 portid, u32 seq, u16 flags, int event, int bind, int ref) { struct tcamsg *t; @@ -673,7 +668,7 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 portid, u32 seq, if (nest == NULL) goto out_nlmsg_trim; - if (tcf_action_dump(skb, a, bind, ref) < 0) + if (tcf_action_dump(skb, actions, bind, ref) < 0) goto out_nlmsg_trim; nla_nest_end(skb, nest); @@ -688,14 +683,14 @@ out_nlmsg_trim: static int act_get_notify(struct net *net, u32 portid, struct nlmsghdr *n, - struct tc_action *a, int event) + struct list_head *actions, int event) { struct sk_buff *skb; skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); if (!skb) return -ENOBUFS; - if (tca_get_fill(skb, a, portid, n->nlmsg_seq, 0, event, 0, 0) <= 0) { + if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event, 0, 0) <= 0) { kfree_skb(skb); return -EINVAL; } @@ -726,6 +721,7 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid) if (a == NULL) goto err_out; + INIT_LIST_HEAD(&a->list); err = -EINVAL; a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); if (a->ops == NULL) @@ -745,12 +741,12 @@ err_out: return ERR_PTR(err); } -static void cleanup_a(struct tc_action *act) +static void cleanup_a(struct list_head *actions) { - struct tc_action *a; + struct tc_action *a, *tmp; - for (a = act; a; a = act) { - act = a->next; + list_for_each_entry_safe(a, tmp, actions, list) { + list_del(&a->list); kfree(a); } } @@ -765,6 +761,7 @@ static struct tc_action *create_a(int i) return NULL; } act->order = i; + INIT_LIST_HEAD(&act->list); return act; } @@ -852,7 +849,8 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, { int i, ret; struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; - struct tc_action *head = NULL, *act, *act_prev = NULL; + struct tc_action *act; + LIST_HEAD(actions); ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL); if (ret < 0) @@ -872,16 +870,11 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, goto err; } act->order = i; - - if (head == NULL) - head = act; - else - act_prev->next = act; - act_prev = act; + list_add_tail(&act->list, &actions); } if (event == RTM_GETACTION) - ret = act_get_notify(net, portid, n, head, event); + ret = act_get_notify(net, portid, n, &actions, event); else { /* delete */ struct sk_buff *skb; @@ -891,7 +884,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, goto err; } - if (tca_get_fill(skb, head, portid, n->nlmsg_seq, 0, event, + if (tca_get_fill(skb, &actions, portid, n->nlmsg_seq, 0, event, 0, 1) <= 0) { kfree_skb(skb); ret = -EINVAL; @@ -899,7 +892,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, } /* now do the delete */ - tcf_action_destroy(head, 0); + tcf_action_destroy(&actions, 0); ret = rtnetlink_send(skb, net, portid, RTNLGRP_TC, n->nlmsg_flags & NLM_F_ECHO); if (ret > 0) @@ -907,11 +900,11 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, return ret; } err: - cleanup_a(head); + cleanup_a(&actions); return ret; } -static int tcf_add_notify(struct net *net, struct tc_action *a, +static int tcf_add_notify(struct net *net, struct list_head *actions, u32 portid, u32 seq, int event, u16 flags) { struct tcamsg *t; @@ -939,7 +932,7 @@ static int tcf_add_notify(struct net *net, struct tc_action *a, if (nest == NULL) goto out_kfree_skb; - if (tcf_action_dump(skb, a, 0, 0) < 0) + if (tcf_action_dump(skb, actions, 0, 0) < 0) goto out_kfree_skb; nla_nest_end(skb, nest); @@ -963,26 +956,18 @@ tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n, u32 portid, int ovr) { int ret = 0; - struct tc_action *act; - struct tc_action *a; + LIST_HEAD(actions); u32 seq = n->nlmsg_seq; - act = tcf_action_init(net, nla, NULL, NULL, ovr, 0); - if (act == NULL) - goto done; - if (IS_ERR(act)) { - ret = PTR_ERR(act); + ret = tcf_action_init(net, nla, NULL, NULL, ovr, 0, &actions); + if (ret) goto done; - } /* dump then free all the actions after update; inserted policy * stays intact */ - ret = tcf_add_notify(net, act, portid, seq, RTM_NEWACTION, n->nlmsg_flags); - for (a = act; a; a = act) { - act = a->next; - kfree(a); - } + ret = tcf_add_notify(net, &actions, portid, seq, RTM_NEWACTION, n->nlmsg_flags); + cleanup_a(&actions); done: return ret; } diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 8e118af9097..3c056d73d39 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -500,10 +500,8 @@ out: void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts) { #ifdef CONFIG_NET_CLS_ACT - if (exts->action) { - tcf_action_destroy(exts->action, TCA_ACT_UNBIND); - exts->action = NULL; - } + tcf_action_destroy(&exts->actions, TCA_ACT_UNBIND); + INIT_LIST_HEAD(&exts->actions); #endif } EXPORT_SYMBOL(tcf_exts_destroy); @@ -518,6 +516,7 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, { struct tc_action *act; + INIT_LIST_HEAD(&exts->actions); if (map->police && tb[map->police]) { act = tcf_action_init_1(net, tb[map->police], rate_tlv, "police", TCA_ACT_NOREPLACE, @@ -525,16 +524,15 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, if (IS_ERR(act)) return PTR_ERR(act); - act->type = TCA_OLD_COMPAT; - exts->action = act; + act->type = exts->type = TCA_OLD_COMPAT; + list_add(&act->list, &exts->actions); } else if (map->action && tb[map->action]) { - act = tcf_action_init(net, tb[map->action], rate_tlv, + int err; + err = tcf_action_init(net, tb[map->action], rate_tlv, NULL, TCA_ACT_NOREPLACE, - TCA_ACT_BIND); - if (IS_ERR(act)) - return PTR_ERR(act); - - exts->action = act; + TCA_ACT_BIND, &exts->actions); + if (err) + return err; } } #else @@ -551,43 +549,45 @@ void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst, struct tcf_exts *src) { #ifdef CONFIG_NET_CLS_ACT - if (src->action) { - struct tc_action *act; + if (!list_empty(&src->actions)) { + LIST_HEAD(tmp); tcf_tree_lock(tp); - act = dst->action; - dst->action = src->action; + list_splice_init(&dst->actions, &tmp); + list_splice(&src->actions, &dst->actions); tcf_tree_unlock(tp); - if (act) - tcf_action_destroy(act, TCA_ACT_UNBIND); + tcf_action_destroy(&tmp, TCA_ACT_UNBIND); } #endif } EXPORT_SYMBOL(tcf_exts_change); +#define tcf_exts_first_act(ext) \ + list_first_entry(&(exts)->actions, struct tc_action, list) + int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts, const struct tcf_ext_map *map) { #ifdef CONFIG_NET_CLS_ACT - if (map->action && exts->action) { + if (map->action && !list_empty(&exts->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 */ struct nlattr *nest; - - if (exts->action->type != TCA_OLD_COMPAT) { + if (exts->type != TCA_OLD_COMPAT) { nest = nla_nest_start(skb, map->action); if (nest == NULL) goto nla_put_failure; - if (tcf_action_dump(skb, exts->action, 0, 0) < 0) + if (tcf_action_dump(skb, &exts->actions, 0, 0) < 0) goto nla_put_failure; nla_nest_end(skb, nest); } else if (map->police) { + struct tc_action *act = tcf_exts_first_act(exts); nest = nla_nest_start(skb, map->police); if (nest == NULL) goto nla_put_failure; - if (tcf_action_dump_old(skb, exts->action, 0, 0) < 0) + if (tcf_action_dump_old(skb, act, 0, 0) < 0) goto nla_put_failure; nla_nest_end(skb, nest); } @@ -604,13 +604,11 @@ int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts, const struct tcf_ext_map *map) { #ifdef CONFIG_NET_CLS_ACT - if (exts->action) - if (tcf_action_copy_stats(skb, exts->action, 1) < 0) - goto nla_put_failure; + struct tc_action *a = tcf_exts_first_act(exts); + if (tcf_action_copy_stats(skb, a, 1) < 0) + return -1; #endif return 0; -nla_put_failure: __attribute__ ((unused)) - return -1; } EXPORT_SYMBOL(tcf_exts_dump_stats); diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 636d9131d87..7b9b4602b5b 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -191,6 +191,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb, if (f == NULL) goto errout; + tcf_exts_init(&f->exts); err = -EINVAL; if (handle) f->handle = handle; diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index d7c72be121f..90fe275e580 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -271,6 +271,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, if (prog == NULL) return -ENOBUFS; + tcf_exts_init(&prog->exts); if (handle == 0) prog->handle = cls_bpf_grab_new_handle(tp, head); else diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 16006c92c3f..e4fae032bcf 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c @@ -203,6 +203,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb, if (head == NULL) return -ENOBUFS; + tcf_exts_init(&head->exts); head->handle = handle; tcf_tree_lock(tp); diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 83a6322b775..f05904e3848 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -455,6 +455,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb, f->handle = handle; f->mask = ~0U; + tcf_exts_init(&f->exts); get_random_bytes(&f->hashrnd, 4); f->perturb_timer.function = flow_perturbation; diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index 9b97172db84..d1cebad1941 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -280,6 +280,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb, if (f == NULL) return -ENOBUFS; + tcf_exts_init(&f->exts); f->id = handle; err = fw_change_attrs(net, tp, f, tb, tca, base); diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index 37da567d833..f1f1dfdf4eb 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -481,6 +481,7 @@ static int route4_change(struct net *net, struct sk_buff *in_skb, if (f == NULL) goto errout; + tcf_exts_init(&f->exts); err = route4_set_parms(net, tp, base, f, handle, head, tb, tca[TCA_RATE], 1); if (err < 0) diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 252d8b05872..b1d3ce5c5ff 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -471,6 +471,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb, if (f == NULL) goto errout2; + tcf_exts_init(&f->exts); h2 = 16; if (tb[TCA_RSVP_SRC]) { memcpy(f->src, nla_data(tb[TCA_RSVP_SRC]), sizeof(f->src)); diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index b86535a4016..c39bbfc0300 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -215,11 +215,14 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, memcpy(&cp, p, sizeof(cp)); memset(&new_filter_result, 0, sizeof(new_filter_result)); + tcf_exts_init(&new_filter_result.exts); if (old_r) memcpy(&cr, r, sizeof(cr)); - else + else { memset(&cr, 0, sizeof(cr)); + tcf_exts_init(&cr.exts); + } if (tb[TCA_TCINDEX_HASH]) cp.hash = nla_get_u32(tb[TCA_TCINDEX_HASH]); diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 59e546c2ac9..492d9a6401c 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -646,6 +646,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, n->ht_up = ht; n->handle = handle; n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0; + tcf_exts_init(&n->exts); #ifdef CONFIG_CLS_U32_MARK if (tb[TCA_U32_MARK]) { -- cgit v1.2.3-70-g09d2 From 369ba56787d7469c0afda70bb9ff76ad5faaead5 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Sun, 15 Dec 2013 20:15:08 -0800 Subject: net_sched: init struct tcf_hashinfo at register time It looks weird to store the lock out of the struct but still points to a static variable. Just move them into the struct. Cc: Jamal Hadi Salim Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/act_api.h | 18 +++++++++++++++++- net/sched/act_api.c | 16 ++++++++-------- net/sched/act_csum.c | 13 +++++-------- net/sched/act_gact.c | 13 +++++-------- net/sched/act_ipt.c | 21 ++++++++++----------- net/sched/act_mirred.c | 16 +++++++--------- net/sched/act_nat.c | 12 +++++------- net/sched/act_pedit.c | 12 +++++------- net/sched/act_police.c | 38 +++++++++++++++++++------------------- net/sched/act_simple.c | 20 +++++++++++--------- net/sched/act_skbedit.c | 13 +++++-------- 11 files changed, 97 insertions(+), 95 deletions(-) (limited to 'include/net/act_api.h') diff --git a/include/net/act_api.h b/include/net/act_api.h index a7264261079..2b5ec5abfeb 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -38,7 +38,7 @@ struct tcf_common { struct tcf_hashinfo { struct tcf_common **htab; unsigned int hmask; - rwlock_t *lock; + rwlock_t lock; }; static inline unsigned int tcf_hash(u32 index, unsigned int hmask) @@ -46,6 +46,22 @@ static inline unsigned int tcf_hash(u32 index, unsigned int hmask) return index & hmask; } +static inline int tcf_hashinfo_init(struct tcf_hashinfo *hf, unsigned int mask) +{ + rwlock_init(&hf->lock); + hf->hmask = mask; + hf->htab = kzalloc((mask + 1) * sizeof(struct tcf_common *), + GFP_KERNEL); + if (!hf->htab) + return -ENOMEM; + return 0; +} + +static inline void tcf_hashinfo_destroy(struct tcf_hashinfo *hf) +{ + kfree(hf->htab); +} + #ifdef CONFIG_NET_CLS_ACT #define ACT_P_CREATED 1 diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 7d84183b633..125673d5d87 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -34,9 +34,9 @@ void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo) for (p1p = &hinfo->htab[h]; *p1p; p1p = &(*p1p)->tcfc_next) { if (*p1p == p) { - write_lock_bh(hinfo->lock); + write_lock_bh(&hinfo->lock); *p1p = p->tcfc_next; - write_unlock_bh(hinfo->lock); + write_unlock_bh(&hinfo->lock); gen_kill_estimator(&p->tcfc_bstats, &p->tcfc_rate_est); /* @@ -77,7 +77,7 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, int err = 0, index = -1, i = 0, s_i = 0, n_i = 0; struct nlattr *nest; - read_lock_bh(hinfo->lock); + read_lock_bh(&hinfo->lock); s_i = cb->args[0]; @@ -107,7 +107,7 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, } } done: - read_unlock_bh(hinfo->lock); + read_unlock_bh(&hinfo->lock); if (n_i) cb->args[0] += n_i; return n_i; @@ -170,13 +170,13 @@ struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo) { struct tcf_common *p; - read_lock_bh(hinfo->lock); + read_lock_bh(&hinfo->lock); for (p = hinfo->htab[tcf_hash(index, hinfo->hmask)]; p; p = p->tcfc_next) { if (p->tcfc_index == index) break; } - read_unlock_bh(hinfo->lock); + read_unlock_bh(&hinfo->lock); return p; } @@ -257,10 +257,10 @@ void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo) { unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask); - write_lock_bh(hinfo->lock); + write_lock_bh(&hinfo->lock); p->tcfc_next = hinfo->htab[h]; hinfo->htab[h] = p; - write_unlock_bh(hinfo->lock); + write_unlock_bh(&hinfo->lock); } EXPORT_SYMBOL(tcf_hash_insert); diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 5c5edf56adb..5d350c57af3 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -37,15 +37,8 @@ #include #define CSUM_TAB_MASK 15 -static struct tcf_common *tcf_csum_ht[CSUM_TAB_MASK + 1]; static u32 csum_idx_gen; -static DEFINE_RWLOCK(csum_lock); - -static struct tcf_hashinfo csum_hash_info = { - .htab = tcf_csum_ht, - .hmask = CSUM_TAB_MASK, - .lock = &csum_lock, -}; +static struct tcf_hashinfo csum_hash_info; static const struct nla_policy csum_policy[TCA_CSUM_MAX + 1] = { [TCA_CSUM_PARMS] = { .len = sizeof(struct tc_csum), }, @@ -593,6 +586,10 @@ MODULE_LICENSE("GPL"); static int __init csum_init_module(void) { + int err = tcf_hashinfo_init(&csum_hash_info, CSUM_TAB_MASK+1); + if (err) + return err; + return tcf_register_action(&act_csum_ops); } diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index 5645a4d32ab..1e6e0e76524 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -24,15 +24,8 @@ #include #define GACT_TAB_MASK 15 -static struct tcf_common *tcf_gact_ht[GACT_TAB_MASK + 1]; static u32 gact_idx_gen; -static DEFINE_RWLOCK(gact_lock); - -static struct tcf_hashinfo gact_hash_info = { - .htab = tcf_gact_ht, - .hmask = GACT_TAB_MASK, - .lock = &gact_lock, -}; +static struct tcf_hashinfo gact_hash_info; #ifdef CONFIG_GACT_PROB static int gact_net_rand(struct tcf_gact *gact) @@ -215,6 +208,9 @@ MODULE_LICENSE("GPL"); static int __init gact_init_module(void) { + int err = tcf_hashinfo_init(&gact_hash_info, GACT_TAB_MASK+1); + if (err) + return err; #ifdef CONFIG_GACT_PROB pr_info("GACT probability on\n"); #else @@ -226,6 +222,7 @@ static int __init gact_init_module(void) static void __exit gact_cleanup_module(void) { tcf_unregister_action(&act_gact_ops); + tcf_hashinfo_destroy(&gact_hash_info); } module_init(gact_init_module); diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 882a89762f7..8344380ebaf 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -29,15 +29,8 @@ #define IPT_TAB_MASK 15 -static struct tcf_common *tcf_ipt_ht[IPT_TAB_MASK + 1]; static u32 ipt_idx_gen; -static DEFINE_RWLOCK(ipt_lock); - -static struct tcf_hashinfo ipt_hash_info = { - .htab = tcf_ipt_ht, - .hmask = IPT_TAB_MASK, - .lock = &ipt_lock, -}; +static struct tcf_hashinfo ipt_hash_info; static int ipt_init_target(struct xt_entry_target *t, char *table, unsigned int hook) { @@ -320,7 +313,11 @@ MODULE_ALIAS("act_xt"); static int __init ipt_init_module(void) { - int ret1, ret2; + int ret1, ret2, err; + err = tcf_hashinfo_init(&ipt_hash_info, IPT_TAB_MASK+1); + if (err) + return err; + ret1 = tcf_register_action(&act_xt_ops); if (ret1 < 0) printk("Failed to load xt action\n"); @@ -328,9 +325,10 @@ static int __init ipt_init_module(void) if (ret2 < 0) printk("Failed to load ipt action\n"); - if (ret1 < 0 && ret2 < 0) + if (ret1 < 0 && ret2 < 0) { + tcf_hashinfo_destroy(&ipt_hash_info); return ret1; - else + } else return 0; } @@ -338,6 +336,7 @@ static void __exit ipt_cleanup_module(void) { tcf_unregister_action(&act_xt_ops); tcf_unregister_action(&act_ipt_ops); + tcf_hashinfo_destroy(&ipt_hash_info); } module_init(ipt_init_module); diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 252378121ce..199fc9838af 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -30,16 +30,9 @@ #include #define MIRRED_TAB_MASK 7 -static struct tcf_common *tcf_mirred_ht[MIRRED_TAB_MASK + 1]; static u32 mirred_idx_gen; -static DEFINE_RWLOCK(mirred_lock); static LIST_HEAD(mirred_list); - -static struct tcf_hashinfo mirred_hash_info = { - .htab = tcf_mirred_ht, - .hmask = MIRRED_TAB_MASK, - .lock = &mirred_lock, -}; +static struct tcf_hashinfo mirred_hash_info; static int tcf_mirred_release(struct tcf_mirred *m, int bind) { @@ -261,7 +254,6 @@ static struct notifier_block mirred_device_notifier = { .notifier_call = mirred_device_event, }; - static struct tc_action_ops act_mirred_ops = { .kind = "mirred", .hinfo = &mirred_hash_info, @@ -284,6 +276,11 @@ static int __init mirred_init_module(void) if (err) return err; + err = tcf_hashinfo_init(&mirred_hash_info, MIRRED_TAB_MASK+1); + if (err) { + unregister_netdevice_notifier(&mirred_device_notifier); + return err; + } pr_info("Mirror/redirect action on\n"); return tcf_register_action(&act_mirred_ops); } @@ -291,6 +288,7 @@ static int __init mirred_init_module(void) static void __exit mirred_cleanup_module(void) { unregister_netdevice_notifier(&mirred_device_notifier); + tcf_hashinfo_destroy(&mirred_hash_info); tcf_unregister_action(&act_mirred_ops); } diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 6a15ace0024..409fe7181c5 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c @@ -30,15 +30,9 @@ #define NAT_TAB_MASK 15 -static struct tcf_common *tcf_nat_ht[NAT_TAB_MASK + 1]; static u32 nat_idx_gen; -static DEFINE_RWLOCK(nat_lock); -static struct tcf_hashinfo nat_hash_info = { - .htab = tcf_nat_ht, - .hmask = NAT_TAB_MASK, - .lock = &nat_lock, -}; +static struct tcf_hashinfo nat_hash_info; static const struct nla_policy nat_policy[TCA_NAT_MAX + 1] = { [TCA_NAT_PARMS] = { .len = sizeof(struct tc_nat) }, @@ -316,12 +310,16 @@ MODULE_LICENSE("GPL"); static int __init nat_init_module(void) { + int err = tcf_hashinfo_init(&nat_hash_info, NAT_TAB_MASK+1); + if (err) + return err; return tcf_register_action(&act_nat_ops); } static void __exit nat_cleanup_module(void) { tcf_unregister_action(&act_nat_ops); + tcf_hashinfo_destroy(&nat_hash_info); } module_init(nat_init_module); diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 03b67674169..aa5347c1b9f 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -24,15 +24,9 @@ #include #define PEDIT_TAB_MASK 15 -static struct tcf_common *tcf_pedit_ht[PEDIT_TAB_MASK + 1]; static u32 pedit_idx_gen; -static DEFINE_RWLOCK(pedit_lock); -static struct tcf_hashinfo pedit_hash_info = { - .htab = tcf_pedit_ht, - .hmask = PEDIT_TAB_MASK, - .lock = &pedit_lock, -}; +static struct tcf_hashinfo pedit_hash_info; static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = { [TCA_PEDIT_PARMS] = { .len = sizeof(struct tc_pedit) }, @@ -252,11 +246,15 @@ MODULE_LICENSE("GPL"); static int __init pedit_init_module(void) { + int err = tcf_hashinfo_init(&pedit_hash_info, PEDIT_TAB_MASK+1); + if (err) + return err; return tcf_register_action(&act_pedit_ops); } static void __exit pedit_cleanup_module(void) { + tcf_hashinfo_destroy(&pedit_hash_info); tcf_unregister_action(&act_pedit_ops); } diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 16a62c36928..f201576d25c 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -41,15 +41,8 @@ struct tcf_police { container_of(pc, struct tcf_police, common) #define POL_TAB_MASK 15 -static struct tcf_common *tcf_police_ht[POL_TAB_MASK + 1]; static u32 police_idx_gen; -static DEFINE_RWLOCK(police_lock); - -static struct tcf_hashinfo police_hash_info = { - .htab = tcf_police_ht, - .hmask = POL_TAB_MASK, - .lock = &police_lock, -}; +static struct tcf_hashinfo police_hash_info; /* old policer structure from before tc actions */ struct tc_police_compat { @@ -71,12 +64,12 @@ static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *c int err = 0, index = -1, i = 0, s_i = 0, n_i = 0; struct nlattr *nest; - read_lock_bh(&police_lock); + read_lock_bh(&police_hash_info.lock); s_i = cb->args[0]; for (i = 0; i < (POL_TAB_MASK + 1); i++) { - p = tcf_police_ht[tcf_hash(i, POL_TAB_MASK)]; + p = police_hash_info.htab[tcf_hash(i, POL_TAB_MASK)]; for (; p; p = p->tcfc_next) { index++; @@ -101,7 +94,7 @@ static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *c } } done: - read_unlock_bh(&police_lock); + read_unlock_bh(&police_hash_info.lock); if (n_i) cb->args[0] += n_i; return n_i; @@ -116,11 +109,11 @@ static void tcf_police_destroy(struct tcf_police *p) unsigned int h = tcf_hash(p->tcf_index, POL_TAB_MASK); struct tcf_common **p1p; - for (p1p = &tcf_police_ht[h]; *p1p; p1p = &(*p1p)->tcfc_next) { + for (p1p = &police_hash_info.htab[h]; *p1p; p1p = &(*p1p)->tcfc_next) { if (*p1p == &p->common) { - write_lock_bh(&police_lock); + write_lock_bh(&police_hash_info.lock); *p1p = p->tcf_next; - write_unlock_bh(&police_lock); + write_unlock_bh(&police_hash_info.lock); gen_kill_estimator(&p->tcf_bstats, &p->tcf_rate_est); /* @@ -266,10 +259,10 @@ override: police->tcf_index = parm->index ? parm->index : tcf_hash_new_index(&police_idx_gen, &police_hash_info); h = tcf_hash(police->tcf_index, POL_TAB_MASK); - write_lock_bh(&police_lock); - police->tcf_next = tcf_police_ht[h]; - tcf_police_ht[h] = &police->common; - write_unlock_bh(&police_lock); + write_lock_bh(&police_hash_info.lock); + police->tcf_next = police_hash_info.htab[h]; + police_hash_info.htab[h] = &police->common; + write_unlock_bh(&police_hash_info.lock); a->priv = police; return ret; @@ -414,12 +407,19 @@ static struct tc_action_ops act_police_ops = { static int __init police_init_module(void) { - return tcf_register_action(&act_police_ops); + int err = tcf_hashinfo_init(&police_hash_info, POL_TAB_MASK+1); + if (err) + return err; + err = tcf_register_action(&act_police_ops); + if (err) + tcf_hashinfo_destroy(&police_hash_info); + return err; } static void __exit police_cleanup_module(void) { + tcf_hashinfo_destroy(&police_hash_info); tcf_unregister_action(&act_police_ops); } diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 31157d3e729..2d7a0eb11c6 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c @@ -25,15 +25,8 @@ #include #define SIMP_TAB_MASK 7 -static struct tcf_common *tcf_simp_ht[SIMP_TAB_MASK + 1]; static u32 simp_idx_gen; -static DEFINE_RWLOCK(simp_lock); - -static struct tcf_hashinfo simp_hash_info = { - .htab = tcf_simp_ht, - .hmask = SIMP_TAB_MASK, - .lock = &simp_lock, -}; +static struct tcf_hashinfo simp_hash_info; #define SIMP_MAX_DATA 32 static int tcf_simp(struct sk_buff *skb, const struct tc_action *a, @@ -209,14 +202,23 @@ MODULE_LICENSE("GPL"); static int __init simp_init_module(void) { - int ret = tcf_register_action(&act_simp_ops); + int err, ret; + err = tcf_hashinfo_init(&simp_hash_info, SIMP_TAB_MASK+1); + if (err) + return err; + + ret = tcf_register_action(&act_simp_ops); if (!ret) pr_info("Simple TC action Loaded\n"); + else + tcf_hashinfo_destroy(&simp_hash_info); + return ret; } static void __exit simp_cleanup_module(void) { + tcf_hashinfo_destroy(&simp_hash_info); tcf_unregister_action(&act_simp_ops); } diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index cf20add1c3f..90ed04a83cf 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c @@ -28,15 +28,8 @@ #include #define SKBEDIT_TAB_MASK 15 -static struct tcf_common *tcf_skbedit_ht[SKBEDIT_TAB_MASK + 1]; static u32 skbedit_idx_gen; -static DEFINE_RWLOCK(skbedit_lock); - -static struct tcf_hashinfo skbedit_hash_info = { - .htab = tcf_skbedit_ht, - .hmask = SKBEDIT_TAB_MASK, - .lock = &skbedit_lock, -}; +static struct tcf_hashinfo skbedit_hash_info; static int tcf_skbedit(struct sk_buff *skb, const struct tc_action *a, struct tcf_result *res) @@ -210,11 +203,15 @@ MODULE_LICENSE("GPL"); static int __init skbedit_init_module(void) { + int err = tcf_hashinfo_init(&skbedit_hash_info, SKBEDIT_TAB_MASK+1); + if (err) + return err; return tcf_register_action(&act_skbedit_ops); } static void __exit skbedit_cleanup_module(void) { + tcf_hashinfo_destroy(&skbedit_hash_info); tcf_unregister_action(&act_skbedit_ops); } -- cgit v1.2.3-70-g09d2 From 89819dc01f4c5920783f561597a48d9d75220e9e Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Sun, 15 Dec 2013 20:15:09 -0800 Subject: net_sched: convert tcf_hashinfo to hlist and use spinlock So that we don't need to play with singly linked list, and since the code is not on hot path, we can use spinlock instead of rwlock. Cc: Jamal Hadi Salim Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/act_api.h | 16 +++++++----- net/sched/act_api.c | 69 ++++++++++++++++++++++---------------------------- net/sched/act_police.c | 45 +++++++++++++------------------- 3 files changed, 58 insertions(+), 72 deletions(-) (limited to 'include/net/act_api.h') diff --git a/include/net/act_api.h b/include/net/act_api.h index 2b5ec5abfeb..22418d1a839 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -9,7 +9,7 @@ #include struct tcf_common { - struct tcf_common *tcfc_next; + struct hlist_node tcfc_head; u32 tcfc_index; int tcfc_refcnt; int tcfc_bindcnt; @@ -22,7 +22,7 @@ struct tcf_common { spinlock_t tcfc_lock; struct rcu_head tcfc_rcu; }; -#define tcf_next common.tcfc_next +#define tcf_head common.tcfc_head #define tcf_index common.tcfc_index #define tcf_refcnt common.tcfc_refcnt #define tcf_bindcnt common.tcfc_bindcnt @@ -36,9 +36,9 @@ struct tcf_common { #define tcf_rcu common.tcfc_rcu struct tcf_hashinfo { - struct tcf_common **htab; + struct hlist_head *htab; unsigned int hmask; - rwlock_t lock; + spinlock_t lock; }; static inline unsigned int tcf_hash(u32 index, unsigned int hmask) @@ -48,12 +48,16 @@ static inline unsigned int tcf_hash(u32 index, unsigned int hmask) static inline int tcf_hashinfo_init(struct tcf_hashinfo *hf, unsigned int mask) { - rwlock_init(&hf->lock); + int i; + + spin_lock_init(&hf->lock); hf->hmask = mask; - hf->htab = kzalloc((mask + 1) * sizeof(struct tcf_common *), + hf->htab = kzalloc((mask + 1) * sizeof(struct hlist_head), GFP_KERNEL); if (!hf->htab) return -ENOMEM; + for (i = 0; i < mask + 1; i++) + INIT_HLIST_HEAD(&hf->htab[i]); return 0; } diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 125673d5d87..dc457c95765 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -29,25 +29,16 @@ void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo) { - unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask); - struct tcf_common **p1p; - - for (p1p = &hinfo->htab[h]; *p1p; p1p = &(*p1p)->tcfc_next) { - if (*p1p == p) { - write_lock_bh(&hinfo->lock); - *p1p = p->tcfc_next; - write_unlock_bh(&hinfo->lock); - gen_kill_estimator(&p->tcfc_bstats, - &p->tcfc_rate_est); - /* - * gen_estimator est_timer() might access p->tcfc_lock - * or bstats, wait a RCU grace period before freeing p - */ - kfree_rcu(p, tcfc_rcu); - return; - } - } - WARN_ON(1); + spin_lock_bh(&hinfo->lock); + hlist_del(&p->tcfc_head); + spin_unlock_bh(&hinfo->lock); + gen_kill_estimator(&p->tcfc_bstats, + &p->tcfc_rate_est); + /* + * gen_estimator est_timer() might access p->tcfc_lock + * or bstats, wait a RCU grace period before freeing p + */ + kfree_rcu(p, tcfc_rcu); } EXPORT_SYMBOL(tcf_hash_destroy); @@ -73,18 +64,19 @@ EXPORT_SYMBOL(tcf_hash_release); static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, struct tc_action *a, struct tcf_hashinfo *hinfo) { + struct hlist_head *head; struct tcf_common *p; int err = 0, index = -1, i = 0, s_i = 0, n_i = 0; struct nlattr *nest; - read_lock_bh(&hinfo->lock); + spin_lock_bh(&hinfo->lock); s_i = cb->args[0]; for (i = 0; i < (hinfo->hmask + 1); i++) { - p = hinfo->htab[tcf_hash(i, hinfo->hmask)]; + head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; - for (; p; p = p->tcfc_next) { + hlist_for_each_entry_rcu(p, head, tcfc_head) { index++; if (index < s_i) continue; @@ -107,7 +99,7 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, } } done: - read_unlock_bh(&hinfo->lock); + spin_unlock_bh(&hinfo->lock); if (n_i) cb->args[0] += n_i; return n_i; @@ -120,7 +112,9 @@ nla_put_failure: static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a, struct tcf_hashinfo *hinfo) { - struct tcf_common *p, *s_p; + struct hlist_head *head; + struct hlist_node *n; + struct tcf_common *p; struct nlattr *nest; int i = 0, n_i = 0; @@ -130,14 +124,11 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a, if (nla_put_string(skb, TCA_KIND, a->ops->kind)) goto nla_put_failure; for (i = 0; i < (hinfo->hmask + 1); i++) { - p = hinfo->htab[tcf_hash(i, hinfo->hmask)]; - - while (p != NULL) { - s_p = p->tcfc_next; + head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; + hlist_for_each_entry_safe(p, n, head, tcfc_head) { if (ACT_P_DELETED == tcf_hash_release(p, 0, hinfo)) module_put(a->ops->owner); n_i++; - p = s_p; } } if (nla_put_u32(skb, TCA_FCNT, n_i)) @@ -168,15 +159,15 @@ EXPORT_SYMBOL(tcf_generic_walker); struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo) { - struct tcf_common *p; + struct tcf_common *p = NULL; + struct hlist_head *head; - read_lock_bh(&hinfo->lock); - for (p = hinfo->htab[tcf_hash(index, hinfo->hmask)]; p; - p = p->tcfc_next) { + spin_lock_bh(&hinfo->lock); + head = &hinfo->htab[tcf_hash(index, hinfo->hmask)]; + hlist_for_each_entry_rcu(p, head, tcfc_head) if (p->tcfc_index == index) break; - } - read_unlock_bh(&hinfo->lock); + spin_unlock_bh(&hinfo->lock); return p; } @@ -236,6 +227,7 @@ struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, p->tcfc_bindcnt = 1; spin_lock_init(&p->tcfc_lock); + INIT_HLIST_NODE(&p->tcfc_head); p->tcfc_index = index ? index : tcf_hash_new_index(idx_gen, hinfo); p->tcfc_tm.install = jiffies; p->tcfc_tm.lastuse = jiffies; @@ -257,10 +249,9 @@ void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo) { unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask); - write_lock_bh(&hinfo->lock); - p->tcfc_next = hinfo->htab[h]; - hinfo->htab[h] = p; - write_unlock_bh(&hinfo->lock); + spin_lock_bh(&hinfo->lock); + hlist_add_head(&p->tcfc_head, &hinfo->htab[h]); + spin_unlock_bh(&hinfo->lock); } EXPORT_SYMBOL(tcf_hash_insert); diff --git a/net/sched/act_police.c b/net/sched/act_police.c index f201576d25c..0cc305e7e46 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -60,18 +60,19 @@ struct tc_police_compat { static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *cb, int type, struct tc_action *a) { + struct hlist_head *head; struct tcf_common *p; int err = 0, index = -1, i = 0, s_i = 0, n_i = 0; struct nlattr *nest; - read_lock_bh(&police_hash_info.lock); + spin_lock_bh(&police_hash_info.lock); s_i = cb->args[0]; for (i = 0; i < (POL_TAB_MASK + 1); i++) { - p = police_hash_info.htab[tcf_hash(i, POL_TAB_MASK)]; + head = &police_hash_info.htab[tcf_hash(i, POL_TAB_MASK)]; - for (; p; p = p->tcfc_next) { + hlist_for_each_entry_rcu(p, head, tcfc_head) { index++; if (index < s_i) continue; @@ -94,7 +95,7 @@ static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *c } } done: - read_unlock_bh(&police_hash_info.lock); + spin_unlock_bh(&police_hash_info.lock); if (n_i) cb->args[0] += n_i; return n_i; @@ -106,25 +107,16 @@ nla_put_failure: static void tcf_police_destroy(struct tcf_police *p) { - unsigned int h = tcf_hash(p->tcf_index, POL_TAB_MASK); - struct tcf_common **p1p; - - for (p1p = &police_hash_info.htab[h]; *p1p; p1p = &(*p1p)->tcfc_next) { - if (*p1p == &p->common) { - write_lock_bh(&police_hash_info.lock); - *p1p = p->tcf_next; - write_unlock_bh(&police_hash_info.lock); - gen_kill_estimator(&p->tcf_bstats, - &p->tcf_rate_est); - /* - * gen_estimator est_timer() might access p->tcf_lock - * or bstats, wait a RCU grace period before freeing p - */ - kfree_rcu(p, tcf_rcu); - return; - } - } - WARN_ON(1); + spin_lock_bh(&police_hash_info.lock); + hlist_del(&p->tcf_head); + spin_unlock_bh(&police_hash_info.lock); + gen_kill_estimator(&p->tcf_bstats, + &p->tcf_rate_est); + /* + * gen_estimator est_timer() might access p->tcf_lock + * or bstats, wait a RCU grace period before freeing p + */ + kfree_rcu(p, tcf_rcu); } static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = { @@ -259,10 +251,9 @@ override: police->tcf_index = parm->index ? parm->index : tcf_hash_new_index(&police_idx_gen, &police_hash_info); h = tcf_hash(police->tcf_index, POL_TAB_MASK); - write_lock_bh(&police_hash_info.lock); - police->tcf_next = police_hash_info.htab[h]; - police_hash_info.htab[h] = &police->common; - write_unlock_bh(&police_hash_info.lock); + spin_lock_bh(&police_hash_info.lock); + hlist_add_head(&police->tcf_head, &police_hash_info.htab[h]); + spin_unlock_bh(&police_hash_info.lock); a->priv = police; return ret; -- cgit v1.2.3-70-g09d2 From 1f747c26c48bb290c79c34e155860c7e2ec3926a Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Sun, 15 Dec 2013 20:15:10 -0800 Subject: net_sched: convert tc_action_ops to use struct list_head We don't need to maintain our own singly linked list code. Cc: Jamal Hadi Salim Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/act_api.h | 2 +- net/sched/act_api.c | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) (limited to 'include/net/act_api.h') diff --git a/include/net/act_api.h b/include/net/act_api.h index 22418d1a839..77d5d8156ef 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -85,7 +85,7 @@ struct tc_action { #define TCA_CAP_NONE 0 struct tc_action_ops { - struct tc_action_ops *next; + struct list_head head; struct tcf_hashinfo *hinfo; char kind[IFNAMSIZ]; __u32 type; /* TBD to match kind */ diff --git a/net/sched/act_api.c b/net/sched/act_api.c index dc457c95765..8114fef308d 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -255,12 +255,12 @@ void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo) } EXPORT_SYMBOL(tcf_hash_insert); -static struct tc_action_ops *act_base = NULL; +static LIST_HEAD(act_base); static DEFINE_RWLOCK(act_mod_lock); int tcf_register_action(struct tc_action_ops *act) { - struct tc_action_ops *a, **ap; + struct tc_action_ops *a; /* Must supply act, dump, cleanup and init */ if (!act->act || !act->dump || !act->cleanup || !act->init) @@ -273,14 +273,13 @@ int tcf_register_action(struct tc_action_ops *act) act->walk = tcf_generic_walker; write_lock(&act_mod_lock); - for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) { + list_for_each_entry(a, &act_base, head) { if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { write_unlock(&act_mod_lock); return -EEXIST; } } - act->next = NULL; - *ap = act; + list_add_tail(&act->head, &act_base); write_unlock(&act_mod_lock); return 0; } @@ -288,16 +287,15 @@ EXPORT_SYMBOL(tcf_register_action); int tcf_unregister_action(struct tc_action_ops *act) { - struct tc_action_ops *a, **ap; + struct tc_action_ops *a; int err = -ENOENT; write_lock(&act_mod_lock); - for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) + list_for_each_entry(a, &act_base, head) if (a == act) break; if (a) { - *ap = a->next; - a->next = NULL; + list_del(&act->head); err = 0; } write_unlock(&act_mod_lock); @@ -312,7 +310,7 @@ static struct tc_action_ops *tc_lookup_action_n(char *kind) if (kind) { read_lock(&act_mod_lock); - for (a = act_base; a; a = a->next) { + list_for_each_entry(a, &act_base, head) { if (strcmp(kind, a->kind) == 0) { if (!try_module_get(a->owner)) { read_unlock(&act_mod_lock); @@ -333,7 +331,7 @@ static struct tc_action_ops *tc_lookup_action(struct nlattr *kind) if (kind) { read_lock(&act_mod_lock); - for (a = act_base; a; a = a->next) { + list_for_each_entry(a, &act_base, head) { if (nla_strcmp(kind, a->kind) == 0) { if (!try_module_get(a->owner)) { read_unlock(&act_mod_lock); -- cgit v1.2.3-70-g09d2 From 9c75f4029cf494ae810a54e34ede9803cff60c7c Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 31 Dec 2013 11:54:00 -0800 Subject: sched action: make local function static No need to export functions only used in one file. Signed-off-by: Stephen Hemminger Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/act_api.h | 3 --- net/sched/act_api.c | 8 +++----- 2 files changed, 3 insertions(+), 8 deletions(-) (limited to 'include/net/act_api.h') diff --git a/include/net/act_api.h b/include/net/act_api.h index 77d5d8156ef..d34e1f4d897 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -105,10 +105,7 @@ struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo); void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo); int tcf_hash_release(struct tcf_common *p, int bind, struct tcf_hashinfo *hinfo); -int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, - int type, struct tc_action *a); u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo); -int tcf_hash_search(struct tc_action *a, u32 index); struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind, struct tcf_hashinfo *hinfo); struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, diff --git a/net/sched/act_api.c b/net/sched/act_api.c index dce2b6ecdbd..6f103fd76c1 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -141,8 +141,8 @@ nla_put_failure: return -EINVAL; } -int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, - int type, struct tc_action *a) +static int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, + int type, struct tc_action *a) { struct tcf_hashinfo *hinfo = a->ops->hinfo; @@ -155,7 +155,6 @@ int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, return -EINVAL; } } -EXPORT_SYMBOL(tcf_generic_walker); struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo) { @@ -187,7 +186,7 @@ u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo) } EXPORT_SYMBOL(tcf_hash_new_index); -int tcf_hash_search(struct tc_action *a, u32 index) +static int tcf_hash_search(struct tc_action *a, u32 index) { struct tcf_hashinfo *hinfo = a->ops->hinfo; struct tcf_common *p = tcf_hash_lookup(index, hinfo); @@ -198,7 +197,6 @@ int tcf_hash_search(struct tc_action *a, u32 index) } return 0; } -EXPORT_SYMBOL(tcf_hash_search); struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind, struct tcf_hashinfo *hinfo) -- cgit v1.2.3-70-g09d2 From ddafd34f419546f1eb7c343178685f059c3cf127 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Thu, 9 Jan 2014 16:13:59 -0800 Subject: net_sched: act: move idx_gen into struct tcf_hashinfo There is no need to store the index separatedly since tcf_hashinfo is allocated statically too. Cc: Jamal Hadi Salim Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/act_api.h | 7 ++++--- net/sched/act_api.c | 10 +++++----- net/sched/act_csum.c | 3 +-- net/sched/act_gact.c | 3 +-- net/sched/act_ipt.c | 3 +-- net/sched/act_mirred.c | 3 +-- net/sched/act_nat.c | 3 +-- net/sched/act_pedit.c | 3 +-- net/sched/act_police.c | 3 +-- net/sched/act_simple.c | 3 +-- net/sched/act_skbedit.c | 3 +-- 11 files changed, 18 insertions(+), 26 deletions(-) (limited to 'include/net/act_api.h') diff --git a/include/net/act_api.h b/include/net/act_api.h index d34e1f4d897..268f9e6babd 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -39,6 +39,7 @@ struct tcf_hashinfo { struct hlist_head *htab; unsigned int hmask; spinlock_t lock; + u32 index; }; static inline unsigned int tcf_hash(u32 index, unsigned int hmask) @@ -51,6 +52,7 @@ static inline int tcf_hashinfo_init(struct tcf_hashinfo *hf, unsigned int mask) int i; spin_lock_init(&hf->lock); + hf->index = 0; hf->hmask = mask; hf->htab = kzalloc((mask + 1) * sizeof(struct hlist_head), GFP_KERNEL); @@ -105,13 +107,12 @@ struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo); void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo); int tcf_hash_release(struct tcf_common *p, int bind, struct tcf_hashinfo *hinfo); -u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo); +u32 tcf_hash_new_index(struct tcf_hashinfo *hinfo); struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind, struct tcf_hashinfo *hinfo); struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, struct tc_action *a, int size, - int bind, u32 *idx_gen, - struct tcf_hashinfo *hinfo); + int bind, struct tcf_hashinfo *hinfo); void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo); int tcf_register_action(struct tc_action_ops *a); diff --git a/net/sched/act_api.c b/net/sched/act_api.c index f63e1467cd3..74ae3ff0574 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -173,16 +173,16 @@ struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo) } EXPORT_SYMBOL(tcf_hash_lookup); -u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo) +u32 tcf_hash_new_index(struct tcf_hashinfo *hinfo) { - u32 val = *idx_gen; + u32 val = hinfo->index; do { if (++val == 0) val = 1; } while (tcf_hash_lookup(val, hinfo)); - *idx_gen = val; + hinfo->index = val; return val; } EXPORT_SYMBOL(tcf_hash_new_index); @@ -215,7 +215,7 @@ EXPORT_SYMBOL(tcf_hash_check); struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, struct tc_action *a, int size, int bind, - u32 *idx_gen, struct tcf_hashinfo *hinfo) + struct tcf_hashinfo *hinfo) { struct tcf_common *p = kzalloc(size, GFP_KERNEL); @@ -227,7 +227,7 @@ struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, spin_lock_init(&p->tcfc_lock); INIT_HLIST_NODE(&p->tcfc_head); - p->tcfc_index = index ? index : tcf_hash_new_index(idx_gen, hinfo); + p->tcfc_index = index ? index : tcf_hash_new_index(hinfo); p->tcfc_tm.install = jiffies; p->tcfc_tm.lastuse = jiffies; if (est) { diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 8b1d65772a8..ee28e1ccbbd 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -37,7 +37,6 @@ #include #define CSUM_TAB_MASK 15 -static u32 csum_idx_gen; static struct tcf_hashinfo csum_hash_info; static const struct nla_policy csum_policy[TCA_CSUM_MAX + 1] = { @@ -67,7 +66,7 @@ static int tcf_csum_init(struct net *n, struct nlattr *nla, struct nlattr *est, pc = tcf_hash_check(parm->index, a, bind, &csum_hash_info); if (!pc) { pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, - &csum_idx_gen, &csum_hash_info); + &csum_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index af5641c290f..f26e6b890cc 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -24,7 +24,6 @@ #include #define GACT_TAB_MASK 15 -static u32 gact_idx_gen; static struct tcf_hashinfo gact_hash_info; #ifdef CONFIG_GACT_PROB @@ -90,7 +89,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, pc = tcf_hash_check(parm->index, a, bind, &gact_hash_info); if (!pc) { pc = tcf_hash_create(parm->index, est, a, sizeof(*gact), - bind, &gact_idx_gen, &gact_hash_info); + bind, &gact_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 242636950ea..484bd19601e 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -29,7 +29,6 @@ #define IPT_TAB_MASK 15 -static u32 ipt_idx_gen; static struct tcf_hashinfo ipt_hash_info; static int ipt_init_target(struct xt_entry_target *t, char *table, unsigned int hook) @@ -129,7 +128,7 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla, struct nlattr *est, pc = tcf_hash_check(index, a, bind, &ipt_hash_info); if (!pc) { pc = tcf_hash_create(index, est, a, sizeof(*ipt), bind, - &ipt_idx_gen, &ipt_hash_info); + &ipt_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 9dbb8cd64cb..5d05b573a62 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -30,7 +30,6 @@ #include #define MIRRED_TAB_MASK 7 -static u32 mirred_idx_gen; static LIST_HEAD(mirred_list); static struct tcf_hashinfo mirred_hash_info; @@ -107,7 +106,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, if (dev == NULL) return -EINVAL; pc = tcf_hash_create(parm->index, est, a, sizeof(*m), bind, - &mirred_idx_gen, &mirred_hash_info); + &mirred_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 584e65503ed..a49fa23b49d 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c @@ -30,7 +30,6 @@ #define NAT_TAB_MASK 15 -static u32 nat_idx_gen; static struct tcf_hashinfo nat_hash_info; @@ -61,7 +60,7 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, pc = tcf_hash_check(parm->index, a, bind, &nat_hash_info); if (!pc) { pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, - &nat_idx_gen, &nat_hash_info); + &nat_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 72918934193..f361e4e3c31 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -24,7 +24,6 @@ #include #define PEDIT_TAB_MASK 15 -static u32 pedit_idx_gen; static struct tcf_hashinfo pedit_hash_info; @@ -63,7 +62,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, if (!parm->nkeys) return -EINVAL; pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, - &pedit_idx_gen, &pedit_hash_info); + &pedit_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); p = to_pedit(pc); diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 9295b86d531..a719fdff575 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -41,7 +41,6 @@ struct tcf_police { container_of(pc, struct tcf_police, common) #define POL_TAB_MASK 15 -static u32 police_idx_gen; static struct tcf_hashinfo police_hash_info; /* old policer structure from before tc actions */ @@ -251,7 +250,7 @@ override: police->tcfp_t_c = ktime_to_ns(ktime_get()); police->tcf_index = parm->index ? parm->index : - tcf_hash_new_index(&police_idx_gen, &police_hash_info); + tcf_hash_new_index(&police_hash_info); h = tcf_hash(police->tcf_index, POL_TAB_MASK); spin_lock_bh(&police_hash_info.lock); hlist_add_head(&police->tcf_head, &police_hash_info.htab[h]); diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index b44491e3ec1..f7d5406c1fe 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c @@ -25,7 +25,6 @@ #include #define SIMP_TAB_MASK 7 -static u32 simp_idx_gen; static struct tcf_hashinfo simp_hash_info; #define SIMP_MAX_DATA 32 @@ -118,7 +117,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info); if (!pc) { pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind, - &simp_idx_gen, &simp_hash_info); + &simp_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index 0fa1aad6e20..74af4612706 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c @@ -28,7 +28,6 @@ #include #define SKBEDIT_TAB_MASK 15 -static u32 skbedit_idx_gen; static struct tcf_hashinfo skbedit_hash_info; static int tcf_skbedit(struct sk_buff *skb, const struct tc_action *a, @@ -104,7 +103,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, pc = tcf_hash_check(parm->index, a, bind, &skbedit_hash_info); if (!pc) { pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind, - &skbedit_idx_gen, &skbedit_hash_info); + &skbedit_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); -- cgit v1.2.3-70-g09d2 From 7eb8896df03d0f4a8b301cb177d7f31c0d70e112 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Thu, 9 Jan 2014 16:14:05 -0800 Subject: net_sched: act: remove struct tcf_act_hdr It is not necessary at all. Cc: Jamal Hadi Salim Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/act_api.h | 4 ---- net/sched/act_api.c | 16 ++++++++-------- 2 files changed, 8 insertions(+), 12 deletions(-) (limited to 'include/net/act_api.h') diff --git a/include/net/act_api.h b/include/net/act_api.h index 268f9e6babd..e171387512b 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -73,10 +73,6 @@ static inline void tcf_hashinfo_destroy(struct tcf_hashinfo *hf) #define ACT_P_CREATED 1 #define ACT_P_DELETED 1 -struct tcf_act_hdr { - struct tcf_common common; -}; - struct tc_action { void *priv; const struct tc_action_ops *ops; diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 178bf2eab11..35f89e9ce49 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -556,9 +556,9 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a, { int err = 0; struct gnet_dump d; - struct tcf_act_hdr *h = a->priv; + struct tcf_common *p = a->priv; - if (h == NULL) + if (p == NULL) goto errout; /* compat_mode being true specifies a call that is supposed @@ -567,20 +567,20 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a, if (compat_mode) { if (a->type == TCA_OLD_COMPAT) err = gnet_stats_start_copy_compat(skb, 0, - TCA_STATS, TCA_XSTATS, &h->tcf_lock, &d); + TCA_STATS, TCA_XSTATS, &p->tcfc_lock, &d); else return 0; } else err = gnet_stats_start_copy(skb, TCA_ACT_STATS, - &h->tcf_lock, &d); + &p->tcfc_lock, &d); if (err < 0) goto errout; - if (gnet_stats_copy_basic(&d, &h->tcf_bstats) < 0 || - gnet_stats_copy_rate_est(&d, &h->tcf_bstats, - &h->tcf_rate_est) < 0 || - gnet_stats_copy_queue(&d, &h->tcf_qstats) < 0) + if (gnet_stats_copy_basic(&d, &p->tcfc_bstats) < 0 || + gnet_stats_copy_rate_est(&d, &p->tcfc_bstats, + &p->tcfc_rate_est) < 0 || + gnet_stats_copy_queue(&d, &p->tcfc_qstats) < 0) goto errout; if (gnet_stats_finish_copy(&d) < 0) -- cgit v1.2.3-70-g09d2 From 671314a5abb7abb8346cd3f16f75c1e55ed7667b Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Wed, 15 Jan 2014 15:49:30 -0800 Subject: net_sched: act: remove capab from struct tc_action_ops It is not actually implemented. Cc: Jamal Hadi Salim Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: David S. Miller --- include/net/act_api.h | 2 -- net/sched/act_csum.c | 1 - net/sched/act_gact.c | 1 - net/sched/act_ipt.c | 2 -- net/sched/act_mirred.c | 1 - net/sched/act_nat.c | 1 - net/sched/act_pedit.c | 1 - net/sched/act_police.c | 1 - net/sched/act_simple.c | 1 - net/sched/act_skbedit.c | 1 - 10 files changed, 12 deletions(-) (limited to 'include/net/act_api.h') diff --git a/include/net/act_api.h b/include/net/act_api.h index e171387512b..8ed97466564 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -81,13 +81,11 @@ struct tc_action { struct list_head list; }; -#define TCA_CAP_NONE 0 struct tc_action_ops { struct list_head head; struct tcf_hashinfo *hinfo; char kind[IFNAMSIZ]; __u32 type; /* TBD to match kind */ - __u32 capab; /* capabilities includes 4 bit version */ struct module *owner; int (*act)(struct sk_buff *, const struct tc_action *, struct tcf_result *); int (*dump)(struct sk_buff *, struct tc_action *, int, int); diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index ee28e1ccbbd..9d5c1d343fe 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -572,7 +572,6 @@ static struct tc_action_ops act_csum_ops = { .kind = "csum", .hinfo = &csum_hash_info, .type = TCA_ACT_CSUM, - .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_csum, .dump = tcf_csum_dump, diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index 31333073cd8..72c49de5061 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -194,7 +194,6 @@ static struct tc_action_ops act_gact_ops = { .kind = "gact", .hinfo = &gact_hash_info, .type = TCA_ACT_GACT, - .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_gact, .dump = tcf_gact_dump, diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index bc9f498f6fe..67d701e0a2b 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -287,7 +287,6 @@ static struct tc_action_ops act_ipt_ops = { .kind = "ipt", .hinfo = &ipt_hash_info, .type = TCA_ACT_IPT, - .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_ipt, .dump = tcf_ipt_dump, @@ -299,7 +298,6 @@ static struct tc_action_ops act_xt_ops = { .kind = "xt", .hinfo = &ipt_hash_info, .type = TCA_ACT_XT, - .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_ipt, .dump = tcf_ipt_dump, diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 5d05b573a62..376234ee851 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -257,7 +257,6 @@ static struct tc_action_ops act_mirred_ops = { .kind = "mirred", .hinfo = &mirred_hash_info, .type = TCA_ACT_MIRRED, - .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_mirred, .dump = tcf_mirred_dump, diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index a49fa23b49d..46e1aa36b14 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c @@ -296,7 +296,6 @@ static struct tc_action_ops act_nat_ops = { .kind = "nat", .hinfo = &nat_hash_info, .type = TCA_ACT_NAT, - .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_nat, .dump = tcf_nat_dump, diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index f361e4e3c31..109265d7c14 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -233,7 +233,6 @@ static struct tc_action_ops act_pedit_ops = { .kind = "pedit", .hinfo = &pedit_hash_info, .type = TCA_ACT_PEDIT, - .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_pedit, .dump = tcf_pedit_dump, diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 5ba467b6124..85437ba5c64 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -361,7 +361,6 @@ static struct tc_action_ops act_police_ops = { .kind = "police", .hinfo = &police_hash_info, .type = TCA_ID_POLICE, - .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_act_police, .dump = tcf_act_police_dump, diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index f7d5406c1fe..92236daaac8 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c @@ -190,7 +190,6 @@ static struct tc_action_ops act_simp_ops = { .kind = "simple", .hinfo = &simp_hash_info, .type = TCA_ACT_SIMP, - .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_simp, .dump = tcf_simp_dump, diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index 74af4612706..c36b5209bc1 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c @@ -189,7 +189,6 @@ static struct tc_action_ops act_skbedit_ops = { .kind = "skbedit", .hinfo = &skbedit_hash_info, .type = TCA_ACT_SKBEDIT, - .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_skbedit, .dump = tcf_skbedit_dump, -- cgit v1.2.3-70-g09d2 From c779f7af99f73abb7270dcaa4c29178ab5ef7472 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Fri, 17 Jan 2014 11:37:02 -0800 Subject: net_sched: act: fetch hinfo from a->ops->hinfo Every action ops has a pointer to hash info, so we don't need to hard-code it in each module. Cc: Jamal Hadi Salim Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/act_api.h | 4 ++-- net/sched/act_api.c | 23 +++++++++++------------ net/sched/act_csum.c | 9 ++++----- net/sched/act_gact.c | 11 +++++------ net/sched/act_ipt.c | 7 +++---- net/sched/act_mirred.c | 7 +++---- net/sched/act_nat.c | 9 ++++----- net/sched/act_pedit.c | 9 ++++----- net/sched/act_police.c | 18 ++++++++++-------- net/sched/act_simple.c | 7 +++---- net/sched/act_skbedit.c | 9 ++++----- 11 files changed, 53 insertions(+), 60 deletions(-) (limited to 'include/net/act_api.h') diff --git a/include/net/act_api.h b/include/net/act_api.h index 8ed97466564..152316b3f59 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -103,10 +103,10 @@ int tcf_hash_release(struct tcf_common *p, int bind, struct tcf_hashinfo *hinfo); u32 tcf_hash_new_index(struct tcf_hashinfo *hinfo); struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, - int bind, struct tcf_hashinfo *hinfo); + int bind); struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, struct tc_action *a, int size, - int bind, struct tcf_hashinfo *hinfo); + int bind); void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo); int tcf_register_action(struct tc_action_ops *a); diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 35f89e9ce49..b94825322d4 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -62,8 +62,9 @@ int tcf_hash_release(struct tcf_common *p, int bind, EXPORT_SYMBOL(tcf_hash_release); static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, - struct tc_action *a, struct tcf_hashinfo *hinfo) + struct tc_action *a) { + struct tcf_hashinfo *hinfo = a->ops->hinfo; struct hlist_head *head; struct tcf_common *p; int err = 0, index = -1, i = 0, s_i = 0, n_i = 0; @@ -109,9 +110,9 @@ nla_put_failure: goto done; } -static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a, - struct tcf_hashinfo *hinfo) +static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a) { + struct tcf_hashinfo *hinfo = a->ops->hinfo; struct hlist_head *head; struct hlist_node *n; struct tcf_common *p; @@ -145,12 +146,10 @@ nla_put_failure: static int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, int type, struct tc_action *a) { - struct tcf_hashinfo *hinfo = a->ops->hinfo; - if (type == RTM_DELACTION) { - return tcf_del_walker(skb, a, hinfo); + return tcf_del_walker(skb, a); } else if (type == RTM_GETACTION) { - return tcf_dump_walker(skb, cb, a, hinfo); + return tcf_dump_walker(skb, cb, a); } else { WARN(1, "tcf_generic_walker: unknown action %d\n", type); return -EINVAL; @@ -199,9 +198,9 @@ static int tcf_hash_search(struct tc_action *a, u32 index) return 0; } -struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind, - struct tcf_hashinfo *hinfo) +struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind) { + struct tcf_hashinfo *hinfo = a->ops->hinfo; struct tcf_common *p = NULL; if (index && (p = tcf_hash_lookup(index, hinfo)) != NULL) { if (bind) @@ -214,9 +213,9 @@ struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind, EXPORT_SYMBOL(tcf_hash_check); struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, - struct tc_action *a, int size, int bind, - struct tcf_hashinfo *hinfo) + struct tc_action *a, int size, int bind) { + struct tcf_hashinfo *hinfo = a->ops->hinfo; struct tcf_common *p = kzalloc(size, GFP_KERNEL); if (unlikely(!p)) @@ -495,6 +494,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, if (a == NULL) goto err_mod; + a->ops = a_o; INIT_LIST_HEAD(&a->list); /* backward compatibility for policer */ if (name == NULL) @@ -510,7 +510,6 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, */ if (err != ACT_P_CREATED) module_put(a_o->owner); - a->ops = a_o; return a; diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 9d5c1d343fe..2210187c45c 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -63,17 +63,16 @@ static int tcf_csum_init(struct net *n, struct nlattr *nla, struct nlattr *est, return -EINVAL; parm = nla_data(tb[TCA_CSUM_PARMS]); - pc = tcf_hash_check(parm->index, a, bind, &csum_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { - pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, - &csum_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; } else { if (bind)/* dont override defaults */ return 0; - tcf_hash_release(pc, bind, &csum_hash_info); + tcf_hash_release(pc, bind, a->ops->hinfo); if (!ovr) return -EEXIST; } @@ -85,7 +84,7 @@ static int tcf_csum_init(struct net *n, struct nlattr *nla, struct nlattr *est, spin_unlock_bh(&p->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &csum_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; } diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index 72c49de5061..a0eed30d581 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -86,17 +86,16 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, } #endif - pc = tcf_hash_check(parm->index, a, bind, &gact_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { - pc = tcf_hash_create(parm->index, est, a, sizeof(*gact), - bind, &gact_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*gact), bind); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; } else { if (bind)/* dont override defaults */ return 0; - tcf_hash_release(pc, bind, &gact_hash_info); + tcf_hash_release(pc, bind, a->ops->hinfo); if (!ovr) return -EEXIST; } @@ -114,7 +113,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, #endif spin_unlock_bh(&gact->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &gact_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; } @@ -123,7 +122,7 @@ static int tcf_gact_cleanup(struct tc_action *a, int bind) struct tcf_gact *gact = a->priv; if (gact) - return tcf_hash_release(&gact->common, bind, &gact_hash_info); + return tcf_hash_release(&gact->common, bind, a->ops->hinfo); return 0; } diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 67d701e0a2b..0a6d6217402 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -125,10 +125,9 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla, struct nlattr *est, if (tb[TCA_IPT_INDEX] != NULL) index = nla_get_u32(tb[TCA_IPT_INDEX]); - pc = tcf_hash_check(index, a, bind, &ipt_hash_info); + pc = tcf_hash_check(index, a, bind); if (!pc) { - pc = tcf_hash_create(index, est, a, sizeof(*ipt), bind, - &ipt_hash_info); + pc = tcf_hash_create(index, est, a, sizeof(*ipt), bind); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; @@ -171,7 +170,7 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla, struct nlattr *est, ipt->tcfi_hook = hook; spin_unlock_bh(&ipt->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &ipt_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; err3: diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 376234ee851..0b2c6d39d39 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -101,12 +101,11 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, dev = NULL; } - pc = tcf_hash_check(parm->index, a, bind, &mirred_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { if (dev == NULL) return -EINVAL; - pc = tcf_hash_create(parm->index, est, a, sizeof(*m), bind, - &mirred_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*m), bind); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; @@ -132,7 +131,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, spin_unlock_bh(&m->tcf_lock); if (ret == ACT_P_CREATED) { list_add(&m->tcfm_list, &mirred_list); - tcf_hash_insert(pc, &mirred_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); } return ret; diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 46e1aa36b14..81f0404bb33 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c @@ -57,17 +57,16 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, return -EINVAL; parm = nla_data(tb[TCA_NAT_PARMS]); - pc = tcf_hash_check(parm->index, a, bind, &nat_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { - pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, - &nat_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; } else { if (bind) return 0; - tcf_hash_release(pc, bind, &nat_hash_info); + tcf_hash_release(pc, bind, a->ops->hinfo); if (!ovr) return -EEXIST; } @@ -83,7 +82,7 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, spin_unlock_bh(&p->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &nat_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; } diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 109265d7c14..be3f0f6875b 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -57,12 +57,11 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, if (nla_len(tb[TCA_PEDIT_PARMS]) < sizeof(*parm) + ksize) return -EINVAL; - pc = tcf_hash_check(parm->index, a, bind, &pedit_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { if (!parm->nkeys) return -EINVAL; - pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, - &pedit_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind); if (IS_ERR(pc)) return PTR_ERR(pc); p = to_pedit(pc); @@ -77,7 +76,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, ret = ACT_P_CREATED; } else { p = to_pedit(pc); - tcf_hash_release(pc, bind, &pedit_hash_info); + tcf_hash_release(pc, bind, a->ops->hinfo); if (bind) return 0; if (!ovr) @@ -101,7 +100,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, memcpy(p->tcfp_keys, parm->keys, ksize); spin_unlock_bh(&p->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &pedit_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; } diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 85437ba5c64..c7093896cf1 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -59,17 +59,18 @@ struct tc_police_compat { static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *cb, int type, struct tc_action *a) { + struct tcf_hashinfo *hinfo = a->ops->hinfo; struct hlist_head *head; struct tcf_common *p; int err = 0, index = -1, i = 0, s_i = 0, n_i = 0; struct nlattr *nest; - spin_lock_bh(&police_hash_info.lock); + spin_lock_bh(&hinfo->lock); s_i = cb->args[0]; for (i = 0; i < (POL_TAB_MASK + 1); i++) { - head = &police_hash_info.htab[tcf_hash(i, POL_TAB_MASK)]; + head = &hinfo->htab[tcf_hash(i, POL_TAB_MASK)]; hlist_for_each_entry_rcu(p, head, tcfc_head) { index++; @@ -94,7 +95,7 @@ static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *c } } done: - spin_unlock_bh(&police_hash_info.lock); + spin_unlock_bh(&hinfo->lock); if (n_i) cb->args[0] += n_i; return n_i; @@ -121,6 +122,7 @@ static int tcf_act_police_locate(struct net *net, struct nlattr *nla, struct tc_police *parm; struct tcf_police *police; struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL; + struct tcf_hashinfo *hinfo = a->ops->hinfo; int size; if (nla == NULL) @@ -140,7 +142,7 @@ static int tcf_act_police_locate(struct net *net, struct nlattr *nla, if (parm->index) { struct tcf_common *pc; - pc = tcf_hash_lookup(parm->index, &police_hash_info); + pc = tcf_hash_lookup(parm->index, hinfo); if (pc != NULL) { a->priv = pc; police = to_police(pc); @@ -236,11 +238,11 @@ override: police->tcfp_t_c = ktime_to_ns(ktime_get()); police->tcf_index = parm->index ? parm->index : - tcf_hash_new_index(&police_hash_info); + tcf_hash_new_index(a->ops->hinfo); h = tcf_hash(police->tcf_index, POL_TAB_MASK); - spin_lock_bh(&police_hash_info.lock); - hlist_add_head(&police->tcf_head, &police_hash_info.htab[h]); - spin_unlock_bh(&police_hash_info.lock); + spin_lock_bh(&hinfo->lock); + hlist_add_head(&police->tcf_head, &hinfo->htab[h]); + spin_unlock_bh(&hinfo->lock); a->priv = police; return ret; diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 92236daaac8..8ef2f1fcbfb 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c @@ -114,10 +114,9 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, parm = nla_data(tb[TCA_DEF_PARMS]); defdata = nla_data(tb[TCA_DEF_DATA]); - pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { - pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind, - &simp_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind); if (IS_ERR(pc)) return PTR_ERR(pc); @@ -145,7 +144,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, } if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &simp_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; } diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index c36b5209bc1..98725080b5a 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c @@ -100,10 +100,9 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, parm = nla_data(tb[TCA_SKBEDIT_PARMS]); - pc = tcf_hash_check(parm->index, a, bind, &skbedit_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { - pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind, - &skbedit_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind); if (IS_ERR(pc)) return PTR_ERR(pc); @@ -113,7 +112,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, d = to_skbedit(pc); if (bind) return 0; - tcf_hash_release(pc, bind, &skbedit_hash_info); + tcf_hash_release(pc, bind, a->ops->hinfo); if (!ovr) return -EEXIST; } @@ -133,7 +132,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, spin_unlock_bh(&d->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &skbedit_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; } -- cgit v1.2.3-70-g09d2 From 6e6a50c254220acb19bd338ce433b1770e4a7a3c Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Fri, 17 Jan 2014 11:37:03 -0800 Subject: net_sched: act: export tcf_hash_search() instead of tcf_hash_lookup() So that we will not expose struct tcf_common to modules. Cc: Jamal Hadi Salim Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/act_api.h | 2 +- net/sched/act_api.c | 6 +++--- net/sched/act_police.c | 8 ++------ 3 files changed, 6 insertions(+), 10 deletions(-) (limited to 'include/net/act_api.h') diff --git a/include/net/act_api.h b/include/net/act_api.h index 152316b3f59..788d8378e58 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -97,7 +97,7 @@ struct tc_action_ops { int (*walk)(struct sk_buff *, struct netlink_callback *, int, struct tc_action *); }; -struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo); +int tcf_hash_search(struct tc_action *a, u32 index); void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo); int tcf_hash_release(struct tcf_common *p, int bind, struct tcf_hashinfo *hinfo); diff --git a/net/sched/act_api.c b/net/sched/act_api.c index b94825322d4..72bdc716634 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -156,7 +156,7 @@ static int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, } } -struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo) +static struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo) { struct tcf_common *p = NULL; struct hlist_head *head; @@ -170,7 +170,6 @@ struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo) return p; } -EXPORT_SYMBOL(tcf_hash_lookup); u32 tcf_hash_new_index(struct tcf_hashinfo *hinfo) { @@ -186,7 +185,7 @@ u32 tcf_hash_new_index(struct tcf_hashinfo *hinfo) } EXPORT_SYMBOL(tcf_hash_new_index); -static int tcf_hash_search(struct tc_action *a, u32 index) +int tcf_hash_search(struct tc_action *a, u32 index) { struct tcf_hashinfo *hinfo = a->ops->hinfo; struct tcf_common *p = tcf_hash_lookup(index, hinfo); @@ -197,6 +196,7 @@ static int tcf_hash_search(struct tc_action *a, u32 index) } return 0; } +EXPORT_SYMBOL(tcf_hash_search); struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind) { diff --git a/net/sched/act_police.c b/net/sched/act_police.c index c7093896cf1..1778209a332 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -140,12 +140,8 @@ static int tcf_act_police_locate(struct net *net, struct nlattr *nla, parm = nla_data(tb[TCA_POLICE_TBF]); if (parm->index) { - struct tcf_common *pc; - - pc = tcf_hash_lookup(parm->index, hinfo); - if (pc != NULL) { - a->priv = pc; - police = to_police(pc); + if (tcf_hash_search(a, parm->index)) { + police = to_police(a->priv); if (bind) { police->tcf_bindcnt += 1; police->tcf_refcnt += 1; -- cgit v1.2.3-70-g09d2