forked from mirrors/linux
		
	net_sched: get rid of struct tcf_common
After the previous patch, struct tc_action should be enough to represent the generic tc action, tcf_common is not necessary any more. This patch gets rid of it to make tc action code more readable. Cc: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									a85a970af2
								
							
						
					
					
						commit
						ec0595cc44
					
				
					 15 changed files with 113 additions and 121 deletions
				
			
		|  | @ -22,42 +22,39 @@ struct tc_action_ops; | ||||||
| 
 | 
 | ||||||
| struct tc_action { | struct tc_action { | ||||||
| 	const struct tc_action_ops	*ops; | 	const struct tc_action_ops	*ops; | ||||||
| 	__u32			type; /* for backward compat(TCA_OLD_COMPAT) */ | 	__u32				type; /* for backward compat(TCA_OLD_COMPAT) */ | ||||||
| 	__u32			order; | 	__u32				order; | ||||||
| 	struct list_head	list; | 	struct list_head		list; | ||||||
| 	struct tcf_hashinfo	*hinfo; | 	struct tcf_hashinfo		*hinfo; | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| struct tcf_common { | 	struct hlist_node		tcfa_head; | ||||||
| 	struct tc_action		tcfc_act; | 	u32				tcfa_index; | ||||||
| 	struct hlist_node		tcfc_head; | 	int				tcfa_refcnt; | ||||||
| 	u32				tcfc_index; | 	int				tcfa_bindcnt; | ||||||
| 	int				tcfc_refcnt; | 	u32				tcfa_capab; | ||||||
| 	int				tcfc_bindcnt; | 	int				tcfa_action; | ||||||
| 	u32				tcfc_capab; | 	struct tcf_t			tcfa_tm; | ||||||
| 	int				tcfc_action; | 	struct gnet_stats_basic_packed	tcfa_bstats; | ||||||
| 	struct tcf_t			tcfc_tm; | 	struct gnet_stats_queue		tcfa_qstats; | ||||||
| 	struct gnet_stats_basic_packed	tcfc_bstats; | 	struct gnet_stats_rate_est64	tcfa_rate_est; | ||||||
| 	struct gnet_stats_queue		tcfc_qstats; | 	spinlock_t			tcfa_lock; | ||||||
| 	struct gnet_stats_rate_est64	tcfc_rate_est; | 	struct rcu_head			tcfa_rcu; | ||||||
| 	spinlock_t			tcfc_lock; |  | ||||||
| 	struct rcu_head			tcfc_rcu; |  | ||||||
| 	struct gnet_stats_basic_cpu __percpu *cpu_bstats; | 	struct gnet_stats_basic_cpu __percpu *cpu_bstats; | ||||||
| 	struct gnet_stats_queue __percpu *cpu_qstats; | 	struct gnet_stats_queue __percpu *cpu_qstats; | ||||||
| }; | }; | ||||||
| #define tcf_act		common.tcfc_act | #define tcf_act		common.tcfa_act | ||||||
| #define tcf_head	common.tcfc_head | #define tcf_head	common.tcfa_head | ||||||
| #define tcf_index	common.tcfc_index | #define tcf_index	common.tcfa_index | ||||||
| #define tcf_refcnt	common.tcfc_refcnt | #define tcf_refcnt	common.tcfa_refcnt | ||||||
| #define tcf_bindcnt	common.tcfc_bindcnt | #define tcf_bindcnt	common.tcfa_bindcnt | ||||||
| #define tcf_capab	common.tcfc_capab | #define tcf_capab	common.tcfa_capab | ||||||
| #define tcf_action	common.tcfc_action | #define tcf_action	common.tcfa_action | ||||||
| #define tcf_tm		common.tcfc_tm | #define tcf_tm		common.tcfa_tm | ||||||
| #define tcf_bstats	common.tcfc_bstats | #define tcf_bstats	common.tcfa_bstats | ||||||
| #define tcf_qstats	common.tcfc_qstats | #define tcf_qstats	common.tcfa_qstats | ||||||
| #define tcf_rate_est	common.tcfc_rate_est | #define tcf_rate_est	common.tcfa_rate_est | ||||||
| #define tcf_lock	common.tcfc_lock | #define tcf_lock	common.tcfa_lock | ||||||
| #define tcf_rcu		common.tcfc_rcu | #define tcf_rcu		common.tcfa_rcu | ||||||
| 
 | 
 | ||||||
| static inline unsigned int tcf_hash(u32 index, unsigned int hmask) | static inline unsigned int tcf_hash(u32 index, unsigned int hmask) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ | ||||||
| #include <net/act_api.h> | #include <net/act_api.h> | ||||||
| 
 | 
 | ||||||
| struct tcf_bpf { | struct tcf_bpf { | ||||||
| 	struct tcf_common	common; | 	struct tc_action	common; | ||||||
| 	struct bpf_prog __rcu	*filter; | 	struct bpf_prog __rcu	*filter; | ||||||
| 	union { | 	union { | ||||||
| 		u32		bpf_fd; | 		u32		bpf_fd; | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ | ||||||
| #include <net/act_api.h> | #include <net/act_api.h> | ||||||
| 
 | 
 | ||||||
| struct tcf_connmark_info { | struct tcf_connmark_info { | ||||||
| 	struct tcf_common common; | 	struct tc_action common; | ||||||
| 	struct net *net; | 	struct net *net; | ||||||
| 	u16 zone; | 	u16 zone; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ | ||||||
| #include <net/act_api.h> | #include <net/act_api.h> | ||||||
| 
 | 
 | ||||||
| struct tcf_csum { | struct tcf_csum { | ||||||
| 	struct tcf_common common; | 	struct tc_action common; | ||||||
| 
 | 
 | ||||||
| 	u32 update_flags; | 	u32 update_flags; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ | ||||||
| #include <net/act_api.h> | #include <net/act_api.h> | ||||||
| 
 | 
 | ||||||
| struct tcf_defact { | struct tcf_defact { | ||||||
| 	struct tcf_common	common; | 	struct tc_action	common; | ||||||
| 	u32		tcfd_datalen; | 	u32		tcfd_datalen; | ||||||
| 	void		*tcfd_defdata; | 	void		*tcfd_defdata; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ | ||||||
| #include <linux/tc_act/tc_gact.h> | #include <linux/tc_act/tc_gact.h> | ||||||
| 
 | 
 | ||||||
| struct tcf_gact { | struct tcf_gact { | ||||||
| 	struct tcf_common	common; | 	struct tc_action	common; | ||||||
| #ifdef CONFIG_GACT_PROB | #ifdef CONFIG_GACT_PROB | ||||||
| 	u16			tcfg_ptype; | 	u16			tcfg_ptype; | ||||||
| 	u16			tcfg_pval; | 	u16			tcfg_pval; | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ | ||||||
| 
 | 
 | ||||||
| #define IFE_METAHDRLEN 2 | #define IFE_METAHDRLEN 2 | ||||||
| struct tcf_ife_info { | struct tcf_ife_info { | ||||||
| 	struct tcf_common common; | 	struct tc_action common; | ||||||
| 	u8 eth_dst[ETH_ALEN]; | 	u8 eth_dst[ETH_ALEN]; | ||||||
| 	u8 eth_src[ETH_ALEN]; | 	u8 eth_src[ETH_ALEN]; | ||||||
| 	u16 eth_type; | 	u16 eth_type; | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ | ||||||
| struct xt_entry_target; | struct xt_entry_target; | ||||||
| 
 | 
 | ||||||
| struct tcf_ipt { | struct tcf_ipt { | ||||||
| 	struct tcf_common	common; | 	struct tc_action	common; | ||||||
| 	u32			tcfi_hook; | 	u32			tcfi_hook; | ||||||
| 	char			*tcfi_tname; | 	char			*tcfi_tname; | ||||||
| 	struct xt_entry_target	*tcfi_t; | 	struct xt_entry_target	*tcfi_t; | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ | ||||||
| #include <linux/tc_act/tc_mirred.h> | #include <linux/tc_act/tc_mirred.h> | ||||||
| 
 | 
 | ||||||
| struct tcf_mirred { | struct tcf_mirred { | ||||||
| 	struct tcf_common	common; | 	struct tc_action	common; | ||||||
| 	int			tcfm_eaction; | 	int			tcfm_eaction; | ||||||
| 	int			tcfm_ifindex; | 	int			tcfm_ifindex; | ||||||
| 	int			tcfm_ok_push; | 	int			tcfm_ok_push; | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ | ||||||
| #include <net/act_api.h> | #include <net/act_api.h> | ||||||
| 
 | 
 | ||||||
| struct tcf_nat { | struct tcf_nat { | ||||||
| 	struct tcf_common common; | 	struct tc_action common; | ||||||
| 
 | 
 | ||||||
| 	__be32 old_addr; | 	__be32 old_addr; | ||||||
| 	__be32 new_addr; | 	__be32 new_addr; | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ | ||||||
| #include <net/act_api.h> | #include <net/act_api.h> | ||||||
| 
 | 
 | ||||||
| struct tcf_pedit { | struct tcf_pedit { | ||||||
| 	struct tcf_common	common; | 	struct tc_action	common; | ||||||
| 	unsigned char		tcfp_nkeys; | 	unsigned char		tcfp_nkeys; | ||||||
| 	unsigned char		tcfp_flags; | 	unsigned char		tcfp_flags; | ||||||
| 	struct tc_pedit_key	*tcfp_keys; | 	struct tc_pedit_key	*tcfp_keys; | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ | ||||||
| #include <linux/tc_act/tc_skbedit.h> | #include <linux/tc_act/tc_skbedit.h> | ||||||
| 
 | 
 | ||||||
| struct tcf_skbedit { | struct tcf_skbedit { | ||||||
| 	struct tcf_common	common; | 	struct tc_action	common; | ||||||
| 	u32		flags; | 	u32		flags; | ||||||
| 	u32		priority; | 	u32		priority; | ||||||
| 	u32		mark; | 	u32		mark; | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ | ||||||
| #define VLAN_F_PUSH		0x2 | #define VLAN_F_PUSH		0x2 | ||||||
| 
 | 
 | ||||||
| struct tcf_vlan { | struct tcf_vlan { | ||||||
| 	struct tcf_common	common; | 	struct tc_action	common; | ||||||
| 	int			tcfv_action; | 	int			tcfv_action; | ||||||
| 	u16			tcfv_push_vid; | 	u16			tcfv_push_vid; | ||||||
| 	__be16			tcfv_push_proto; | 	__be16			tcfv_push_proto; | ||||||
|  |  | ||||||
|  | @ -29,46 +29,43 @@ | ||||||
| 
 | 
 | ||||||
| static void free_tcf(struct rcu_head *head) | static void free_tcf(struct rcu_head *head) | ||||||
| { | { | ||||||
| 	struct tcf_common *p = container_of(head, struct tcf_common, tcfc_rcu); | 	struct tc_action *p = container_of(head, struct tc_action, tcfa_rcu); | ||||||
| 
 | 
 | ||||||
| 	free_percpu(p->cpu_bstats); | 	free_percpu(p->cpu_bstats); | ||||||
| 	free_percpu(p->cpu_qstats); | 	free_percpu(p->cpu_qstats); | ||||||
| 	kfree(p); | 	kfree(p); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void tcf_hash_destroy(struct tcf_hashinfo *hinfo, struct tc_action *a) | static void tcf_hash_destroy(struct tcf_hashinfo *hinfo, struct tc_action *p) | ||||||
| { | { | ||||||
| 	struct tcf_common *p = (struct tcf_common *)a; |  | ||||||
| 
 |  | ||||||
| 	spin_lock_bh(&hinfo->lock); | 	spin_lock_bh(&hinfo->lock); | ||||||
| 	hlist_del(&p->tcfc_head); | 	hlist_del(&p->tcfa_head); | ||||||
| 	spin_unlock_bh(&hinfo->lock); | 	spin_unlock_bh(&hinfo->lock); | ||||||
| 	gen_kill_estimator(&p->tcfc_bstats, | 	gen_kill_estimator(&p->tcfa_bstats, | ||||||
| 			   &p->tcfc_rate_est); | 			   &p->tcfa_rate_est); | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * gen_estimator est_timer() might access p->tcfc_lock | 	 * gen_estimator est_timer() might access p->tcfa_lock | ||||||
| 	 * or bstats, wait a RCU grace period before freeing p | 	 * or bstats, wait a RCU grace period before freeing p | ||||||
| 	 */ | 	 */ | ||||||
| 	call_rcu(&p->tcfc_rcu, free_tcf); | 	call_rcu(&p->tcfa_rcu, free_tcf); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int __tcf_hash_release(struct tc_action *a, bool bind, bool strict) | int __tcf_hash_release(struct tc_action *p, bool bind, bool strict) | ||||||
| { | { | ||||||
| 	struct tcf_common *p = (struct tcf_common *)a; |  | ||||||
| 	int ret = 0; | 	int ret = 0; | ||||||
| 
 | 
 | ||||||
| 	if (p) { | 	if (p) { | ||||||
| 		if (bind) | 		if (bind) | ||||||
| 			p->tcfc_bindcnt--; | 			p->tcfa_bindcnt--; | ||||||
| 		else if (strict && p->tcfc_bindcnt > 0) | 		else if (strict && p->tcfa_bindcnt > 0) | ||||||
| 			return -EPERM; | 			return -EPERM; | ||||||
| 
 | 
 | ||||||
| 		p->tcfc_refcnt--; | 		p->tcfa_refcnt--; | ||||||
| 		if (p->tcfc_bindcnt <= 0 && p->tcfc_refcnt <= 0) { | 		if (p->tcfa_bindcnt <= 0 && p->tcfa_refcnt <= 0) { | ||||||
| 			if (a->ops->cleanup) | 			if (p->ops->cleanup) | ||||||
| 				a->ops->cleanup(a, bind); | 				p->ops->cleanup(p, bind); | ||||||
| 			list_del(&a->list); | 			list_del(&p->list); | ||||||
| 			tcf_hash_destroy(a->hinfo, a); | 			tcf_hash_destroy(p->hinfo, p); | ||||||
| 			ret = ACT_P_DELETED; | 			ret = ACT_P_DELETED; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -89,11 +86,11 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb, | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < (hinfo->hmask + 1); i++) { | 	for (i = 0; i < (hinfo->hmask + 1); i++) { | ||||||
| 		struct hlist_head *head; | 		struct hlist_head *head; | ||||||
| 		struct tcf_common *p; | 		struct tc_action *p; | ||||||
| 
 | 
 | ||||||
| 		head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; | 		head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; | ||||||
| 
 | 
 | ||||||
| 		hlist_for_each_entry_rcu(p, head, tcfc_head) { | 		hlist_for_each_entry_rcu(p, head, tcfa_head) { | ||||||
| 			index++; | 			index++; | ||||||
| 			if (index < s_i) | 			if (index < s_i) | ||||||
| 				continue; | 				continue; | ||||||
|  | @ -101,7 +98,7 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb, | ||||||
| 			nest = nla_nest_start(skb, n_i); | 			nest = nla_nest_start(skb, n_i); | ||||||
| 			if (nest == NULL) | 			if (nest == NULL) | ||||||
| 				goto nla_put_failure; | 				goto nla_put_failure; | ||||||
| 			err = tcf_action_dump_1(skb, (struct tc_action *)p, 0, 0); | 			err = tcf_action_dump_1(skb, p, 0, 0); | ||||||
| 			if (err < 0) { | 			if (err < 0) { | ||||||
| 				index--; | 				index--; | ||||||
| 				nlmsg_trim(skb, nest); | 				nlmsg_trim(skb, nest); | ||||||
|  | @ -139,13 +136,13 @@ static int tcf_del_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb, | ||||||
| 	for (i = 0; i < (hinfo->hmask + 1); i++) { | 	for (i = 0; i < (hinfo->hmask + 1); i++) { | ||||||
| 		struct hlist_head *head; | 		struct hlist_head *head; | ||||||
| 		struct hlist_node *n; | 		struct hlist_node *n; | ||||||
| 		struct tcf_common *p; | 		struct tc_action *p; | ||||||
| 
 | 
 | ||||||
| 		head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; | 		head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; | ||||||
| 		hlist_for_each_entry_safe(p, n, head, tcfc_head) { | 		hlist_for_each_entry_safe(p, n, head, tcfa_head) { | ||||||
| 			ret = __tcf_hash_release((struct tc_action *)p, false, true); | 			ret = __tcf_hash_release(p, false, true); | ||||||
| 			if (ret == ACT_P_DELETED) { | 			if (ret == ACT_P_DELETED) { | ||||||
| 				module_put(p->tcfc_act.ops->owner); | 				module_put(p->ops->owner); | ||||||
| 				n_i++; | 				n_i++; | ||||||
| 			} else if (ret < 0) | 			} else if (ret < 0) | ||||||
| 				goto nla_put_failure; | 				goto nla_put_failure; | ||||||
|  | @ -178,15 +175,15 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb, | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(tcf_generic_walker); | EXPORT_SYMBOL(tcf_generic_walker); | ||||||
| 
 | 
 | ||||||
| static struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo) | static struct tc_action *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo) | ||||||
| { | { | ||||||
| 	struct tcf_common *p = NULL; | 	struct tc_action *p = NULL; | ||||||
| 	struct hlist_head *head; | 	struct hlist_head *head; | ||||||
| 
 | 
 | ||||||
| 	spin_lock_bh(&hinfo->lock); | 	spin_lock_bh(&hinfo->lock); | ||||||
| 	head = &hinfo->htab[tcf_hash(index, hinfo->hmask)]; | 	head = &hinfo->htab[tcf_hash(index, hinfo->hmask)]; | ||||||
| 	hlist_for_each_entry_rcu(p, head, tcfc_head) | 	hlist_for_each_entry_rcu(p, head, tcfa_head) | ||||||
| 		if (p->tcfc_index == index) | 		if (p->tcfa_index == index) | ||||||
| 			break; | 			break; | ||||||
| 	spin_unlock_bh(&hinfo->lock); | 	spin_unlock_bh(&hinfo->lock); | ||||||
| 
 | 
 | ||||||
|  | @ -211,10 +208,10 @@ EXPORT_SYMBOL(tcf_hash_new_index); | ||||||
| int tcf_hash_search(struct tc_action_net *tn, struct tc_action **a, u32 index) | int tcf_hash_search(struct tc_action_net *tn, struct tc_action **a, u32 index) | ||||||
| { | { | ||||||
| 	struct tcf_hashinfo *hinfo = tn->hinfo; | 	struct tcf_hashinfo *hinfo = tn->hinfo; | ||||||
| 	struct tcf_common *p = tcf_hash_lookup(index, hinfo); | 	struct tc_action *p = tcf_hash_lookup(index, hinfo); | ||||||
| 
 | 
 | ||||||
| 	if (p) { | 	if (p) { | ||||||
| 		*a = &p->tcfc_act; | 		*a = p; | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
|  | @ -225,12 +222,13 @@ bool tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action **a, | ||||||
| 		    int bind) | 		    int bind) | ||||||
| { | { | ||||||
| 	struct tcf_hashinfo *hinfo = tn->hinfo; | 	struct tcf_hashinfo *hinfo = tn->hinfo; | ||||||
| 	struct tcf_common *p = NULL; | 	struct tc_action *p = NULL; | ||||||
|  | 
 | ||||||
| 	if (index && (p = tcf_hash_lookup(index, hinfo)) != NULL) { | 	if (index && (p = tcf_hash_lookup(index, hinfo)) != NULL) { | ||||||
| 		if (bind) | 		if (bind) | ||||||
| 			p->tcfc_bindcnt++; | 			p->tcfa_bindcnt++; | ||||||
| 		p->tcfc_refcnt++; | 		p->tcfa_refcnt++; | ||||||
| 		*a = &p->tcfc_act; | 		*a = p; | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 	return false; | 	return false; | ||||||
|  | @ -239,11 +237,10 @@ EXPORT_SYMBOL(tcf_hash_check); | ||||||
| 
 | 
 | ||||||
| void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est) | void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est) | ||||||
| { | { | ||||||
| 	struct tcf_common *pc = (struct tcf_common *)a; |  | ||||||
| 	if (est) | 	if (est) | ||||||
| 		gen_kill_estimator(&pc->tcfc_bstats, | 		gen_kill_estimator(&a->tcfa_bstats, | ||||||
| 				   &pc->tcfc_rate_est); | 				   &a->tcfa_rate_est); | ||||||
| 	call_rcu(&pc->tcfc_rcu, free_tcf); | 	call_rcu(&a->tcfa_rcu, free_tcf); | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(tcf_hash_cleanup); | EXPORT_SYMBOL(tcf_hash_cleanup); | ||||||
| 
 | 
 | ||||||
|  | @ -251,15 +248,15 @@ int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est, | ||||||
| 		    struct tc_action **a, const struct tc_action_ops *ops, | 		    struct tc_action **a, const struct tc_action_ops *ops, | ||||||
| 		    int bind, bool cpustats) | 		    int bind, bool cpustats) | ||||||
| { | { | ||||||
| 	struct tcf_common *p = kzalloc(ops->size, GFP_KERNEL); | 	struct tc_action *p = kzalloc(ops->size, GFP_KERNEL); | ||||||
| 	struct tcf_hashinfo *hinfo = tn->hinfo; | 	struct tcf_hashinfo *hinfo = tn->hinfo; | ||||||
| 	int err = -ENOMEM; | 	int err = -ENOMEM; | ||||||
| 
 | 
 | ||||||
| 	if (unlikely(!p)) | 	if (unlikely(!p)) | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 	p->tcfc_refcnt = 1; | 	p->tcfa_refcnt = 1; | ||||||
| 	if (bind) | 	if (bind) | ||||||
| 		p->tcfc_bindcnt = 1; | 		p->tcfa_bindcnt = 1; | ||||||
| 
 | 
 | ||||||
| 	if (cpustats) { | 	if (cpustats) { | ||||||
| 		p->cpu_bstats = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu); | 		p->cpu_bstats = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu); | ||||||
|  | @ -275,38 +272,37 @@ int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est, | ||||||
| 			goto err1; | 			goto err1; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	spin_lock_init(&p->tcfc_lock); | 	spin_lock_init(&p->tcfa_lock); | ||||||
| 	INIT_HLIST_NODE(&p->tcfc_head); | 	INIT_HLIST_NODE(&p->tcfa_head); | ||||||
| 	p->tcfc_index = index ? index : tcf_hash_new_index(tn); | 	p->tcfa_index = index ? index : tcf_hash_new_index(tn); | ||||||
| 	p->tcfc_tm.install = jiffies; | 	p->tcfa_tm.install = jiffies; | ||||||
| 	p->tcfc_tm.lastuse = jiffies; | 	p->tcfa_tm.lastuse = jiffies; | ||||||
| 	p->tcfc_tm.firstuse = 0; | 	p->tcfa_tm.firstuse = 0; | ||||||
| 	if (est) { | 	if (est) { | ||||||
| 		err = gen_new_estimator(&p->tcfc_bstats, p->cpu_bstats, | 		err = gen_new_estimator(&p->tcfa_bstats, p->cpu_bstats, | ||||||
| 					&p->tcfc_rate_est, | 					&p->tcfa_rate_est, | ||||||
| 					&p->tcfc_lock, NULL, est); | 					&p->tcfa_lock, NULL, est); | ||||||
| 		if (err) { | 		if (err) { | ||||||
| 			free_percpu(p->cpu_qstats); | 			free_percpu(p->cpu_qstats); | ||||||
| 			goto err2; | 			goto err2; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	p->tcfc_act.hinfo = hinfo; | 	p->hinfo = hinfo; | ||||||
| 	p->tcfc_act.ops = ops; | 	p->ops = ops; | ||||||
| 	INIT_LIST_HEAD(&p->tcfc_act.list); | 	INIT_LIST_HEAD(&p->list); | ||||||
| 	*a = &p->tcfc_act; | 	*a = p; | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(tcf_hash_create); | EXPORT_SYMBOL(tcf_hash_create); | ||||||
| 
 | 
 | ||||||
| void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a) | void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a) | ||||||
| { | { | ||||||
| 	struct tcf_common *p = (struct tcf_common *)a; |  | ||||||
| 	struct tcf_hashinfo *hinfo = tn->hinfo; | 	struct tcf_hashinfo *hinfo = tn->hinfo; | ||||||
| 	unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask); | 	unsigned int h = tcf_hash(a->tcfa_index, hinfo->hmask); | ||||||
| 
 | 
 | ||||||
| 	spin_lock_bh(&hinfo->lock); | 	spin_lock_bh(&hinfo->lock); | ||||||
| 	hlist_add_head(&p->tcfc_head, &hinfo->htab[h]); | 	hlist_add_head(&a->tcfa_head, &hinfo->htab[h]); | ||||||
| 	spin_unlock_bh(&hinfo->lock); | 	spin_unlock_bh(&hinfo->lock); | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(tcf_hash_insert); | EXPORT_SYMBOL(tcf_hash_insert); | ||||||
|  | @ -317,13 +313,13 @@ void tcf_hashinfo_destroy(const struct tc_action_ops *ops, | ||||||
| 	int i; | 	int i; | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < hinfo->hmask + 1; i++) { | 	for (i = 0; i < hinfo->hmask + 1; i++) { | ||||||
| 		struct tcf_common *p; | 		struct tc_action *p; | ||||||
| 		struct hlist_node *n; | 		struct hlist_node *n; | ||||||
| 
 | 
 | ||||||
| 		hlist_for_each_entry_safe(p, n, &hinfo->htab[i], tcfc_head) { | 		hlist_for_each_entry_safe(p, n, &hinfo->htab[i], tcfa_head) { | ||||||
| 			int ret; | 			int ret; | ||||||
| 
 | 
 | ||||||
| 			ret = __tcf_hash_release((struct tc_action *)p, false, true); | 			ret = __tcf_hash_release(p, false, true); | ||||||
| 			if (ret == ACT_P_DELETED) | 			if (ret == ACT_P_DELETED) | ||||||
| 				module_put(ops->owner); | 				module_put(ops->owner); | ||||||
| 			else if (ret < 0) | 			else if (ret < 0) | ||||||
|  | @ -625,12 +621,11 @@ int tcf_action_init(struct net *net, struct nlattr *nla, | ||||||
| 	return err; | 	return err; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a, | int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *p, | ||||||
| 			  int compat_mode) | 			  int compat_mode) | ||||||
| { | { | ||||||
| 	int err = 0; | 	int err = 0; | ||||||
| 	struct gnet_dump d; | 	struct gnet_dump d; | ||||||
| 	struct tcf_common *p = (struct tcf_common *)a; |  | ||||||
| 
 | 
 | ||||||
| 	if (p == NULL) | 	if (p == NULL) | ||||||
| 		goto errout; | 		goto errout; | ||||||
|  | @ -639,27 +634,27 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a, | ||||||
| 	 * to add additional backward compatibility statistic TLVs. | 	 * to add additional backward compatibility statistic TLVs. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (compat_mode) { | 	if (compat_mode) { | ||||||
| 		if (a->type == TCA_OLD_COMPAT) | 		if (p->type == TCA_OLD_COMPAT) | ||||||
| 			err = gnet_stats_start_copy_compat(skb, 0, | 			err = gnet_stats_start_copy_compat(skb, 0, | ||||||
| 							   TCA_STATS, | 							   TCA_STATS, | ||||||
| 							   TCA_XSTATS, | 							   TCA_XSTATS, | ||||||
| 							   &p->tcfc_lock, &d, | 							   &p->tcfa_lock, &d, | ||||||
| 							   TCA_PAD); | 							   TCA_PAD); | ||||||
| 		else | 		else | ||||||
| 			return 0; | 			return 0; | ||||||
| 	} else | 	} else | ||||||
| 		err = gnet_stats_start_copy(skb, TCA_ACT_STATS, | 		err = gnet_stats_start_copy(skb, TCA_ACT_STATS, | ||||||
| 					    &p->tcfc_lock, &d, TCA_ACT_PAD); | 					    &p->tcfa_lock, &d, TCA_ACT_PAD); | ||||||
| 
 | 
 | ||||||
| 	if (err < 0) | 	if (err < 0) | ||||||
| 		goto errout; | 		goto errout; | ||||||
| 
 | 
 | ||||||
| 	if (gnet_stats_copy_basic(NULL, &d, p->cpu_bstats, &p->tcfc_bstats) < 0 || | 	if (gnet_stats_copy_basic(NULL, &d, p->cpu_bstats, &p->tcfa_bstats) < 0 || | ||||||
| 	    gnet_stats_copy_rate_est(&d, &p->tcfc_bstats, | 	    gnet_stats_copy_rate_est(&d, &p->tcfa_bstats, | ||||||
| 				     &p->tcfc_rate_est) < 0 || | 				     &p->tcfa_rate_est) < 0 || | ||||||
| 	    gnet_stats_copy_queue(&d, p->cpu_qstats, | 	    gnet_stats_copy_queue(&d, p->cpu_qstats, | ||||||
| 				  &p->tcfc_qstats, | 				  &p->tcfa_qstats, | ||||||
| 				  p->tcfc_qstats.qlen) < 0) | 				  p->tcfa_qstats.qlen) < 0) | ||||||
| 		goto errout; | 		goto errout; | ||||||
| 
 | 
 | ||||||
| 	if (gnet_stats_finish_copy(&d) < 0) | 	if (gnet_stats_finish_copy(&d) < 0) | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ | ||||||
| #include <net/netlink.h> | #include <net/netlink.h> | ||||||
| 
 | 
 | ||||||
| struct tcf_police { | struct tcf_police { | ||||||
| 	struct tcf_common	common; | 	struct tc_action	common; | ||||||
| 	int			tcfp_result; | 	int			tcfp_result; | ||||||
| 	u32			tcfp_ewma_rate; | 	u32			tcfp_ewma_rate; | ||||||
| 	s64			tcfp_burst; | 	s64			tcfp_burst; | ||||||
|  | @ -73,11 +73,11 @@ static int tcf_act_police_walker(struct net *net, struct sk_buff *skb, | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < (POL_TAB_MASK + 1); i++) { | 	for (i = 0; i < (POL_TAB_MASK + 1); i++) { | ||||||
| 		struct hlist_head *head; | 		struct hlist_head *head; | ||||||
| 		struct tcf_common *p; | 		struct tc_action *p; | ||||||
| 
 | 
 | ||||||
| 		head = &hinfo->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) { | 		hlist_for_each_entry_rcu(p, head, tcfa_head) { | ||||||
| 			index++; | 			index++; | ||||||
| 			if (index < s_i) | 			if (index < s_i) | ||||||
| 				continue; | 				continue; | ||||||
|  | @ -85,9 +85,9 @@ static int tcf_act_police_walker(struct net *net, struct sk_buff *skb, | ||||||
| 			if (nest == NULL) | 			if (nest == NULL) | ||||||
| 				goto nla_put_failure; | 				goto nla_put_failure; | ||||||
| 			if (type == RTM_DELACTION) | 			if (type == RTM_DELACTION) | ||||||
| 				err = tcf_action_dump_1(skb, (struct tc_action *)p, 0, 1); | 				err = tcf_action_dump_1(skb, p, 0, 1); | ||||||
| 			else | 			else | ||||||
| 				err = tcf_action_dump_1(skb, (struct tc_action *)p, 0, 0); | 				err = tcf_action_dump_1(skb, p, 0, 0); | ||||||
| 			if (err < 0) { | 			if (err < 0) { | ||||||
| 				index--; | 				index--; | ||||||
| 				nla_nest_cancel(skb, nest); | 				nla_nest_cancel(skb, nest); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 WANG Cong
						WANG Cong