From patchwork Thu Feb 4 02:04:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 12066011 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C63E6C433E0 for ; Thu, 4 Feb 2021 02:04:09 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 73BD064E0F for ; Thu, 4 Feb 2021 02:04:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 73BD064E0F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D20326EC63; Thu, 4 Feb 2021 02:04:08 +0000 (UTC) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by gabe.freedesktop.org (Postfix) with ESMTPS id 941226EC63; Thu, 4 Feb 2021 02:04:07 +0000 (UTC) IronPort-SDR: jfwKdJuFjSsQ0sagsLE8OTILUIMwmCF5CEO/aiqq+zvW/4ZqJjtnp9cDJN8GCNh5eGQPa2hMhR 9i+dAecG9aig== X-IronPort-AV: E=McAfee;i="6000,8403,9884"; a="160319670" X-IronPort-AV: E=Sophos;i="5.79,399,1602572400"; d="scan'208";a="160319670" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Feb 2021 18:04:04 -0800 IronPort-SDR: UklALSy41EyEh3Lz6omN09oupx7ZFKXhxjhLLr9/x1hc2MKVAk3MzKn/e/jTv08N9/LKmkPxee WSwB6JpxYQCA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,399,1602572400"; d="scan'208";a="372718169" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.171]) by orsmga002.jf.intel.com with SMTP; 03 Feb 2021 18:04:01 -0800 Received: by stinkbox (sSMTP sendmail emulation); Thu, 04 Feb 2021 04:04:00 +0200 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Subject: [PATCH] drm/vblank: Avoid storing a timestamp for the same frame twice Date: Thu, 4 Feb 2021 04:04:00 +0200 Message-Id: <20210204020400.29628-1-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Daniel Vetter , intel-gfx@lists.freedesktop.org, Dhinakaran Pandiyan , Rodrigo Vivi Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Ville Syrjälä drm_vblank_restore() exists because certain power saving states can clobber the hardware frame counter. The way it does this is by guesstimating how many frames were missed purely based on the difference between the last stored timestamp vs. a newly sampled timestamp. If we should call this function before a full frame has elapsed since we sampled the last timestamp we would end up with a possibly slightly different timestamp value for the same frame. Currently we will happily overwrite the already stored timestamp for the frame with the new value. This could cause userspace to observe two different timestamps for the same frame (and the timestamp could even go backwards depending on how much error we introduce when correcting the timestamp based on the scanout position). To avoid that let's not update the stored timestamp unless we're also incrementing the sequence counter. We do still want to update vblank->last with the freshly sampled hw frame counter value so that subsequent vblank irqs/queries can actually use the hw frame counter to determine how many frames have elapsed. Cc: Dhinakaran Pandiyan Cc: Rodrigo Vivi Cc: Daniel Vetter Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_vblank.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 893165eeddf3..e127a7db2088 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -176,6 +176,17 @@ static void store_vblank(struct drm_device *dev, unsigned int pipe, vblank->last = last; + /* + * drm_vblank_restore() wants to always update + * vblank->last since we can't trust the frame counter + * across power saving states. But we don't want to alter + * the stored timestamp for the same frame number since + * that would cause userspace to potentially observe two + * different timestamps for the same frame. + */ + if (vblank_count_inc == 0) + return; + write_seqlock(&vblank->seqlock); vblank->time = t_vblank; atomic64_add(vblank_count_inc, &vblank->count);