Commit-ID: 58e1177b4cd10b0d358faf7d7ebb3779f98bc3ea Gitweb: https://git.kernel.org/tip/58e1177b4cd10b0d358faf7d7ebb3779f98bc3ea Author: Kees Cook <[email protected]> AuthorDate: Wed, 4 Oct 2017 16:26:55 -0700 Committer: Thomas Gleixner <[email protected]> CommitDate: Thu, 5 Oct 2017 15:01:16 +0200
timer: Convert schedule_timeout() to use from_timer() In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new from_timer() helper and passing the timer pointer explicitly. Since this special timer is on the stack, it needs to have a wrapper structure to carry state once .data is eliminated. Signed-off-by: Kees Cook <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: [email protected] Cc: Petr Mladek <[email protected]> Cc: Benjamin Herrenschmidt <[email protected]> Cc: Lai Jiangshan <[email protected]> Cc: Sebastian Reichel <[email protected]> Cc: Kalle Valo <[email protected]> Cc: Paul Mackerras <[email protected]> Cc: Pavel Machek <[email protected]> Cc: [email protected] Cc: Chris Metcalf <[email protected]> Cc: [email protected] Cc: [email protected] Cc: "James E.J. Bottomley" <[email protected]> Cc: Wim Van Sebroeck <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Ursula Braun <[email protected]> Cc: Geert Uytterhoeven <[email protected]> Cc: Viresh Kumar <[email protected]> Cc: Harish Patil <[email protected]> Cc: Guenter Roeck <[email protected]> Cc: Manish Chopra <[email protected]> Cc: Len Brown <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: [email protected] Cc: Heiko Carstens <[email protected]> Cc: Tejun Heo <[email protected]> Cc: Julian Wiedmann <[email protected]> Cc: John Stultz <[email protected]> Cc: Mark Gross <[email protected]> Cc: "Rafael J. Wysocki" <[email protected]> Cc: [email protected] Cc: [email protected] Cc: "Martin K. Petersen" <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: Stephen Boyd <[email protected]> Cc: Oleg Nesterov <[email protected]> Cc: Ralf Baechle <[email protected]> Cc: Stefan Richter <[email protected]> Cc: Michael Reed <[email protected]> Cc: [email protected] Cc: Martin Schwidefsky <[email protected]> Cc: Andrew Morton <[email protected]> Cc: [email protected] Cc: Sudip Mukherjee <[email protected]> Link: https://lkml.kernel.org/r/[email protected] --- include/linux/timer.h | 8 ++++++++ kernel/time/timer.c | 26 +++++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/include/linux/timer.h b/include/linux/timer.h index 6383c52..5ef5c9e 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -179,6 +179,14 @@ static inline void timer_setup(struct timer_list *timer, (TIMER_DATA_TYPE)timer, flags); } +static inline void timer_setup_on_stack(struct timer_list *timer, + void (*callback)(struct timer_list *), + unsigned int flags) +{ + __setup_timer_on_stack(timer, (TIMER_FUNC_TYPE)callback, + (TIMER_DATA_TYPE)timer, flags); +} + #define from_timer(var, callback_timer, timer_fieldname) \ container_of(callback_timer, typeof(*var), timer_fieldname) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index f2674a0..38613ce 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1668,9 +1668,20 @@ void run_local_timers(void) raise_softirq(TIMER_SOFTIRQ); } -static void process_timeout(unsigned long __data) +/* + * Since schedule_timeout()'s timer is defined on the stack, it must store + * the target task on the stack as well. + */ +struct process_timer { + struct timer_list timer; + struct task_struct *task; +}; + +static void process_timeout(struct timer_list *t) { - wake_up_process((struct task_struct *)__data); + struct process_timer *timeout = from_timer(timeout, t, timer); + + wake_up_process(timeout->task); } /** @@ -1704,7 +1715,7 @@ static void process_timeout(unsigned long __data) */ signed long __sched schedule_timeout(signed long timeout) { - struct timer_list timer; + struct process_timer timer; unsigned long expire; switch (timeout) @@ -1738,13 +1749,14 @@ signed long __sched schedule_timeout(signed long timeout) expire = timeout + jiffies; - setup_timer_on_stack(&timer, process_timeout, (unsigned long)current); - __mod_timer(&timer, expire, false); + timer.task = current; + timer_setup_on_stack(&timer.timer, process_timeout, 0); + __mod_timer(&timer.timer, expire, false); schedule(); - del_singleshot_timer_sync(&timer); + del_singleshot_timer_sync(&timer.timer); /* Remove the timer from the object tracker */ - destroy_timer_on_stack(&timer); + destroy_timer_on_stack(&timer.timer); timeout = expire - jiffies;

