|
@@ -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);
|
|
|
|