Messages in this thread Patch in this message |  | | From | Nicolai Stange <> | Subject | [RFC v8 16/28] clockevents: min delta increment: calculate min_delta_ns from ticks | Date | Sat, 19 Nov 2016 17:10:24 +0100 |
| |
The use of a clockevent device's ->min_delta_ns in the event programming path hinders upcoming changes to the clockevent core making it NTP correction aware: both, ->mult and ->min_delta_ns would need to get updated as well as consumed atomically and we'd rather like to avoid any locking here.
We already have got ->min_delta_ticks_adjusted which - resembles the value of ->min_delta_ns - and is guaranteed to be always >= the hardware's hard limit ->min_delta_ticks and thus, can be used w/o locking as we don't care for small deviations.
In clockevents_increase_min_delta(), don't use ->min_delta_ns but calculate it dynamically from ->min_delta_ticks_adjusted.
As clockevents_increase_min_delta() gets invoked only rarely, the additional division should not be an issue from a performance standpoint.
Signed-off-by: Nicolai Stange <nicstange@gmail.com> --- kernel/time/clockevents.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 74b05dd..36dd024 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -209,29 +209,32 @@ int clockevents_tick_resume(struct clock_event_device *dev) */ static int clockevents_increase_min_delta(struct clock_event_device *dev) { + u64 min_delta_ns = cev_delta2ns(dev->min_delta_ticks_adjusted, dev, + false); + /* Nothing to do if we already reached the limit */ - if (dev->min_delta_ns >= MIN_DELTA_LIMIT) { + if (min_delta_ns >= MIN_DELTA_LIMIT) { printk_deferred(KERN_WARNING "CE: Reprogramming failure. Giving up\n"); dev->next_event.tv64 = KTIME_MAX; return -ETIME; } - if (dev->min_delta_ns < 5000) - dev->min_delta_ns = 5000; + if (min_delta_ns < 5000) + min_delta_ns = 5000; else - dev->min_delta_ns += dev->min_delta_ns >> 1; + min_delta_ns += min_delta_ns >> 1; - if (dev->min_delta_ns > MIN_DELTA_LIMIT) - dev->min_delta_ns = MIN_DELTA_LIMIT; + if (min_delta_ns > MIN_DELTA_LIMIT) + min_delta_ns = MIN_DELTA_LIMIT; - dev->min_delta_ticks_adjusted = (unsigned long)((dev->min_delta_ns * + dev->min_delta_ticks_adjusted = (unsigned long)((min_delta_ns * dev->mult) >> dev->shift); printk_deferred(KERN_WARNING "CE: %s increased min_delta_ns to %llu nsec\n", dev->name ? dev->name : "?", - (unsigned long long) dev->min_delta_ns); + (unsigned long long) min_delta_ns); return 0; } -- 2.10.2
|  |