Merge branch 'linus' into locking/core, to fix up conflicts
Conflicts: mm/page_alloc.c Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -5556,7 +5556,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
|
||||
* our DAD process, so we don't need
|
||||
* to do it again
|
||||
*/
|
||||
if (!(ifp->rt->rt6i_node))
|
||||
if (!rcu_access_pointer(ifp->rt->rt6i_node))
|
||||
ip6_ins_rt(ifp->rt);
|
||||
if (ifp->idev->cnf.forwarding)
|
||||
addrconf_join_anycast(ifp);
|
||||
|
@@ -226,7 +226,7 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
|
||||
int tailen = esp->tailen;
|
||||
|
||||
if (!skb_cloned(skb)) {
|
||||
if (tailen <= skb_availroom(skb)) {
|
||||
if (tailen <= skb_tailroom(skb)) {
|
||||
nfrags = 1;
|
||||
trailer = skb;
|
||||
tail = skb_tail_pointer(trailer);
|
||||
@@ -260,8 +260,6 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
|
||||
|
||||
kunmap_atomic(vaddr);
|
||||
|
||||
spin_unlock_bh(&x->lock);
|
||||
|
||||
nfrags = skb_shinfo(skb)->nr_frags;
|
||||
|
||||
__skb_fill_page_desc(skb, nfrags, page, pfrag->offset,
|
||||
@@ -269,6 +267,9 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
|
||||
skb_shinfo(skb)->nr_frags = ++nfrags;
|
||||
|
||||
pfrag->offset = pfrag->offset + allocsize;
|
||||
|
||||
spin_unlock_bh(&x->lock);
|
||||
|
||||
nfrags++;
|
||||
|
||||
skb->len += tailen;
|
||||
@@ -345,7 +346,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
|
||||
(unsigned char *)esph - skb->data,
|
||||
assoclen + ivlen + esp->clen + alen);
|
||||
if (unlikely(err < 0))
|
||||
goto error;
|
||||
goto error_free;
|
||||
|
||||
if (!esp->inplace) {
|
||||
int allocsize;
|
||||
@@ -356,7 +357,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
|
||||
spin_lock_bh(&x->lock);
|
||||
if (unlikely(!skb_page_frag_refill(allocsize, pfrag, GFP_ATOMIC))) {
|
||||
spin_unlock_bh(&x->lock);
|
||||
goto error;
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
skb_shinfo(skb)->nr_frags = 1;
|
||||
@@ -373,7 +374,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
|
||||
(unsigned char *)esph - skb->data,
|
||||
assoclen + ivlen + esp->clen + alen);
|
||||
if (unlikely(err < 0))
|
||||
goto error;
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
if ((x->props.flags & XFRM_STATE_ESN))
|
||||
@@ -406,8 +407,9 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
|
||||
|
||||
if (sg != dsg)
|
||||
esp_ssg_unref(x, tmp);
|
||||
kfree(tmp);
|
||||
|
||||
error_free:
|
||||
kfree(tmp);
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
|
@@ -286,7 +286,7 @@ static int esp6_xmit(struct xfrm_state *x, struct sk_buff *skb, netdev_features
|
||||
esp.seqno = cpu_to_be64(xo->seq.low + ((u64)xo->seq.hi << 32));
|
||||
|
||||
err = esp6_output_tail(x, skb, &esp);
|
||||
if (err < 0)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
secpath_reset(skb);
|
||||
|
@@ -148,11 +148,23 @@ static struct fib6_node *node_alloc(void)
|
||||
return fn;
|
||||
}
|
||||
|
||||
static void node_free(struct fib6_node *fn)
|
||||
static void node_free_immediate(struct fib6_node *fn)
|
||||
{
|
||||
kmem_cache_free(fib6_node_kmem, fn);
|
||||
}
|
||||
|
||||
static void node_free_rcu(struct rcu_head *head)
|
||||
{
|
||||
struct fib6_node *fn = container_of(head, struct fib6_node, rcu);
|
||||
|
||||
kmem_cache_free(fib6_node_kmem, fn);
|
||||
}
|
||||
|
||||
static void node_free(struct fib6_node *fn)
|
||||
{
|
||||
call_rcu(&fn->rcu, node_free_rcu);
|
||||
}
|
||||
|
||||
static void rt6_free_pcpu(struct rt6_info *non_pcpu_rt)
|
||||
{
|
||||
int cpu;
|
||||
@@ -601,9 +613,9 @@ insert_above:
|
||||
|
||||
if (!in || !ln) {
|
||||
if (in)
|
||||
node_free(in);
|
||||
node_free_immediate(in);
|
||||
if (ln)
|
||||
node_free(ln);
|
||||
node_free_immediate(ln);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
@@ -877,7 +889,7 @@ add:
|
||||
|
||||
rt->dst.rt6_next = iter;
|
||||
*ins = rt;
|
||||
rt->rt6i_node = fn;
|
||||
rcu_assign_pointer(rt->rt6i_node, fn);
|
||||
atomic_inc(&rt->rt6i_ref);
|
||||
if (!info->skip_notify)
|
||||
inet6_rt_notify(RTM_NEWROUTE, rt, info, nlflags);
|
||||
@@ -903,7 +915,7 @@ add:
|
||||
return err;
|
||||
|
||||
*ins = rt;
|
||||
rt->rt6i_node = fn;
|
||||
rcu_assign_pointer(rt->rt6i_node, fn);
|
||||
rt->dst.rt6_next = iter->dst.rt6_next;
|
||||
atomic_inc(&rt->rt6i_ref);
|
||||
if (!info->skip_notify)
|
||||
@@ -1038,7 +1050,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
|
||||
root, and then (in failure) stale node
|
||||
in main tree.
|
||||
*/
|
||||
node_free(sfn);
|
||||
node_free_immediate(sfn);
|
||||
err = PTR_ERR(sn);
|
||||
goto failure;
|
||||
}
|
||||
@@ -1468,8 +1480,9 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
|
||||
|
||||
int fib6_del(struct rt6_info *rt, struct nl_info *info)
|
||||
{
|
||||
struct fib6_node *fn = rcu_dereference_protected(rt->rt6i_node,
|
||||
lockdep_is_held(&rt->rt6i_table->tb6_lock));
|
||||
struct net *net = info->nl_net;
|
||||
struct fib6_node *fn = rt->rt6i_node;
|
||||
struct rt6_info **rtp;
|
||||
|
||||
#if RT6_DEBUG >= 2
|
||||
@@ -1658,7 +1671,9 @@ static int fib6_clean_node(struct fib6_walker *w)
|
||||
if (res) {
|
||||
#if RT6_DEBUG >= 2
|
||||
pr_debug("%s: del failed: rt=%p@%p err=%d\n",
|
||||
__func__, rt, rt->rt6i_node, res);
|
||||
__func__, rt,
|
||||
rcu_access_pointer(rt->rt6i_node),
|
||||
res);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
@@ -1780,8 +1795,10 @@ static int fib6_age(struct rt6_info *rt, void *arg)
|
||||
}
|
||||
gc_args->more++;
|
||||
} else if (rt->rt6i_flags & RTF_CACHE) {
|
||||
if (time_after_eq(now, rt->dst.lastuse + gc_args->timeout))
|
||||
rt->dst.obsolete = DST_OBSOLETE_KILL;
|
||||
if (atomic_read(&rt->dst.__refcnt) == 1 &&
|
||||
time_after_eq(now, rt->dst.lastuse + gc_args->timeout)) {
|
||||
rt->dst.obsolete == DST_OBSOLETE_KILL) {
|
||||
RT6_TRACE("aging clone %p\n", rt);
|
||||
return -1;
|
||||
} else if (rt->rt6i_flags & RTF_GATEWAY) {
|
||||
|
@@ -242,7 +242,6 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
pktopt = xchg(&np->pktoptions, NULL);
|
||||
kfree_skb(pktopt);
|
||||
|
||||
sk->sk_destruct = inet_sock_destruct;
|
||||
/*
|
||||
* ... and add it to the refcnt debug socks count
|
||||
* in the new family. -acme
|
||||
|
@@ -86,7 +86,6 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
|
||||
|
||||
while (offset <= packet_len) {
|
||||
struct ipv6_opt_hdr *exthdr;
|
||||
unsigned int len;
|
||||
|
||||
switch (**nexthdr) {
|
||||
|
||||
@@ -112,10 +111,9 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
|
||||
|
||||
exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
|
||||
offset);
|
||||
len = ipv6_optlen(exthdr);
|
||||
if (len + offset >= IPV6_MAXPLEN)
|
||||
offset += ipv6_optlen(exthdr);
|
||||
if (offset > IPV6_MAXPLEN)
|
||||
return -EINVAL;
|
||||
offset += len;
|
||||
*nexthdr = &exthdr->nexthdr;
|
||||
}
|
||||
|
||||
|
@@ -440,7 +440,8 @@ static bool rt6_check_expired(const struct rt6_info *rt)
|
||||
if (time_after(jiffies, rt->dst.expires))
|
||||
return true;
|
||||
} else if (rt->dst.from) {
|
||||
return rt6_check_expired((struct rt6_info *) rt->dst.from);
|
||||
return rt->dst.obsolete != DST_OBSOLETE_FORCE_CHK ||
|
||||
rt6_check_expired((struct rt6_info *)rt->dst.from);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1289,7 +1290,9 @@ static void rt6_dst_from_metrics_check(struct rt6_info *rt)
|
||||
|
||||
static struct dst_entry *rt6_check(struct rt6_info *rt, u32 cookie)
|
||||
{
|
||||
if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie))
|
||||
u32 rt_cookie = 0;
|
||||
|
||||
if (!rt6_get_cookie_safe(rt, &rt_cookie) || rt_cookie != cookie)
|
||||
return NULL;
|
||||
|
||||
if (rt6_check_expired(rt))
|
||||
@@ -1357,8 +1360,14 @@ static void ip6_link_failure(struct sk_buff *skb)
|
||||
if (rt->rt6i_flags & RTF_CACHE) {
|
||||
if (dst_hold_safe(&rt->dst))
|
||||
ip6_del_rt(rt);
|
||||
} else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) {
|
||||
rt->rt6i_node->fn_sernum = -1;
|
||||
} else {
|
||||
struct fib6_node *fn;
|
||||
|
||||
rcu_read_lock();
|
||||
fn = rcu_dereference(rt->rt6i_node);
|
||||
if (fn && (rt->rt6i_flags & RTF_DEFAULT))
|
||||
fn->fn_sernum = -1;
|
||||
rcu_read_unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1375,7 +1384,8 @@ static void rt6_do_update_pmtu(struct rt6_info *rt, u32 mtu)
|
||||
static bool rt6_cache_allowed_for_pmtu(const struct rt6_info *rt)
|
||||
{
|
||||
return !(rt->rt6i_flags & RTF_CACHE) &&
|
||||
(rt->rt6i_flags & RTF_PCPU || rt->rt6i_node);
|
||||
(rt->rt6i_flags & RTF_PCPU ||
|
||||
rcu_access_pointer(rt->rt6i_node));
|
||||
}
|
||||
|
||||
static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk,
|
||||
|
@@ -767,6 +767,15 @@ start_lookup:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void udp6_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
|
||||
{
|
||||
if (udp_sk_rx_dst_set(sk, dst)) {
|
||||
const struct rt6_info *rt = (const struct rt6_info *)dst;
|
||||
|
||||
inet6_sk(sk)->rx_dst_cookie = rt6_get_cookie(rt);
|
||||
}
|
||||
}
|
||||
|
||||
int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
|
||||
int proto)
|
||||
{
|
||||
@@ -816,7 +825,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
|
||||
int ret;
|
||||
|
||||
if (unlikely(sk->sk_rx_dst != dst))
|
||||
udp_sk_rx_dst_set(sk, dst);
|
||||
udp6_sk_rx_dst_set(sk, dst);
|
||||
|
||||
ret = udpv6_queue_rcv_skb(sk, skb);
|
||||
sock_put(sk);
|
||||
|
Reference in New Issue
Block a user