diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 12 | ||||
-rw-r--r-- | net/core/dst.c | 2 | ||||
-rw-r--r-- | net/core/fib_rules.c | 1 | ||||
-rw-r--r-- | net/core/filter.c | 4 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 9 |
5 files changed, 23 insertions, 5 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index bcb05cb799c1..c7e305d13b71 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1308,6 +1308,13 @@ void dev_disable_lro(struct net_device *dev) { u32 flags; + /* + * If we're trying to disable lro on a vlan device + * use the underlying physical device instead + */ + if (is_vlan_dev(dev)) + dev = vlan_dev_real_dev(dev); + if (dev->ethtool_ops && dev->ethtool_ops->get_flags) flags = dev->ethtool_ops->get_flags(dev); else @@ -5954,7 +5961,10 @@ EXPORT_SYMBOL(free_netdev); void synchronize_net(void) { might_sleep(); - synchronize_rcu(); + if (rtnl_is_locked()) + synchronize_rcu_expedited(); + else + synchronize_rcu(); } EXPORT_SYMBOL(synchronize_net); diff --git a/net/core/dst.c b/net/core/dst.c index 81a4fa1c95ed..9ccca038444f 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -315,7 +315,7 @@ void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old) { unsigned long prev, new; - new = (unsigned long) dst_default_metrics; + new = ((unsigned long) dst_default_metrics) | DST_METRICS_READ_ONLY; prev = cmpxchg(&dst->_metrics, old, new); if (prev == old) kfree(__DST_METRICS_PTR(old)); diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 3911586e12e4..008dc70b064b 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -602,6 +602,7 @@ static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb, skip: idx++; } + rcu_read_unlock(); cb->args[1] = idx; rules_ops_put(ops); diff --git a/net/core/filter.c b/net/core/filter.c index 0eb8c4466eaa..0e3622f1dcb1 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -350,7 +350,9 @@ load_b: continue; } default: - WARN_ON(1); + WARN_RATELIMIT(1, "Unknown code:%u jt:%u tf:%u k:%u\n", + fentry->code, fentry->jt, + fentry->jf, fentry->k); return 0; } } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index d1644e317e70..2d56cb9b0b94 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -850,6 +850,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, struct nlattr *attr, *af_spec; struct rtnl_af_ops *af_ops; + ASSERT_RTNL(); nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); if (nlh == NULL) return -EMSGSIZE; @@ -1876,6 +1877,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) int min_len; int family; int type; + int err; type = nlh->nlmsg_type; if (type > RTM_MAX) @@ -1902,8 +1904,11 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (dumpit == NULL) return -EOPNOTSUPP; + __rtnl_unlock(); rtnl = net->rtnl; - return netlink_dump_start(rtnl, skb, nlh, dumpit, NULL); + err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL); + rtnl_lock(); + return err; } memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *))); @@ -1975,7 +1980,7 @@ static int __net_init rtnetlink_net_init(struct net *net) { struct sock *sk; sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX, - rtnetlink_rcv, NULL, THIS_MODULE); + rtnetlink_rcv, &rtnl_mutex, THIS_MODULE); if (!sk) return -ENOMEM; net->rtnl = sk; |