Messages in this thread Patch in this message |  | | From | Nicolai Stange <> | Subject | [RFC v8 11/28] clockevents: always initialize ->min_delta_ns and ->max_delta_ns | Date | Sat, 19 Nov 2016 17:00:38 +0100 |
| |
Now that all clockevent drivers set ->min_delta_ticks and ->max_delta_ticks independently of whether they use clockevents_config*() or not, the clockevent core can calculate ->min_delta_ns and ->max_delta_ns from these unconditionally.
The goal is to prepare the clockevent core for introducing NTP rate correction awareness: as the clockevent devices' rates will get adjusted, the ->*_delta_ns won't stay fixed but need to get changed as well.
Thus, make the clockevent core calculate the ->*_delta_ns values from the invariant ->_delta_ticks ones at device registration.
In order to facilitate this, move the corresponding code from clockevents_config() into its own helper function, __clockevents_update_bounds() and invoke this where needed, in particular from clockevents_register_device().
Note that there is a side effect affecting those drivers - not using clockevents_config*() - and manually initializing their ->min_delta_ns to values less than 1us. In order to avoid "pointless noise", the clockevent core always sets ->min_delta_ns to values >= 1us, and thus, those drivers' ->min_delta_ns is now increased. I think that this side effect is desired though.
Signed-off-by: Nicolai Stange <nicstange@gmail.com> --- kernel/time/clockevents.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index e73ac7f..4fcec08 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -442,6 +442,20 @@ int clockevents_unbind_device(struct clock_event_device *ced, int cpu) } EXPORT_SYMBOL_GPL(clockevents_unbind_device); +static void __clockevents_update_bounds(struct clock_event_device *dev) +{ + if (!(dev->features & CLOCK_EVT_FEAT_ONESHOT) || + (dev->features & CLOCK_EVT_FEAT_DUMMY)) + return; + + /* + * cev_delta2ns() never returns values less than 1us and thus, + * we'll never program any ced with anything less. + */ + dev->min_delta_ns = cev_delta2ns(dev->min_delta_ticks, dev, false); + dev->max_delta_ns = cev_delta2ns(dev->max_delta_ticks, dev, true); +} + /** * clockevents_register_device - register a clock event device * @dev: device to register @@ -458,6 +472,8 @@ void clockevents_register_device(struct clock_event_device *dev) dev->cpumask = cpumask_of(smp_processor_id()); } + __clockevents_update_bounds(dev); + raw_spin_lock_irqsave(&clockevents_lock, flags); list_add(&dev->list, &clockevent_devices); @@ -488,8 +504,6 @@ static void clockevents_config(struct clock_event_device *dev, u32 freq) sec = 600; clockevents_calc_mult_shift(dev, freq, sec); - dev->min_delta_ns = cev_delta2ns(dev->min_delta_ticks, dev, false); - dev->max_delta_ns = cev_delta2ns(dev->max_delta_ticks, dev, true); } /** @@ -515,6 +529,7 @@ EXPORT_SYMBOL_GPL(clockevents_config_and_register); int __clockevents_update_freq(struct clock_event_device *dev, u32 freq) { clockevents_config(dev, freq); + __clockevents_update_bounds(dev); if (clockevent_state_oneshot(dev)) return clockevents_program_event(dev, dev->next_event, false); -- 2.10.2
|  |