From patchwork Thu Mar 22 10:40:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas Stach X-Patchwork-Id: 10301219 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BADBD60349 for ; Thu, 22 Mar 2018 10:40:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AE32729B12 for ; Thu, 22 Mar 2018 10:40:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ACBA529B30; Thu, 22 Mar 2018 10:40:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2CA4729B31 for ; Thu, 22 Mar 2018 10:40:12 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 32A516E191; Thu, 22 Mar 2018 10:40:10 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by gabe.freedesktop.org (Postfix) with ESMTPS id A5B316E191 for ; Thu, 22 Mar 2018 10:40:08 +0000 (UTC) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7] helo=dude.pengutronix.de.) by metis.ext.pengutronix.de with esmtp (Exim 4.89) (envelope-from ) id 1eyxde-0008CT-My; Thu, 22 Mar 2018 11:40:06 +0100 From: Lucas Stach To: etnaviv@lists.freedesktop.org, dri-devel@lists.freedesktop.org Subject: [PATCH v2] drm/etnaviv: correct timeout calculation Date: Thu, 22 Mar 2018 11:40:05 +0100 Message-Id: <20180322104005.22945-1-l.stach@pengutronix.de> X-Mailer: git-send-email 2.16.1 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: l.stach@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: patchwork-lst@pengutronix.de, kernel@pengutronix.de, Russell King MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Russell King The old way did clamp the jiffy conversion and thus caused the timeouts to become negative after some time. Also it didn't work with userspace which actually fills the upper 32bits of the 64bit timestamp value. clock_gettime() is 32-bit on 32-bit architectures. Using 64-bit timespec math, like we do in this commit, means that when a wrap occurs, the specified timeout goes into the past and we can't request a timeout in the future. As the Linux implementation of CLOCK_MONOTONIC is reasonable and starts at 0, the first such timer wrap will occur after approx. 68 years of system uptime. Signed-off-by: Russell King Signed-off-by: Lucas Stach --- v2: - add Russell as author and add Sign-off - amend commit message to carry the overflow on 32bit issue --- drivers/gpu/drm/etnaviv/etnaviv_drv.h | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index ddb17ee565e9..17a43da98fb9 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -132,19 +133,27 @@ static inline bool fence_after_eq(u32 a, u32 b) return (s32)(a - b) >= 0; } +/* + * Etnaviv timeouts are specified wrt CLOCK_MONOTONIC, not jiffies. + * We need to calculate the timeout in terms of number of jiffies + * between the specified timeout and the current CLOCK_MONOTONIC time. + */ static inline unsigned long etnaviv_timeout_to_jiffies( const struct timespec *timeout) { - unsigned long timeout_jiffies = timespec_to_jiffies(timeout); - unsigned long start_jiffies = jiffies; - unsigned long remaining_jiffies; + struct timespec64 ts, to; + + to = timespec_to_timespec64(*timeout); + + ktime_get_ts64(&ts); + + /* timeouts before "now" have already expired */ + if (timespec64_compare(&to, &ts) <= 0) + return 0; - if (time_after(start_jiffies, timeout_jiffies)) - remaining_jiffies = 0; - else - remaining_jiffies = timeout_jiffies - start_jiffies; + ts = timespec64_sub(to, ts); - return remaining_jiffies; + return timespec64_to_jiffies(&ts); } #endif /* __ETNAVIV_DRV_H__ */