From patchwork Fri Jun 2 08:50:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 102394 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp889253vqr; Fri, 2 Jun 2023 02:06:03 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ55aPGHNmStXUDd5Az8S6eZMPDfA/cYGN88HuhBCTJ2vhXpK05/8sYk8dPmgagBvEdOb/n7 X-Received: by 2002:a17:902:e5c8:b0:1b0:3742:e732 with SMTP id u8-20020a170902e5c800b001b03742e732mr2020837plf.23.1685696763427; Fri, 02 Jun 2023 02:06:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685696763; cv=none; d=google.com; s=arc-20160816; b=nUHDjj5eF2oJOE74vkyGqd5YAmMLKOZGc43LvGqkaOybazK2vi/+/bCUGXa/z4YwdF G2NvF4Jfd1h6MXbs3gvLYEVIkY5O5oIbbJP3bXgjyFQr/J8/jInM2bP/TwNPA8vCQsCG 1xatq8F7rCPhwHiSbTm0ojEAKK29QWErlUiLa9jzuW392EsJPq2qB6LykGwz8QmE9txO kR9jUMOb57vS8vJVIbXxUoaMS4Wk2sHUcGYnmnA5HtMCntpOuApxOtbDVxBeIrvZxAHf AFrucIvpwhPoDibYl5lEPg9lNqRfBmUH9rCVw7vgM5oFFqcjm5sy/mtZQQwtSEqV7A7A Cvkw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=PkQBVPUAFZ5XEHFObGUj8TILXcCKIUCwq9u6TMBR4W8=; b=z61247o55ptjtW59TXEg+HHkRh1/7M3mVm0CXezf3xbp5PGsV9fEpDlo/Y0GnmXDfm pVTHC0lpW4T9o5aC3BoFprMnji4yX+sJyyVB69yPmia/j5rC67g89WF4RfCiLPffTmOS gcgn2ElN/oNcNjfF0WR4YVd4b3u+DZXKejw3laMZsYZaXfdERRDXyJ5lbARJwCA7+r3c nOdw9S8VHaz3UnUVje5eJjuIdxiHbg4T2/rCV4b3zQvgdwxrJKYwdsHjSBKgjhYOW5KL AcEU5uAmZ0b5WwjaTDC8bH5mZro877OJT58i3Na1yvqhhoG7Dd4OJEUnlqBsD0luXAzc uxgQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id c1-20020a170903234100b001aff514a8f0si572167plh.534.2023.06.02.02.05.51; Fri, 02 Jun 2023 02:06:03 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234253AbjFBIwW (ORCPT + 99 others); Fri, 2 Jun 2023 04:52:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51284 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234861AbjFBIvv (ORCPT ); Fri, 2 Jun 2023 04:51:51 -0400 Received: from xavier.telenet-ops.be (xavier.telenet-ops.be [IPv6:2a02:1800:120:4::f00:14]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7482F1722 for ; Fri, 2 Jun 2023 01:51:15 -0700 (PDT) Received: from ramsan.of.borg ([IPv6:2a02:1810:ac12:ed30:158c:2ccf:1f70:e136]) by xavier.telenet-ops.be with bizsmtp id 48qo2A0041tRZS8018qoDF; Fri, 02 Jun 2023 10:51:12 +0200 Received: from rox.of.borg ([192.168.97.57]) by ramsan.of.borg with esmtp (Exim 4.95) (envelope-from ) id 1q50UO-00BhYB-SP; Fri, 02 Jun 2023 10:50:48 +0200 Received: from geert by rox.of.borg with local (Exim 4.95) (envelope-from ) id 1q50Uh-00APxV-Vr; Fri, 02 Jun 2023 10:50:47 +0200 From: Geert Uytterhoeven To: Michael Turquette , Stephen Boyd , Yoshihiro Shimoda , Magnus Damm , Joerg Roedel , Robin Murphy Cc: Tomasz Figa , Sylwester Nawrocki , Will Deacon , Arnd Bergmann , Wolfram Sang , Dejin Zheng , Kai-Heng Feng , Nicholas Piggin , Heiko Carstens , Peter Zijlstra , Russell King , John Stultz , Thomas Gleixner , Tony Lindgren , Krzysztof Kozlowski , Tero Kristo , Ulf Hansson , "Rafael J . Wysocki" , Vincent Guittot , linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-renesas-soc@vger.kernel.org, linux-pm@vger.kernel.org, iommu@lists.linux.dev, linux-kernel@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH v3 2/7] iopoll: Do not use timekeeping in read_poll_timeout_atomic() Date: Fri, 2 Jun 2023 10:50:37 +0200 Message-Id: <3d2a2f4e553489392d871108797c3be08f88300b.1685692810.git.geert+renesas@glider.be> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_DNSWL_LOW,SPF_HELO_NONE,SPF_NONE, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767581169850862958?= X-GMAIL-MSGID: =?utf-8?q?1767581169850862958?= read_poll_timeout_atomic() uses ktime_get() to implement the timeout feature, just like its non-atomic counterpart. However, there are several issues with this, due to its use in atomic contexts: 1. When called in the s2ram path (as typically done by clock or PM domain drivers), timekeeping may be suspended, triggering the WARN_ON(timekeeping_suspended) in ktime_get(): WARNING: CPU: 0 PID: 654 at kernel/time/timekeeping.c:843 ktime_get+0x28/0x78 Calling ktime_get_mono_fast_ns() instead of ktime_get() would get rid of that warning. However, that would break timeout handling, as (at least on systems with an ARM architectured timer), the time returned by ktime_get_mono_fast_ns() does not advance while timekeeping is suspended. Interestingly, (on the same ARM systems) the time returned by ktime_get() does advance while timekeeping is suspended, despite the warning. 2. Depending on the actual clock source, and especially before a high-resolution clocksource (e.g. the ARM architectured timer) becomes available, time may not advance in atomic contexts, thus breaking timeout handling. Fix this by abandoning the idea that one can rely on timekeeping to implement timeout handling in all atomic contexts, and switch from a global time-based to a locally-estimated timeout handling. In most (all?) cases the timeout condition is exceptional and an error condition, hence any additional delays due to underestimating wall clock time are irrelevant. Signed-off-by: Geert Uytterhoeven Acked-by: Arnd Bergmann Reviewed-by: Tony Lindgren Reviewed-by: Ulf Hansson --- The first issue was seen with the rcar-sysc driver in the BSP, as the BSP contains modifications to the resume sequence of various PM Domains. v3: - Add Acked-by, Reviewed-by, - Add comment about not using timekeeping, and its impact, v2: - New. --- include/linux/iopoll.h | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h index 0417360a6db9b0d6..19a7b00baff43595 100644 --- a/include/linux/iopoll.h +++ b/include/linux/iopoll.h @@ -74,6 +74,10 @@ * Returns 0 on success and -ETIMEDOUT upon a timeout. In either * case, the last read value at @args is stored in @val. * + * This macro does not rely on timekeeping. Hence it is safe to call even when + * timekeeping is suspended, at the expense of an underestimation of wall clock + * time, which is rather minimal with a non-zero delay_us. + * * When available, you'll probably want to use one of the specialized * macros defined below rather than this macro directly. */ @@ -81,22 +85,30 @@ delay_before_read, args...) \ ({ \ u64 __timeout_us = (timeout_us); \ + s64 __left_ns = __timeout_us * NSEC_PER_USEC; \ unsigned long __delay_us = (delay_us); \ - ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ - if (delay_before_read && __delay_us) \ + u64 __delay_ns = __delay_us * NSEC_PER_USEC; \ + if (delay_before_read && __delay_us) { \ udelay(__delay_us); \ + if (__timeout_us) \ + __left_ns -= __delay_ns; \ + } \ for (;;) { \ (val) = op(args); \ if (cond) \ break; \ - if (__timeout_us && \ - ktime_compare(ktime_get(), __timeout) > 0) { \ + if (__timeout_us && __left_ns < 0) { \ (val) = op(args); \ break; \ } \ - if (__delay_us) \ + if (__delay_us) { \ udelay(__delay_us); \ + if (__timeout_us) \ + __left_ns -= __delay_ns; \ + } \ cpu_relax(); \ + if (__timeout_us) \ + __left_ns--; \ } \ (cond) ? 0 : -ETIMEDOUT; \ })