diff options
author | Takashi Iwai <tiwai@suse.de> | 2017-07-03 20:51:42 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2017-07-03 20:51:42 +0300 |
commit | 818a23e3882b1bf65d1719e407be04716e69a4d5 (patch) | |
tree | 6e4267b570541f779e7d85c11eb14312fa86fbb1 /net/core/fib_rules.c | |
parent | a178232ddab55048e347b43b697bfa5013ef819e (diff) | |
parent | b821d298f8864dc3c3d42643812df43289159507 (diff) | |
download | linux-818a23e3882b1bf65d1719e407be04716e69a4d5.tar.xz |
Merge tag 'asoc-v4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v4.13
The big news with this release is the of-graph card, this provides a
replacement for simple-card that is much more flexibile and scalable,
allowing many more systems to use a generic sound card than was possible
before:
- The of-graph card, finally merged after a long and dedicated effort
by Morimoto-san.
- New widget types intended mainly for use with DSPs.
- New drivers for Allwinner V3s SoCs, Ensonic ES8316, several classes
of x86 machine, Rockchip PDM controllers, STM32 I2S and S/PDIF
controllers and ZTE AUD96P22 CODECs.
Diffstat (limited to 'net/core/fib_rules.c')
-rw-r--r-- | net/core/fib_rules.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index f21c4d3aeae0..3bba291c6c32 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -568,7 +568,7 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh, struct net *net = sock_net(skb->sk); struct fib_rule_hdr *frh = nlmsg_data(nlh); struct fib_rules_ops *ops = NULL; - struct fib_rule *rule, *tmp; + struct fib_rule *rule, *r; struct nlattr *tb[FRA_MAX+1]; struct fib_kuid_range range; int err = -EINVAL; @@ -668,16 +668,23 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh, /* * Check if this rule is a target to any of them. If so, + * adjust to the next one with the same preference or * disable them. As this operation is eventually very - * expensive, it is only performed if goto rules have - * actually been added. + * expensive, it is only performed if goto rules, except + * current if it is goto rule, have actually been added. */ if (ops->nr_goto_rules > 0) { - list_for_each_entry(tmp, &ops->rules_list, list) { - if (rtnl_dereference(tmp->ctarget) == rule) { - RCU_INIT_POINTER(tmp->ctarget, NULL); + struct fib_rule *n; + + n = list_next_entry(rule, list); + if (&n->list == &ops->rules_list || n->pref != rule->pref) + n = NULL; + list_for_each_entry(r, &ops->rules_list, list) { + if (rtnl_dereference(r->ctarget) != rule) + continue; + rcu_assign_pointer(r->ctarget, n); + if (!n) ops->unresolved_rules++; - } } } |