diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c index b7fa969..b52deb4 100644 --- a/net/sched/act_ife.c +++ b/net/sched/act_ife.c @@ -239,8 +239,7 @@ static int ife_validate_metatype(struct tcf_meta_ops *ops, void *val, int len) return ret; } -/* called when adding new meta information - * under ife->tcf_lock +/* called to find new metadata ops. Possibly load it as a module. */ static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid, void *val, int len) @@ -251,11 +250,9 @@ static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid, if (!ops) { ret = -ENOENT; #ifdef CONFIG_MODULES - spin_unlock_bh(&ife->tcf_lock); rtnl_unlock(); request_module("ifemeta%u", metaid); rtnl_lock(); - spin_lock_bh(&ife->tcf_lock); ops = find_ife_oplist(metaid); #endif } @@ -272,7 +269,6 @@ static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid, } /* called when adding new meta information - * under ife->tcf_lock */ static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, int len) @@ -302,7 +298,9 @@ static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, } } + spin_lock_bh(&ife->tcf_lock); list_add_tail(&mi->metalist, &ife->metalist); + spin_unlock_bh(&ife->tcf_lock); return ret; } @@ -357,7 +355,6 @@ out_nlmsg_trim: return -1; } -/* under ife->tcf_lock */ static void _tcf_ife_cleanup(struct tc_action *a, int bind) { struct tcf_ife_info *ife = a->priv; @@ -385,7 +382,6 @@ static void tcf_ife_cleanup(struct tc_action *a, int bind) spin_unlock_bh(&ife->tcf_lock); } -/* under ife->tcf_lock */ static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb) { int len = 0; @@ -465,6 +461,8 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, } ife = to_ife(a); + if (exists) + spin_lock_bh(&ife->tcf_lock); ife->flags = parm->flags; if (parm->flags & IFE_ENCODE) { @@ -475,10 +473,9 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, saddr = nla_data(tb[TCA_IFE_SMAC]); } - spin_lock_bh(&ife->tcf_lock); ife->tcf_action = parm->action; - if (parm->flags & IFE_ENCODE) { + if (daddr) ether_addr_copy(ife->eth_dst, daddr); else @@ -492,6 +489,9 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, ife->eth_type = ife_type; } + if (exists) + spin_unlock_bh(&ife->tcf_lock); + if (ret == ACT_P_CREATED) INIT_LIST_HEAD(&ife->metalist); @@ -505,7 +505,6 @@ metadata_parse_err: if (ret == ACT_P_CREATED) _tcf_ife_cleanup(a, bind); - spin_unlock_bh(&ife->tcf_lock); return err; } @@ -524,13 +523,10 @@ metadata_parse_err: if (ret == ACT_P_CREATED) _tcf_ife_cleanup(a, bind); - spin_unlock_bh(&ife->tcf_lock); return err; } } - spin_unlock_bh(&ife->tcf_lock); - if (ret == ACT_P_CREATED) tcf_hash_insert(tn, a);