From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754982AbcIIUSj (ORCPT ); Fri, 9 Sep 2016 16:18:39 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:34076 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754900AbcIIUSf (ORCPT ); Fri, 9 Sep 2016 16:18:35 -0400 From: Nicolai Stange To: Thomas Gleixner Cc: John Stultz , linux-kernel@vger.kernel.org, Nicolai Stange Subject: [RFC v6 18/23] clockevents: min delta increment: calculate min_delta_ns from ticks Date: Fri, 9 Sep 2016 22:18:07 +0200 Message-Id: <20160909201812.32396-3-nicstange@gmail.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20160909200033.32103-1-nicstange@gmail.com> References: <20160909200033.32103-1-nicstange@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 aa7b325..86d9f97 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -210,23 +210,26 @@ 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); dev->min_delta_ticks_adjusted = max(dev->min_delta_ticks_adjusted, dev->min_delta_ticks); @@ -234,7 +237,7 @@ static int clockevents_increase_min_delta(struct clock_event_device *dev) 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.9.3