]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
um: Simplify os_idle_sleep() and sleep longer
authorJohannes Berg <johannes.berg@intel.com>
Wed, 2 Dec 2020 19:58:04 +0000 (20:58 +0100)
committerRichard Weinberger <richard@nod.at>
Sun, 13 Dec 2020 21:22:37 +0000 (22:22 +0100)
There really is no reason to pass the amount of time we should
sleep, especially since it's just hard-coded to one second.

Additionally, one second isn't really all that long, and as we
are expecting to be woken up by a signal, we can sleep longer
and avoid doing some work every second, so replace the current
clock_nanosleep() with just an empty select() that can _only_
be woken up by a signal.

We can also remove the deliver_alarm() since we don't need to
do that when we got e.g. SIGIO that woke us up, and if we got
SIGALRM the signal handler will actually (have) run, so it's
just unnecessary extra work.

Similarly, in time-travel mode, just program the wakeup event
from idle to be S64_MAX, which is basically the most you could
ever simulate to. Of course, you should already have an event
in the list that's earlier and will cause a wakeup, normally
that's the regular timer interrupt, though in suspend it may
(later) also be an RTC event. Since actually getting to this
point would be a bug and you can't ever get out again, panic()
on it in the time control code.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Acked-By: Anton Ivanov <anton.ivanov@cambridgegreys.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
arch/um/include/linux/time-internal.h
arch/um/include/shared/os.h
arch/um/kernel/process.c
arch/um/kernel/time.c
arch/um/os-Linux/time.c

index f3b03d39a854387e4b6544ff1297bedaa2b0f53a..68e45e950137c1539cb8fcff1cf9351a9e179051 100644 (file)
@@ -28,7 +28,7 @@ struct time_travel_event {
 
 extern enum time_travel_mode time_travel_mode;
 
-void time_travel_sleep(unsigned long long duration);
+void time_travel_sleep(void);
 
 static inline void
 time_travel_set_event_fn(struct time_travel_event *e,
@@ -60,7 +60,7 @@ struct time_travel_event {
 
 #define time_travel_mode TT_MODE_OFF
 
-static inline void time_travel_sleep(unsigned long long duration)
+static inline void time_travel_sleep(void)
 {
 }
 
index e2bb7e488d5995807175eec75666c396de286347..0f7fb8bad728c5438e2079a8cebd4fef786f81e9 100644 (file)
@@ -256,7 +256,7 @@ extern void os_warn(const char *fmt, ...)
        __attribute__ ((format (printf, 1, 2)));
 
 /* time.c */
-extern void os_idle_sleep(unsigned long long nsecs);
+extern void os_idle_sleep(void);
 extern int os_timer_create(void);
 extern int os_timer_set_interval(unsigned long long nsecs);
 extern int os_timer_one_shot(unsigned long long nsecs);
index 0fcdc374a9a1a2aee5d9049e8b93a1be3ccd3fad..a85c48ac2b273361a3d36e38b0595ed3d7b9d6d7 100644 (file)
@@ -205,13 +205,10 @@ void initial_thread_cb(void (*proc)(void *), void *arg)
 
 static void um_idle_sleep(void)
 {
-       unsigned long long duration = UM_NSEC_PER_SEC;
-
-       if (time_travel_mode != TT_MODE_OFF) {
-               time_travel_sleep(duration);
-       } else {
-               os_idle_sleep(duration);
-       }
+       if (time_travel_mode != TT_MODE_OFF)
+               time_travel_sleep();
+       else
+               os_idle_sleep();
 }
 
 void arch_cpu_idle(void)
index 8dafc3f2add42004a41ca68341ed619268909255..8e8eb8ba04a49966b5f9dddfb978a61e20588a9e 100644 (file)
@@ -46,6 +46,9 @@ static void time_travel_set_time(unsigned long long ns)
        if (unlikely(ns < time_travel_time))
                panic("time-travel: time goes backwards %lld -> %lld\n",
                      time_travel_time, ns);
+       else if (unlikely(ns >= S64_MAX))
+               panic("The system was going to sleep forever, aborting");
+
        time_travel_time = ns;
 }
 
@@ -399,9 +402,14 @@ static void time_travel_oneshot_timer(struct time_travel_event *e)
        deliver_alarm();
 }
 
-void time_travel_sleep(unsigned long long duration)
+void time_travel_sleep(void)
 {
-       unsigned long long next = time_travel_time + duration;
+       /*
+        * Wait "forever" (using S64_MAX because there are some potential
+        * wrapping issues, especially with the current TT_MODE_EXTERNAL
+        * controller application.
+        */
+       unsigned long long next = S64_MAX;
 
        if (time_travel_mode == TT_MODE_BASIC)
                os_timer_disable();
index 90f6de224c700d76402a36b598c199f08b217143..a61cbf73a179dec6a4bf55595c3d5906057c3c38 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <stddef.h>
+#include <unistd.h>
 #include <errno.h>
 #include <signal.h>
 #include <time.h>
@@ -99,19 +100,9 @@ long long os_nsecs(void)
 }
 
 /**
- * os_idle_sleep() - sleep for a given time of nsecs
- * @nsecs: nanoseconds to sleep
+ * os_idle_sleep() - sleep until interrupted
  */
-void os_idle_sleep(unsigned long long nsecs)
+void os_idle_sleep(void)
 {
-       struct timespec ts = {
-               .tv_sec  = nsecs / UM_NSEC_PER_SEC,
-               .tv_nsec = nsecs % UM_NSEC_PER_SEC
-       };
-
-       /*
-        * Relay the signal if clock_nanosleep is interrupted.
-        */
-       if (clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL))
-               deliver_alarm();
+       pause();
 }