From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933397AbcHVXgL (ORCPT ); Mon, 22 Aug 2016 19:36:11 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:35632 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933237AbcHVXeW (ORCPT ); Mon, 22 Aug 2016 19:34:22 -0400 From: Nicolai Stange To: Thomas Gleixner Cc: John Stultz , linux-kernel@vger.kernel.org, Nicolai Stange Subject: [RFC v4 17/22] clockevents: min delta increment: calculate min_delta_ns from ticks Date: Tue, 23 Aug 2016 01:33:15 +0200 Message-Id: <20160822233320.4548-18-nicstange@gmail.com> X-Mailer: git-send-email 2.9.2 In-Reply-To: <20160822233320.4548-1-nicstange@gmail.com> References: <20160822233320.4548-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 77ecbb2..bb3b98c 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -209,23 +209,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); @@ -233,7 +236,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.2