Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp3104192ybi; Thu, 18 Jul 2019 21:06:31 -0700 (PDT) X-Google-Smtp-Source: APXvYqx/RILugeU3HMU+Aww9fF8XF+/yP8AuAPRtHfK6dYddBBsSFOanDYV3VVLhXK34qQSkgZLv X-Received: by 2002:a17:902:5ac4:: with SMTP id g4mr55565491plm.80.1563509191524; Thu, 18 Jul 2019 21:06:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1563509191; cv=none; d=google.com; s=arc-20160816; b=j2SblTITLvN0QBmh5BIXZbxrO4w7Ipwe5bqG+oJ3QChfLUufnXLXKPL+dK41+L36Jo XQmD2O0//38K8lTn9MrxdsX/+FYXzO5gThyz5ALXz0NRKNn1vn2M6fmmkLY0WUJuuF7K Cx3P0+s6WFm/pOuQpGMpntJhvAj4wyNFkfS3o8pYMYaS2N8IbP6I1shJO9UGfUcJuZSF mLVgBHmrrt4Hl8Ib8+r8q+7d3Uonl2Ki/KAOPNRkI0nkCz0YTaRednxFMaqf+EDEABva pWLhmtLhIaVY8WUzv/0s2oqldXmO9/gn7AjFNHEs5+Y7KHotVeVZAGsRyegYk7mrgWj4 mY1A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=p3u/DReAPvLhnyakBQSs8dZ6oJwNb7P5EskgzX2RJUQ=; b=m+mzqsNenTnKmWnn4zJLRBbK2cmAqYr5Pj5P/JAlB7Gs4TmHlA8Q1aHzVh2vOkesrv 3Niacu1lfdkrebuBynvtJzm66nkjnFn/zPGu2Nin1PYn9nubtYEelL/wlMyMvOueBm60 btstl9NmUPJ0aRzgXsqxjMwT+b+Stffz9YklZ+XBpIVYfoWK//9noTWAu4ql1KtTrEq1 nGNNqwF8lh/UgLzQJoBt/YTcwtz0ElD5VjtpXKcRpsmDr54d9kQ01fZ1aO8nQikXjAJG p2pyWuiHkZ0GGDiq5cRO+6rohK5pLVMsQOSk1BrbxFPIxZYJDaFsp25E3APzSAXIPZ2S W8Gg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=gG92Eaf4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h9si524710pgp.435.2019.07.18.21.06.16; Thu, 18 Jul 2019 21:06:31 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=gG92Eaf4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729765AbfGSED6 (ORCPT + 99 others); Fri, 19 Jul 2019 00:03:58 -0400 Received: from mail.kernel.org ([198.145.29.99]:36034 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729690AbfGSED4 (ORCPT ); Fri, 19 Jul 2019 00:03:56 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 05796218A3; Fri, 19 Jul 2019 04:03:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1563509034; bh=KLNygqYyFHSspqiGbQoEEhnB0BiMvRcyv/HVld6ouGY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gG92Eaf41xslAw5ZuRsfh3CNcCGf7LtU/QhL4z6rbN1kEtdsIrK5I1ygbhj3+39zH LJ9/UoL4yKlb8KIYdmOs1X5Za6zU72p8Ojzzt4p6EsRnzhAqZu8Rks4M/IYekL2qcd 44XblHDPC8JmCOnU+yNf59bX3fNoCmts6013jx7M= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Daniel Vetter , Shayenne Moura , Rodrigo Siqueira , Daniel Vetter , Sasha Levin , dri-devel@lists.freedesktop.org Subject: [PATCH AUTOSEL 5.1 033/141] drm/vkms: Forward timer right after drm_crtc_handle_vblank Date: Fri, 19 Jul 2019 00:00:58 -0400 Message-Id: <20190719040246.15945-33-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190719040246.15945-1-sashal@kernel.org> References: <20190719040246.15945-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Daniel Vetter [ Upstream commit 7355965da22b8d9ebac8bce4b776399fb0bb9d32 ] In commit def35e7c592616bc09be328de8795e5e624a3cf8 Author: Shayenne Moura Date: Wed Jan 30 14:06:36 2019 -0200 drm/vkms: Bugfix extra vblank frame we fixed the vblank counter to give accurate results outside of drm_crtc_handle_vblank, which fixed bugs around vblank timestamps being off-by-one and causing the vblank counter to jump when it shouldn't. The trouble is that this completely broke crc generation. Shayenne and Rodrigo tracked this down to the vblank timestamp going backwards in time somehow. Which then resulted in an underflow in drm_vblank.c code, which resulted in all kinds of things breaking really badly. The reason for this is that once we've called drm_crtc_handle_vblank and the hrtimer isn't forwarded yet, we're returning a vblank timestamp in the past. This race is really hard to hit since it's small, except when you enable crc generation: In that case there's a call to drm_crtc_accurate_vblank right in-betwen, so we're guaranteed to hit the bug. The fix is to roll the hrtimer forward _before_ we do the vblank processing (which has a side-effect of incrementing the vblank counter), and we always subtract one frame from the hrtimer - since now it's always one frame in the future. To make sure we don't hit this again also add a WARN_ON checking for whether our timestamp is somehow moving into the past, which is never should. This also aligns more with how real hw works: 1. first all registers are updated with the new timestamp/vblank counter values. 2. then an interrupt is generated 3. kernel interrupt handler eventually fires. So doing this aligns vkms closer with what drm_vblank.c expects. Document this also in a comment. Cc: Shayenne Moura Cc: Rodrigo Siqueira Signed-off-by: Daniel Vetter Tested-by: Rodrigo Siqueira Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira Link: https://patchwork.freedesktop.org/patch/msgid/20190606084404.12014-1-daniel.vetter@ffwll.ch Signed-off-by: Sasha Levin --- drivers/gpu/drm/vkms/vkms_crtc.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 8a9aeb0a9ea8..0947a9f75c79 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -15,6 +15,10 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) spin_lock(&output->lock); + ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer, + output->period_ns); + WARN_ON(ret_overrun != 1); + ret = drm_crtc_handle_vblank(crtc); if (!ret) DRM_ERROR("vkms failure on handling vblank"); @@ -35,10 +39,6 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) DRM_WARN("failed to queue vkms_crc_work_handle"); } - ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer, - output->period_ns); - WARN_ON(ret_overrun != 1); - spin_unlock(&output->lock); return HRTIMER_RESTART; @@ -74,11 +74,21 @@ bool vkms_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, { struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev); struct vkms_output *output = &vkmsdev->output; + struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; *vblank_time = output->vblank_hrtimer.node.expires; - if (!in_vblank_irq) - *vblank_time -= output->period_ns; + if (WARN_ON(*vblank_time == vblank->time)) + return true; + + /* + * To prevent races we roll the hrtimer forward before we do any + * interrupt processing - this is how real hw works (the interrupt is + * only generated after all the vblank registers are updated) and what + * the vblank core expects. Therefore we need to always correct the + * timestampe by one frame. + */ + *vblank_time -= output->period_ns; return true; } -- 2.20.1