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@chromium.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: linux-mips@linux-mips.org Cc: Petr Mladek <pmladek@suse.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Lai Jiangshan <jiangshanlai@gmail.com> Cc: Sebastian Reichel <sre@kernel.org> Cc: Kalle Valo <kvalo@qca.qualcomm.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Pavel Machek <pavel@ucw.cz> Cc: linux1394-devel@lists.sourceforge.net Cc: Chris Metcalf <cmetcalf@mellanox.com> Cc: linux-s390@vger.kernel.org Cc: linux-wireless@vger.kernel.org Cc: "James E.J. Bottomley" <jejb@linux.vnet.ibm.com> Cc: Wim Van Sebroeck <wim@iguana.be> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Ursula Braun <ubraun@linux.vnet.ibm.com> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Viresh Kumar <viresh.kumar@linaro.org> Cc: Harish Patil <harish.patil@cavium.com> Cc: Guenter Roeck <linux@roeck-us.net> Cc: Manish Chopra <manish.chopra@cavium.com> Cc: Len Brown <len.brown@intel.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: linux-pm@vger.kernel.org Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Tejun Heo <tj@kernel.org> Cc: Julian Wiedmann <jwi@linux.vnet.ibm.com> Cc: John Stultz <john.stultz@linaro.org> Cc: Mark Gross <mark.gross@intel.com> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> Cc: linux-watchdog@vger.kernel.org Cc: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" <martin.petersen@oracle.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Stephen Boyd <sboyd@codeaurora.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Stefan Richter <stefanr@s5r6.in-berlin.de> Cc: Michael Reed <mdr@sgi.com> Cc: netdev@vger.kernel.org Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: linuxppc-dev@lists.ozlabs.org Cc: Sudip Mukherjee <sudipm.mukherjee@gmail.com> Link: https://lkml.kernel.org/r/1507159627-127660-2-git-send-email-keescook@chromium.org
This commit is contained in:
parent
26eafeaab9
commit
58e1177b4c
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue