linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] [RESEND] aoe: use ktime_t instead of timeval
@ 2018-01-17 15:30 Arnd Bergmann
  2018-01-17 15:41 ` Jens Axboe
  0 siblings, 1 reply; 3+ messages in thread
From: Arnd Bergmann @ 2018-01-17 15:30 UTC (permalink / raw)
  To: Ed L. Cashin; +Cc: Tina Ruchandani, Arnd Bergmann, Jens Axboe, linux-kernel

From: Tina Ruchandani <ruchandani.tina@gmail.com>

'struct frame' uses two variables to store the sent timestamp - 'struct
timeval' and jiffies. jiffies is used to avoid discrepancies caused by
updates to system time. 'struct timeval' is deprecated because it uses
32-bit representation for seconds which will overflow in year 2038.

This patch does the following:
- Replace the use of 'struct timeval' and jiffies with ktime_t, which
  is the recommended type for timestamping
- ktime_t provides both long range (like jiffies) and high resolution
  (like timeval). Using ktime_get (monotonic time) instead of wall-clock
  time prevents any discprepancies caused by updates to system time.

[updates by Arnd below]
The original patch from Tina never went anywhere as we discussed how
to keep the impact on performance minimal. I've started over now but
arrived at basically the same patch that she had originally, except for
an slightly improved tsince_hr() function. I'm making it more robust
against overflows, and also optimize explicitly for the common case
in which a frame is less than 4.2 seconds old, using only a 32-bit
division in that case.

This should make the new version more efficient than the old code,
since we replace the existing two 32-bit division in do_gettimeofday()
plus one multiplication with a single single 32-bit division in
tsince_hr() and drop the double bookkeeping. It's also more efficient
than the ktime_get_us() API we discussed before, since that would
also rely on multiple divisions.

Link: https://lists.linaro.org/pipermail/y2038/2015-May/000276.html
Signed-off-by: Tina Ruchandani <ruchandani.tina@gmail.com>
Cc: Ed Cashin <ed.cashin@acm.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
I submitted this version in November 2017, but got no reply from
Ed. Jens, could you pick it up directly?
---
 drivers/block/aoe/aoe.h    |  3 +--
 drivers/block/aoe/aoecmd.c | 48 +++++++++++++---------------------------------
 2 files changed, 14 insertions(+), 37 deletions(-)

diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 9220f8e833d0..c0ebda1283cc 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -112,8 +112,7 @@ enum frame_flags {
 struct frame {
 	struct list_head head;
 	u32 tag;
-	struct timeval sent;	/* high-res time packet was sent */
-	u32 sent_jiffs;		/* low-res jiffies-based sent time */
+	ktime_t sent;			/* high-res time packet was sent */
 	ulong waited;
 	ulong waited_total;
 	struct aoetgt *t;		/* parent target I belong to */
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 812fed069708..540bb60cd071 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -398,8 +398,7 @@ aoecmd_ata_rw(struct aoedev *d)
 
 	skb = skb_clone(f->skb, GFP_ATOMIC);
 	if (skb) {
-		do_gettimeofday(&f->sent);
-		f->sent_jiffs = (u32) jiffies;
+		f->sent = ktime_get();
 		__skb_queue_head_init(&queue);
 		__skb_queue_tail(&queue, skb);
 		aoenet_xmit(&queue);
@@ -489,8 +488,7 @@ resend(struct aoedev *d, struct frame *f)
 	skb = skb_clone(skb, GFP_ATOMIC);
 	if (skb == NULL)
 		return;
-	do_gettimeofday(&f->sent);
-	f->sent_jiffs = (u32) jiffies;
+	f->sent = ktime_get();
 	__skb_queue_head_init(&queue);
 	__skb_queue_tail(&queue, skb);
 	aoenet_xmit(&queue);
@@ -499,33 +497,17 @@ resend(struct aoedev *d, struct frame *f)
 static int
 tsince_hr(struct frame *f)
 {
-	struct timeval now;
-	int n;
+	u64 delta = ktime_to_ns(ktime_sub(ktime_get(), f->sent));
 
-	do_gettimeofday(&now);
-	n = now.tv_usec - f->sent.tv_usec;
-	n += (now.tv_sec - f->sent.tv_sec) * USEC_PER_SEC;
+	/* delta is normally under 4.2 seconds, avoid 64-bit division */
+	if (likely(delta <= UINT_MAX))
+		return (u32)delta / NSEC_PER_USEC;
 
-	if (n < 0)
-		n = -n;
+	/* avoid overflow after 71 minutes */
+	if (delta > ((u64)INT_MAX * NSEC_PER_USEC))
+		return INT_MAX;
 
-	/* For relatively long periods, use jiffies to avoid
-	 * discrepancies caused by updates to the system time.
-	 *
-	 * On system with HZ of 1000, 32-bits is over 49 days
-	 * worth of jiffies, or over 71 minutes worth of usecs.
-	 *
-	 * Jiffies overflow is handled by subtraction of unsigned ints:
-	 * (gdb) print (unsigned) 2 - (unsigned) 0xfffffffe
-	 * $3 = 4
-	 * (gdb)
-	 */
-	if (n > USEC_PER_SEC / 4) {
-		n = ((u32) jiffies) - f->sent_jiffs;
-		n *= USEC_PER_SEC / HZ;
-	}
-
-	return n;
+	return div_u64(delta, NSEC_PER_USEC);
 }
 
 static int
@@ -589,7 +571,6 @@ reassign_frame(struct frame *f)
 	nf->waited = 0;
 	nf->waited_total = f->waited_total;
 	nf->sent = f->sent;
-	nf->sent_jiffs = f->sent_jiffs;
 	f->skb = skb;
 
 	return nf;
@@ -633,8 +614,7 @@ probe(struct aoetgt *t)
 
 	skb = skb_clone(f->skb, GFP_ATOMIC);
 	if (skb) {
-		do_gettimeofday(&f->sent);
-		f->sent_jiffs = (u32) jiffies;
+		f->sent = ktime_get();
 		__skb_queue_head_init(&queue);
 		__skb_queue_tail(&queue, skb);
 		aoenet_xmit(&queue);
@@ -1432,10 +1412,8 @@ aoecmd_ata_id(struct aoedev *d)
 	d->timer.function = rexmit_timer;
 
 	skb = skb_clone(skb, GFP_ATOMIC);
-	if (skb) {
-		do_gettimeofday(&f->sent);
-		f->sent_jiffs = (u32) jiffies;
-	}
+	if (skb)
+		f->sent = ktime_get();
 
 	return skb;
 }
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] [RESEND] aoe: use ktime_t instead of timeval
  2018-01-17 15:30 [PATCH] [RESEND] aoe: use ktime_t instead of timeval Arnd Bergmann
@ 2018-01-17 15:41 ` Jens Axboe
  2018-01-17 22:26   ` Ed Cashin
  0 siblings, 1 reply; 3+ messages in thread
From: Jens Axboe @ 2018-01-17 15:41 UTC (permalink / raw)
  To: Arnd Bergmann, Ed L. Cashin; +Cc: Tina Ruchandani, linux-kernel

On 1/17/18 8:30 AM, Arnd Bergmann wrote:
> From: Tina Ruchandani <ruchandani.tina@gmail.com>
> 
> 'struct frame' uses two variables to store the sent timestamp - 'struct
> timeval' and jiffies. jiffies is used to avoid discrepancies caused by
> updates to system time. 'struct timeval' is deprecated because it uses
> 32-bit representation for seconds which will overflow in year 2038.
> 
> This patch does the following:
> - Replace the use of 'struct timeval' and jiffies with ktime_t, which
>   is the recommended type for timestamping
> - ktime_t provides both long range (like jiffies) and high resolution
>   (like timeval). Using ktime_get (monotonic time) instead of wall-clock
>   time prevents any discprepancies caused by updates to system time.
> 
> [updates by Arnd below]
> The original patch from Tina never went anywhere as we discussed how
> to keep the impact on performance minimal. I've started over now but
> arrived at basically the same patch that she had originally, except for
> an slightly improved tsince_hr() function. I'm making it more robust
> against overflows, and also optimize explicitly for the common case
> in which a frame is less than 4.2 seconds old, using only a 32-bit
> division in that case.
> 
> This should make the new version more efficient than the old code,
> since we replace the existing two 32-bit division in do_gettimeofday()
> plus one multiplication with a single single 32-bit division in
> tsince_hr() and drop the double bookkeeping. It's also more efficient
> than the ktime_get_us() API we discussed before, since that would
> also rely on multiple divisions.

Applied, thanks Arnd/Tina.

-- 
Jens Axboe

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] [RESEND] aoe: use ktime_t instead of timeval
  2018-01-17 15:41 ` Jens Axboe
@ 2018-01-17 22:26   ` Ed Cashin
  0 siblings, 0 replies; 3+ messages in thread
From: Ed Cashin @ 2018-01-17 22:26 UTC (permalink / raw)
  To: Jens Axboe, Arnd Bergmann; +Cc: Tina Ruchandani, linux-kernel

On 01/17/2018 10:41 AM, Jens Axboe wrote:
...
> Applied, thanks Arnd/Tina.

Thank you for the CC.  Sorry for the lack of response in November.

-- 
   Ed

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-01-17 23:07 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-17 15:30 [PATCH] [RESEND] aoe: use ktime_t instead of timeval Arnd Bergmann
2018-01-17 15:41 ` Jens Axboe
2018-01-17 22:26   ` Ed Cashin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).