clocksource: Add module refcount
Add a module refcount, so the current clocksource cannot be removed unconditionally. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: John Stultz <john.stultz@linaro.org> Cc: Magnus Damm <magnus.damm@gmail.com> Link: http://lkml.kernel.org/r/20130425143435.762417789@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
ba919d1caa
commit
09ac369c82
|
@ -21,6 +21,7 @@
|
|||
/* clocksource cycle base type */
|
||||
typedef u64 cycle_t;
|
||||
struct clocksource;
|
||||
struct module;
|
||||
|
||||
#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
|
||||
#include <asm/clocksource.h>
|
||||
|
@ -162,6 +163,7 @@ extern u64 timecounter_cyc2time(struct timecounter *tc,
|
|||
* @suspend: suspend function for the clocksource, if necessary
|
||||
* @resume: resume function for the clocksource, if necessary
|
||||
* @cycle_last: most recent cycle counter value seen by ::read()
|
||||
* @owner: module reference, must be set by clocksource in modules
|
||||
*/
|
||||
struct clocksource {
|
||||
/*
|
||||
|
@ -195,6 +197,7 @@ struct clocksource {
|
|||
cycle_t cs_last;
|
||||
cycle_t wd_last;
|
||||
#endif
|
||||
struct module *owner;
|
||||
} ____cacheline_aligned;
|
||||
|
||||
/*
|
||||
|
|
|
@ -627,11 +627,20 @@ static int change_clocksource(void *data)
|
|||
write_seqcount_begin(&timekeeper_seq);
|
||||
|
||||
timekeeping_forward_now(tk);
|
||||
if (!new->enable || new->enable(new) == 0) {
|
||||
old = tk->clock;
|
||||
tk_setup_internals(tk, new);
|
||||
if (old->disable)
|
||||
old->disable(old);
|
||||
/*
|
||||
* If the cs is in module, get a module reference. Succeeds
|
||||
* for built-in code (owner == NULL) as well.
|
||||
*/
|
||||
if (try_module_get(new->owner)) {
|
||||
if (!new->enable || new->enable(new) == 0) {
|
||||
old = tk->clock;
|
||||
tk_setup_internals(tk, new);
|
||||
if (old->disable)
|
||||
old->disable(old);
|
||||
module_put(old->owner);
|
||||
} else {
|
||||
module_put(new->owner);
|
||||
}
|
||||
}
|
||||
timekeeping_update(tk, true, true);
|
||||
|
||||
|
|
Loading…
Reference in New Issue