page_pool: fragment API support for 32-bit arch with 64-bit DMA
[platform/kernel/linux-rpi.git] / net / core / sock.c
index 16584e2..383e30f 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/poll.h>
 #include <linux/tcp.h>
+#include <linux/udp.h>
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <linux/user_namespace.h>
@@ -600,7 +601,7 @@ struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
            INDIRECT_CALL_INET(dst->ops->check, ip6_dst_check, ipv4_dst_check,
                               dst, cookie) == NULL) {
                sk_tx_queue_clear(sk);
-               sk->sk_dst_pending_confirm = 0;
+               WRITE_ONCE(sk->sk_dst_pending_confirm, 0);
                RCU_INIT_POINTER(sk->sk_dst_cache, NULL);
                dst_release(dst);
                return NULL;
@@ -1718,9 +1719,16 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
                break;
 
        case SO_TIMESTAMPING_OLD:
+       case SO_TIMESTAMPING_NEW:
                lv = sizeof(v.timestamping);
-               v.timestamping.flags = READ_ONCE(sk->sk_tsflags);
-               v.timestamping.bind_phc = READ_ONCE(sk->sk_bind_phc);
+               /* For the later-added case SO_TIMESTAMPING_NEW: Be strict about only
+                * returning the flags when they were set through the same option.
+                * Don't change the beviour for the old case SO_TIMESTAMPING_OLD.
+                */
+               if (optname == SO_TIMESTAMPING_OLD || sock_flag(sk, SOCK_TSTAMP_NEW)) {
+                       v.timestamping.flags = READ_ONCE(sk->sk_tsflags);
+                       v.timestamping.bind_phc = READ_ONCE(sk->sk_bind_phc);
+               }
                break;
 
        case SO_RCVTIMEO_OLD:
@@ -2821,6 +2829,7 @@ int __sock_cmsg_send(struct sock *sk, struct cmsghdr *cmsg,
                sockc->mark = *(u32 *)CMSG_DATA(cmsg);
                break;
        case SO_TIMESTAMPING_OLD:
+       case SO_TIMESTAMPING_NEW:
                if (cmsg->cmsg_len != CMSG_LEN(sizeof(u32)))
                        return -EINVAL;
 
@@ -4128,8 +4137,14 @@ bool sk_busy_loop_end(void *p, unsigned long start_time)
 {
        struct sock *sk = p;
 
-       return !skb_queue_empty_lockless(&sk->sk_receive_queue) ||
-              sk_busy_loop_timeout(sk, start_time);
+       if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
+               return true;
+
+       if (sk_is_udp(sk) &&
+           !skb_queue_empty_lockless(&udp_sk(sk)->reader_queue))
+               return true;
+
+       return sk_busy_loop_timeout(sk, start_time);
 }
 EXPORT_SYMBOL(sk_busy_loop_end);
 #endif /* CONFIG_NET_RX_BUSY_POLL */