Merge tag 'y2038-drivers-for-v5.6-signed' of git://git.kernel.org:/pub/scm/linux...
[linux-2.6-microblaze.git] / net / packet / af_packet.c
index 118cd66..30c6879 100644 (file)
@@ -408,17 +408,17 @@ static int __packet_get_status(const struct packet_sock *po, void *frame)
        }
 }
 
-static __u32 tpacket_get_timestamp(struct sk_buff *skb, struct timespec *ts,
+static __u32 tpacket_get_timestamp(struct sk_buff *skb, struct timespec64 *ts,
                                   unsigned int flags)
 {
        struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
 
        if (shhwtstamps &&
            (flags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
-           ktime_to_timespec_cond(shhwtstamps->hwtstamp, ts))
+           ktime_to_timespec64_cond(shhwtstamps->hwtstamp, ts))
                return TP_STATUS_TS_RAW_HARDWARE;
 
-       if (ktime_to_timespec_cond(skb->tstamp, ts))
+       if (ktime_to_timespec64_cond(skb->tstamp, ts))
                return TP_STATUS_TS_SOFTWARE;
 
        return 0;
@@ -428,13 +428,20 @@ static __u32 __packet_set_timestamp(struct packet_sock *po, void *frame,
                                    struct sk_buff *skb)
 {
        union tpacket_uhdr h;
-       struct timespec ts;
+       struct timespec64 ts;
        __u32 ts_status;
 
        if (!(ts_status = tpacket_get_timestamp(skb, &ts, po->tp_tstamp)))
                return 0;
 
        h.raw = frame;
+       /*
+        * versions 1 through 3 overflow the timestamps in y2106, since they
+        * all store the seconds in a 32-bit unsigned integer.
+        * If we create a version 4, that should have a 64-bit timestamp,
+        * either 64-bit seconds + 32-bit nanoseconds, or just 64-bit
+        * nanoseconds.
+        */
        switch (po->tp_version) {
        case TPACKET_V1:
                h.h1->tp_sec = ts.tv_sec;
@@ -520,7 +527,7 @@ static int prb_calc_retire_blk_tmo(struct packet_sock *po,
                                int blk_size_in_bytes)
 {
        struct net_device *dev;
-       unsigned int mbits = 0, msec = 0, div = 0, tmo = 0;
+       unsigned int mbits, div;
        struct ethtool_link_ksettings ecmd;
        int err;
 
@@ -532,31 +539,25 @@ static int prb_calc_retire_blk_tmo(struct packet_sock *po,
        }
        err = __ethtool_get_link_ksettings(dev, &ecmd);
        rtnl_unlock();
-       if (!err) {
-               /*
-                * If the link speed is so slow you don't really
-                * need to worry about perf anyways
-                */
-               if (ecmd.base.speed < SPEED_1000 ||
-                   ecmd.base.speed == SPEED_UNKNOWN) {
-                       return DEFAULT_PRB_RETIRE_TOV;
-               } else {
-                       msec = 1;
-                       div = ecmd.base.speed / 1000;
-               }
-       } else
+       if (err)
+               return DEFAULT_PRB_RETIRE_TOV;
+
+       /* If the link speed is so slow you don't really
+        * need to worry about perf anyways
+        */
+       if (ecmd.base.speed < SPEED_1000 ||
+           ecmd.base.speed == SPEED_UNKNOWN)
                return DEFAULT_PRB_RETIRE_TOV;
 
+       div = ecmd.base.speed / 1000;
        mbits = (blk_size_in_bytes * 8) / (1024 * 1024);
 
        if (div)
                mbits /= div;
 
-       tmo = mbits * msec;
-
        if (div)
-               return tmo+1;
-       return tmo;
+               return mbits + 1;
+       return mbits;
 }
 
 static void prb_init_ft_ops(struct tpacket_kbdq_core *p1,
@@ -775,8 +776,8 @@ static void prb_close_block(struct tpacket_kbdq_core *pkc1,
                 * It shouldn't really happen as we don't close empty
                 * blocks. See prb_retire_rx_blk_timer_expired().
                 */
-               struct timespec ts;
-               getnstimeofday(&ts);
+               struct timespec64 ts;
+               ktime_get_real_ts64(&ts);
                h1->ts_last_pkt.ts_sec = ts.tv_sec;
                h1->ts_last_pkt.ts_nsec = ts.tv_nsec;
        }
@@ -806,7 +807,7 @@ static void prb_thaw_queue(struct tpacket_kbdq_core *pkc)
 static void prb_open_block(struct tpacket_kbdq_core *pkc1,
        struct tpacket_block_desc *pbd1)
 {
-       struct timespec ts;
+       struct timespec64 ts;
        struct tpacket_hdr_v1 *h1 = &pbd1->hdr.bh1;
 
        smp_rmb();
@@ -819,7 +820,7 @@ static void prb_open_block(struct tpacket_kbdq_core *pkc1,
        BLOCK_NUM_PKTS(pbd1) = 0;
        BLOCK_LEN(pbd1) = BLK_PLUS_PRIV(pkc1->blk_sizeof_priv);
 
-       getnstimeofday(&ts);
+       ktime_get_real_ts64(&ts);
 
        h1->ts_first_pkt.ts_sec = ts.tv_sec;
        h1->ts_first_pkt.ts_nsec = ts.tv_nsec;
@@ -2169,7 +2170,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
        unsigned long status = TP_STATUS_USER;
        unsigned short macoff, netoff, hdrlen;
        struct sk_buff *copy_skb = NULL;
-       struct timespec ts;
+       struct timespec64 ts;
        __u32 ts_status;
        bool is_drop_n_account = false;
        bool do_vnet = false;
@@ -2301,7 +2302,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
        skb_copy_bits(skb, 0, h.raw + macoff, snaplen);
 
        if (!(ts_status = tpacket_get_timestamp(skb, &ts, po->tp_tstamp)))
-               getnstimeofday(&ts);
+               ktime_get_real_ts64(&ts);
 
        status |= ts_status;