Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Fix the code that deals with very long sleeps (> 24...



details:   https://anonhg.NetBSD.org/src/rev/04551fee55b8
branches:  trunk
changeset: 449549:04551fee55b8
user:      kre <kre%NetBSD.org@localhost>
date:      Sun Mar 10 14:45:53 2019 +0000

description:
Fix the code that deals with very long sleeps (> 248 days) which
go beyond the maximum that the callout mechanism can handle.
[See the comments in tvtohz() in subr_sleep.c for the details.]

When that happens the timeout is clamped to MAX_INT (ticks), and the
code in nanosleep1() looped (or tried to) repeating the sleep (aka
kpause()) until the requested end time for the sleep was reached.

Unfortunately, the code assumed that kpause() would return 0 when
it returned after the timeout expired.   But it doesn't, it returns
EWOULDBLOCK instead (why is incomprehensible to me, but I assume
there is a reason.)   [That comes from sleepq_block() which returns
EWOULDBLOCK when callout_halt() indicates that the callout had fired,
which is exactly what has happened when the time has elapsed.]

There was already code to deal with that EWOULDBLOCK and return 0
instead of an error in that case - but it was placed after the
error code was tested against 0 for the purposes of the loop.

Simply move the EWOULDBLOCK->0 mapping earlier, so the code which
is expecting "error == 0" to mean "nothing went wrong" actually
gets to see that happen, and the loop can actually loop.

(Someday the loop should probably be rewritten as a loop, instead of
as a bunch of code followed by a "goto again"!)

diffstat:

 sys/kern/kern_time.c |  8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diffs (36 lines):

diff -r e3b12ff218c7 -r 04551fee55b8 sys/kern/kern_time.c
--- a/sys/kern/kern_time.c      Sun Mar 10 13:52:11 2019 +0000
+++ b/sys/kern/kern_time.c      Sun Mar 10 14:45:53 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_time.c,v 1.196 2019/02/24 07:23:11 mlelstv Exp $  */
+/*     $NetBSD: kern_time.c,v 1.197 2019/03/10 14:45:53 kre Exp $      */
 
 /*-
  * Copyright (c) 2000, 2004, 2005, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.196 2019/02/24 07:23:11 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.197 2019/03/10 14:45:53 kre Exp $");
 
 #include <sys/param.h>
 #include <sys/resourcevar.h>
@@ -350,6 +350,8 @@
                timo = 1;
 again:
        error = kpause("nanoslp", true, timo, NULL);
+       if (error == EWOULDBLOCK)
+               error = 0;
        if (rmt != NULL || error == 0) {
                struct timespec rmtend;
                struct timespec t0;
@@ -374,8 +376,6 @@
 
        if (error == ERESTART)
                error = EINTR;
-       if (error == EWOULDBLOCK)
-               error = 0;
 
        return error;
 }



Home | Main Index | Thread Index | Old Index