On Mon, Aug 26, 2019 at 04:14:36PM +0200, Peter Zijlstra wrote:
> (XXX, we should probably move the schedule_timeout() thing into its own
> patch)

A better version here...

---
Subject: sched,time: Allow better constprop/DCE for schedule_timeout()

If timeout is constant and MAX_SCHEDULE_TIMEOUT, it would be nice to
allow to optimize away everything timeout.

Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org>
---
 include/linux/sched.h | 13 ++++++++++++-
 kernel/time/timer.c   | 52 ++++++++++++++++++++++++---------------------------
 2 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index f0edee94834a..6003e96bce52 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -214,7 +214,18 @@ extern void scheduler_tick(void);
 
 #define        MAX_SCHEDULE_TIMEOUT            LONG_MAX
 
-extern long schedule_timeout(long timeout);
+extern long __schedule_timeout(long timeout);
+
+static inline long schedule_timeout(long timeout)
+{
+       if (__builtin_constant_p(timeout) && timeout == MAX_SCHEDULE_TIMEOUT) {
+               schedule();
+               return timeout;
+       }
+
+       return __schedule_timeout(timeout);
+}
+
 extern long schedule_timeout_interruptible(long timeout);
 extern long schedule_timeout_killable(long timeout);
 extern long schedule_timeout_uninterruptible(long timeout);
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 0e315a2e77ae..912ae56b96b8 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1851,38 +1851,34 @@ static void process_timeout(struct timer_list *t)
  * jiffies will be returned.  In all cases the return value is guaranteed
  * to be non-negative.
  */
-signed long __sched schedule_timeout(signed long timeout)
+signed long __sched __schedule_timeout(signed long timeout)
 {
        struct process_timer timer;
        unsigned long expire;
 
-       switch (timeout)
-       {
-       case MAX_SCHEDULE_TIMEOUT:
-               /*
-                * These two special cases are useful to be comfortable
-                * in the caller. Nothing more. We could take
-                * MAX_SCHEDULE_TIMEOUT from one of the negative value
-                * but I' d like to return a valid offset (>=0) to allow
-                * the caller to do everything it want with the retval.
-                */
+       /*
+        * We could take MAX_SCHEDULE_TIMEOUT from one of the negative values,
+        * but I'd like to return a valid offset (>= 0) to allow the caller to
+        * do everything it wants with the retval.
+        */
+       if (timeout == MAX_SCHEDULE_TIMEOUT) {
                schedule();
-               goto out;
-       default:
-               /*
-                * Another bit of PARANOID. Note that the retval will be
-                * 0 since no piece of kernel is supposed to do a check
-                * for a negative retval of schedule_timeout() (since it
-                * should never happens anyway). You just have the printk()
-                * that will tell you if something is gone wrong and where.
-                */
-               if (timeout < 0) {
-                       printk(KERN_ERR "schedule_timeout: wrong timeout "
+               return timeout;
+       }
+
+       /*
+        * Another bit of PARANOID. Note that the retval will be 0 since no
+        * piece of kernel is supposed to do a check for a negative retval of
+        * schedule_timeout() (since it should never happens anyway). You just
+        * have the printk() that will tell you if something is gone wrong and
+        * where.
+        */
+       if (timeout < 0) {
+               printk(KERN_ERR "schedule_timeout: wrong timeout "
                                "value %lx\n", timeout);
-                       dump_stack();
-                       current->state = TASK_RUNNING;
-                       goto out;
-               }
+               dump_stack();
+               current->state = TASK_RUNNING;
+               goto out;
        }
 
        expire = timeout + jiffies;
@@ -1898,10 +1894,10 @@ signed long __sched schedule_timeout(signed long 
timeout)
 
        timeout = expire - jiffies;
 
- out:
+out:
        return timeout < 0 ? 0 : timeout;
 }
-EXPORT_SYMBOL(schedule_timeout);
+EXPORT_SYMBOL(__schedule_timeout);
 
 /*
  * We can use __set_current_state() here because schedule_timeout() calls

Reply via email to