Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753902AbcKSQOE (ORCPT ); Sat, 19 Nov 2016 11:14:04 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:35002 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753656AbcKSQLt (ORCPT ); Sat, 19 Nov 2016 11:11:49 -0500 From: Nicolai Stange To: Thomas Gleixner Cc: John Stultz , linux-kernel@vger.kernel.org, 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 Message-Id: <20161119161036.12679-5-nicstange@gmail.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20161119160055.12491-1-nicstange@gmail.com> References: <20161119160055.12491-1-nicstange@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2433 Lines: 70 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 --- 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