ipv6: do not abuse GFP_ATOMIC in inet6_netconf_notify_devconf()
commit 927265bc6cd6374c9bafc43408ece4e92311b149 upstream. All inet6_netconf_notify_devconf() callers are in process context, so we can use GFP_KERNEL allocations if we take care of not holding a rwlock while not needed in ip6mr (we hold RTNL there) Fixes:d67b8c616b
("netconf: advertise mc_forwarding status") Fixes:f3a1bfb11c
("rtnl/ipv6: use netconf msg to advertise forwarding status") Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
ec2bb1ea9e
commit
20cb4e9180
2 changed files with 9 additions and 8 deletions
|
@ -540,7 +540,7 @@ void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
int err = -ENOBUFS;
|
int err = -ENOBUFS;
|
||||||
|
|
||||||
skb = nlmsg_new(inet6_netconf_msgsize_devconf(type), GFP_ATOMIC);
|
skb = nlmsg_new(inet6_netconf_msgsize_devconf(type), GFP_KERNEL);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
||||||
|
@ -552,7 +552,7 @@ void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
rtnl_notify(skb, net, 0, RTNLGRP_IPV6_NETCONF, NULL, GFP_ATOMIC);
|
rtnl_notify(skb, net, 0, RTNLGRP_IPV6_NETCONF, NULL, GFP_KERNEL);
|
||||||
return;
|
return;
|
||||||
errout:
|
errout:
|
||||||
rtnl_set_sk_err(net, RTNLGRP_IPV6_NETCONF, err);
|
rtnl_set_sk_err(net, RTNLGRP_IPV6_NETCONF, err);
|
||||||
|
|
|
@ -1594,14 +1594,15 @@ static int ip6mr_sk_init(struct mr6_table *mrt, struct sock *sk)
|
||||||
if (likely(mrt->mroute6_sk == NULL)) {
|
if (likely(mrt->mroute6_sk == NULL)) {
|
||||||
mrt->mroute6_sk = sk;
|
mrt->mroute6_sk = sk;
|
||||||
net->ipv6.devconf_all->mc_forwarding++;
|
net->ipv6.devconf_all->mc_forwarding++;
|
||||||
|
} else {
|
||||||
|
err = -EADDRINUSE;
|
||||||
|
}
|
||||||
|
write_unlock_bh(&mrt_lock);
|
||||||
|
|
||||||
|
if (!err)
|
||||||
inet6_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
|
inet6_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
|
||||||
NETCONFA_IFINDEX_ALL,
|
NETCONFA_IFINDEX_ALL,
|
||||||
net->ipv6.devconf_all);
|
net->ipv6.devconf_all);
|
||||||
}
|
|
||||||
else
|
|
||||||
err = -EADDRINUSE;
|
|
||||||
write_unlock_bh(&mrt_lock);
|
|
||||||
|
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -1619,11 +1620,11 @@ int ip6mr_sk_done(struct sock *sk)
|
||||||
write_lock_bh(&mrt_lock);
|
write_lock_bh(&mrt_lock);
|
||||||
mrt->mroute6_sk = NULL;
|
mrt->mroute6_sk = NULL;
|
||||||
net->ipv6.devconf_all->mc_forwarding--;
|
net->ipv6.devconf_all->mc_forwarding--;
|
||||||
|
write_unlock_bh(&mrt_lock);
|
||||||
inet6_netconf_notify_devconf(net,
|
inet6_netconf_notify_devconf(net,
|
||||||
NETCONFA_MC_FORWARDING,
|
NETCONFA_MC_FORWARDING,
|
||||||
NETCONFA_IFINDEX_ALL,
|
NETCONFA_IFINDEX_ALL,
|
||||||
net->ipv6.devconf_all);
|
net->ipv6.devconf_all);
|
||||||
write_unlock_bh(&mrt_lock);
|
|
||||||
|
|
||||||
mroute_clean_tables(mrt, false);
|
mroute_clean_tables(mrt, false);
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue