Commit-ID: 58e1177b4cd10b0d358faf7d7ebb3779f98bc3ea Gitweb: https://git.kernel.org/tip/58e1177b4cd10b0d358faf7d7ebb3779f98bc3ea Author: Kees Cook <keescook@xxxxxxxxxxxx> AuthorDate: Wed, 4 Oct 2017 16:26:55 -0700 Committer: Thomas Gleixner <tglx@xxxxxxxxxxxxx> 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 <keescook@xxxxxxxxxxxx> Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: linux-mips@xxxxxxxxxxxxxx Cc: Petr Mladek <pmladek@xxxxxxxx> Cc: Benjamin Herrenschmidt <benh@xxxxxxxxxxxxxxxxxxx> Cc: Lai Jiangshan <jiangshanlai@xxxxxxxxx> Cc: Sebastian Reichel <sre@xxxxxxxxxx> Cc: Kalle Valo <kvalo@xxxxxxxxxxxxxxxx> Cc: Paul Mackerras <paulus@xxxxxxxxx> Cc: Pavel Machek <pavel@xxxxxx> Cc: linux1394-devel@xxxxxxxxxxxxxxxxxxxxx Cc: Chris Metcalf <cmetcalf@xxxxxxxxxxxx> Cc: linux-s390@xxxxxxxxxxxxxxx Cc: linux-wireless@xxxxxxxxxxxxxxx Cc: "James E.J. Bottomley" <jejb@xxxxxxxxxxxxxxxxxx> Cc: Wim Van Sebroeck <wim@xxxxxxxxx> Cc: Michael Ellerman <mpe@xxxxxxxxxxxxxx> Cc: Ursula Braun <ubraun@xxxxxxxxxxxxxxxxxx> Cc: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> Cc: Viresh Kumar <viresh.kumar@xxxxxxxxxx> Cc: Harish Patil <harish.patil@xxxxxxxxxx> Cc: Guenter Roeck <linux@xxxxxxxxxxxx> Cc: Manish Chopra <manish.chopra@xxxxxxxxxx> Cc: Len Brown <len.brown@xxxxxxxxx> Cc: Arnd Bergmann <arnd@xxxxxxxx> Cc: linux-pm@xxxxxxxxxxxxxxx Cc: Heiko Carstens <heiko.carstens@xxxxxxxxxx> Cc: Tejun Heo <tj@xxxxxxxxxx> Cc: Julian Wiedmann <jwi@xxxxxxxxxxxxxxxxxx> Cc: John Stultz <john.stultz@xxxxxxxxxx> Cc: Mark Gross <mark.gross@xxxxxxxxx> Cc: "Rafael J. Wysocki" <rjw@xxxxxxxxxxxxx> Cc: linux-watchdog@xxxxxxxxxxxxxxx Cc: linux-scsi@xxxxxxxxxxxxxxx Cc: "Martin K. Petersen" <martin.petersen@xxxxxxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> Cc: Stephen Boyd <sboyd@xxxxxxxxxxxxxx> Cc: Oleg Nesterov <oleg@xxxxxxxxxx> Cc: Ralf Baechle <ralf@xxxxxxxxxxxxxx> Cc: Stefan Richter <stefanr@xxxxxxxxxxxxxxxxx> Cc: Michael Reed <mdr@xxxxxxx> Cc: netdev@xxxxxxxxxxxxxxx Cc: Martin Schwidefsky <schwidefsky@xxxxxxxxxx> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: linuxppc-dev@xxxxxxxxxxxxxxxx Cc: Sudip Mukherjee <sudipm.mukherjee@xxxxxxxxx> Link: https://lkml.kernel.org/r/1507159627-127660-2-git-send-email-keescook@xxxxxxxxxxxx --- 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; -- To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html
![]() |