From patchwork Fri May 9 21:05:43 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Pitre X-Patchwork-Id: 29925 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pd0-f200.google.com (mail-pd0-f200.google.com [209.85.192.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 78833202FE for ; Fri, 9 May 2014 21:05:58 +0000 (UTC) Received: by mail-pd0-f200.google.com with SMTP id y10sf18126399pdj.3 for ; Fri, 09 May 2014 14:05:57 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:date:from:to:cc:subject:in-reply-to :message-id:references:user-agent:mime-version:sender:precedence :list-id:x-original-sender:x-original-authentication-results :mailing-list:list-post:list-help:list-archive:list-unsubscribe :content-type; bh=ykeh3cOibHq0dLa4ruW6Mygbe1oSlLU1IJC3vUNGzQg=; b=IYFGBk29m/lXRbcPjv8c56IpE9Ann7voAx3JLZnkNx/3SUUXY/qJOsS9Y55V+cdPSw znppuyzrx9l6L/QeryxUFmq9i8mG6qDkNwplVokm3yQ5u8O/REgPBo+S+1nayhvNi5Ja 7Dp4d6mP0gDgLb7uZY1BGj6nEhNnhqaH6lHSWYMIIMyiBO6lQDWqHIL7zX8HbImft6ZS nlBWiQFK4d72lFixcNjVjULrYWu14UXuCPAsNQ0Czh5HXMqnSu+kmlBJwZE2vw2fvn2a VQarFCpfdiCyUSEKkpD7PTt7l2i4jTtKBrScan1YKCzo6igrA6vHwEGsK9xC4HFC4NYx ULxA== X-Gm-Message-State: ALoCoQnkzQbYmLSgIcFkfpk3O6kYmvIUgFwzkcaYc3j6zFPX9+Oor8YDTX5QcePqODXYahEiRHt9 X-Received: by 10.66.158.6 with SMTP id wq6mr3829912pab.39.1399669557560; Fri, 09 May 2014 14:05:57 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.96.72 with SMTP id j66ls458362qge.99.gmail; Fri, 09 May 2014 14:05:57 -0700 (PDT) X-Received: by 10.58.116.175 with SMTP id jx15mr9986069veb.9.1399669557406; Fri, 09 May 2014 14:05:57 -0700 (PDT) Received: from mail-vc0-f182.google.com (mail-vc0-f182.google.com [209.85.220.182]) by mx.google.com with ESMTPS id iz10si912092vec.168.2014.05.09.14.05.57 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 09 May 2014 14:05:57 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.182 as permitted sender) client-ip=209.85.220.182; Received: by mail-vc0-f182.google.com with SMTP id la4so6090673vcb.27 for ; Fri, 09 May 2014 14:05:57 -0700 (PDT) X-Received: by 10.58.38.40 with SMTP id d8mr2022295vek.61.1399669557276; Fri, 09 May 2014 14:05:57 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.221.72 with SMTP id ib8csp110965vcb; Fri, 9 May 2014 14:05:56 -0700 (PDT) X-Received: by 10.66.122.72 with SMTP id lq8mr24763067pab.69.1399669556313; Fri, 09 May 2014 14:05:56 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id sy7si2972162pac.141.2014.05.09.14.05.55; Fri, 09 May 2014 14:05:55 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757677AbaEIVFs (ORCPT + 27 others); Fri, 9 May 2014 17:05:48 -0400 Received: from mail-qg0-f50.google.com ([209.85.192.50]:48883 "EHLO mail-qg0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757463AbaEIVFq (ORCPT ); Fri, 9 May 2014 17:05:46 -0400 Received: by mail-qg0-f50.google.com with SMTP id z60so5025974qgd.37 for ; Fri, 09 May 2014 14:05:46 -0700 (PDT) X-Received: by 10.140.88.83 with SMTP id s77mr17228564qgd.113.1399669545945; Fri, 09 May 2014 14:05:45 -0700 (PDT) Received: from xanadu.home (modemcable177.143-130-66.mc.videotron.ca. [66.130.143.177]) by mx.google.com with ESMTPSA id j7sm8312606qab.27.2014.05.09.14.05.44 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 09 May 2014 14:05:45 -0700 (PDT) Date: Fri, 9 May 2014 17:05:43 -0400 (EDT) From: Nicolas Pitre To: Russell King - ARM Linux cc: Doug Anderson , Viresh Kumar , "Rafael J. Wysocki" , Will Deacon , John Stultz , David Riley , "olof@lixom.net" , Sonny Rao , Richard Zhao , Santosh Shilimkar , Shawn Guo , Stephen Boyd , Marc Zyngier , Stephen Warren , Paul Gortmaker , "linux-arm-kernel@lists.infradead.org" , "linux-kernel@vger.kernel.org" Subject: Re: [PATCH] ARM: Don't ever downscale loops_per_jiffy in SMP systems# In-Reply-To: <20140509182245.GM3693@n2100.arm.linux.org.uk> Message-ID: References: <20140508192209.GH3693@n2100.arm.linux.org.uk> <20140508205223.GI3693@n2100.arm.linux.org.uk> <20140509091824.GL3693@n2100.arm.linux.org.uk> <20140509182245.GM3693@n2100.arm.linux.org.uk> User-Agent: Alpine 2.11 (LFD 23 2013-08-11) MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: nicolas.pitre@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.182 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , On Fri, 9 May 2014, Russell King - ARM Linux wrote: > I'd much prefer just printing a warning at kernel boot time to report > that the kernel is running with features which would make udelay() less > than accurate. What if there is simply no timer to rely upon, as in those cases where interrupts are needed for time keeping to make progress? We should do better than simply saying "sorry your kernel should irradicate every udelay() usage to be reliable". And I mean "reliable" which is not exactly the same as "accurate". Reliable means "never *significantly* shorter". > Remember, it should be usable for _short_ delays on slow machines as > well as other stuff, and if we're going to start throwing stuff like > the above at it, it's going to become very inefficient. You said that udelay can be much longer than expected due to various reasons. You also said that the IRQ handler overhead during udelay calibration makes actual delays slightli shorter than expected. I'm suggesting the addition of a slight overhead that is much smaller than the IRQ handler here. That shouldn't impact things masurably. I'd certainly like Doug to run his udelay timing test with the following patch to see if it solves the problem. --- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h index dff714d886..74fb571a55 100644 --- a/arch/arm/include/asm/delay.h +++ b/arch/arm/include/asm/delay.h @@ -57,11 +57,6 @@ extern void __bad_udelay(void); __const_udelay((n) * UDELAY_MULT)) : \ __udelay(n)) -/* Loop-based definitions for assembly code. */ -extern void __loop_delay(unsigned long loops); -extern void __loop_udelay(unsigned long usecs); -extern void __loop_const_udelay(unsigned long); - /* Delay-loop timer registration. */ #define ARCH_HAS_READ_CURRENT_TIMER extern void register_current_timer_delay(const struct delay_timer *timer); diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c index 5306de3501..9150d31c2d 100644 --- a/arch/arm/lib/delay.c +++ b/arch/arm/lib/delay.c @@ -25,6 +25,11 @@ #include #include +/* Loop-based definitions for assembly code. */ +extern void __loop_delay(unsigned long loops); +extern void __loop_udelay(unsigned long usecs); +extern void __loop_const_udelay(unsigned long); + /* * Default to the loop-based delay implementation. */ @@ -34,6 +39,85 @@ struct arm_delay_ops arm_delay_ops = { .udelay = __loop_udelay, }; +#if defined(CONFIG_CPU_FREQ) && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)) + +#include + +/* + * Another CPU/thread might increase the CPU clock in the middle of + * the loop based delay routine and the newly scaled LPJ value won't be + * accounted for, resulting in a possibly significantly shorter delay than + * expected. Let's make sure this occurrence is trapped and compensated. + */ + +static int __loop_seq; +static unsigned int __loop_security_factor; + +#define __safe_loop_(type) \ +static void __safe_loop_##type(unsigned long val) \ +{ \ + int seq_count = __loop_seq; \ + __loop_##type(val); \ + if (seq_count != __loop_seq) \ + __loop_##type(val * __loop_security_factor); \ +} + +__safe_loop_(delay) +__safe_loop_(const_udelay) +__safe_loop_(udelay) + +static int cpufreq_callback(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct cpufreq_freqs *freq = data; + unsigned int f; + + if ((freq->flags & CPUFREQ_CONST_LOOPS) || + freq->old >= freq->new) + return NOTIFY_OK; + + switch (val) { + case CPUFREQ_PRECHANGE: + /* Remember the largest security factor ever needed */ + f = DIV_ROUND_UP(freq->new, freq->old) - 1; + if (__loop_security_factor < f) + __loop_security_factor = f; + /* fallthrough */ + case CPUFREQ_POSTCHANGE: + __loop_seq++; + } + return NOTIFY_OK; +} + +static struct notifier_block cpufreq_notifier = { + .notifier_call = cpufreq_callback, +}; + +static int __init init_safe_loop_delays(void) +{ + int err; + + /* + * Bail out if the default loop based implementation has + * already been replaced by something better. + */ + if (arm_delay_ops.udelay != __loop_udelay) + return 0; + + __loop_security_factor = 1; + err = cpufreq_register_notifier(&cpufreq_notifier, + CPUFREQ_TRANSITION_NOTIFIER); + if (!err) { + arm_delay_ops.delay = __safe_loop_delay; + arm_delay_ops.const_udelay = __safe_loop_const_udelay; + arm_delay_ops.udelay = __safe_loop_udelay; + } + return err; +} +core_initcall(init_safe_loop_delays); + +#endif + static const struct delay_timer *delay_timer; static bool delay_calibrated;