From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 8A319CD98DA for ; Mon, 15 Jun 2026 20:18:44 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DBAE710E63F; Mon, 15 Jun 2026 20:18:38 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=lankhorst.se header.i=@lankhorst.se header.b="AGnJ5kJk"; dkim-atps=neutral Received: from lankhorst.se (unknown [141.105.120.124]) by gabe.freedesktop.org (Postfix) with ESMTPS id 977BD10E636; Mon, 15 Jun 2026 20:18:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=lankhorst.se; s=default; t=1781554716; bh=xF/Z0Myz+A8ZRO9Nq1ZV67SO0YqRqvq7QO8j8B3ElGg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AGnJ5kJkMafZV7peQQ+SOR7yV1iNEmOsv06CyIoYoeQpySSVwbpce+Ho/gwFiStlm 04wAwZL4bn8EDjfMUeGhG5bpAfpAnYSReyJtU4gk/9DoLNNvLMEcIRqgjn1iuh71Fd eH1NH9KvlrAyXcwBur8v9cZz9AEQCsd5wFcFSlFGN3I0otDx2XpTstyYvD20EzqxtF t2Wz98nkwpxaeS/5aTbbfoJh3vxH/XrmbCHxg75/WLL80Cs/NrkoUXwFAYP8OgFVsk haccvJ5Iy6DkBfKQZd3fyAIFq81LmVJ310cVha3natnbMn+RGluAnC5Y4O0ALXhgJ1 tnc+UHJgcbCKg== From: Maarten Lankhorst To: intel-xe@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org, Maarten Lankhorst Subject: [PATCH v8 06/27] drm/i915/display: Remove locking from intel_vblank_evade critical section Date: Mon, 15 Jun 2026 22:18:24 +0200 Message-ID: <20260615201846.307297-7-dev@lankhorst.se> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260615201846.307297-1-dev@lankhorst.se> References: <20260615201846.307297-1-dev@lankhorst.se> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" finish_wait() may take a lock, which means that it can take any amount of time. On PREEMPT-RT we should not be taking any lock after disabling preemption, so ensure that the completion is done before disabling interrupts. This also has the benefit of making vblank evasion more deterministic, by performing the final vblank check after all locking is done. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_crtc.c | 2 +- drivers/gpu/drm/i915/display/intel_vblank.c | 30 +++++++++------------ drivers/gpu/drm/i915/display/intel_vblank.h | 1 + 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 34a159f7c9a43..8218938985b41 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -734,7 +734,7 @@ void intel_pipe_update_end(struct intel_atomic_state *state, struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); enum pipe pipe = crtc->pipe; - int scanline_end = intel_get_crtc_scanline(crtc); + int scanline_end = __intel_get_crtc_scanline(crtc); u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc); ktime_t end_vbl_time = ktime_get(); diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c index 28d81199792ef..ca08059e088ea 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c @@ -241,7 +241,7 @@ int intel_crtc_scanline_offset(const struct intel_crtc_state *crtc_state) * intel_de_read_fw(), only for fast reads of display block, no need for * forcewake etc. */ -static int __intel_get_crtc_scanline(struct intel_crtc *crtc) +int __intel_get_crtc_scanline(struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base); @@ -732,6 +732,16 @@ void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state, evade->min -= vblank_delay; } +static bool scanline_in_safe_range(struct intel_vblank_evade_ctx *evade, int *scanline, bool unlocked) +{ + if (unlocked) + *scanline = intel_get_crtc_scanline(evade->crtc); + else + *scanline = __intel_get_crtc_scanline(evade->crtc); + + return *scanline < evade->min || *scanline > evade->max; +} + /* must be called with vblank interrupt already enabled! */ int intel_vblank_evade(struct intel_vblank_evade_ctx *evade) { @@ -739,24 +749,12 @@ int intel_vblank_evade(struct intel_vblank_evade_ctx *evade) struct intel_display *display = to_intel_display(crtc); long timeout = msecs_to_jiffies_timeout(1); wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); - DEFINE_WAIT(wait); int scanline; if (evade->min <= 0 || evade->max <= 0) return 0; - for (;;) { - /* - * prepare_to_wait() has a memory barrier, which guarantees - * other CPUs can see the task state update by the time we - * read the scanline. - */ - prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); - - scanline = intel_get_crtc_scanline(crtc); - if (scanline < evade->min || scanline > evade->max) - break; - + while (!scanline_in_safe_range(evade, &scanline, false)) { if (!timeout) { drm_dbg_kms(display->drm, "Potential atomic update failure on pipe %c\n", @@ -766,13 +764,11 @@ int intel_vblank_evade(struct intel_vblank_evade_ctx *evade) local_irq_enable(); - timeout = schedule_timeout(timeout); + timeout = wait_event_timeout(*wq, scanline_in_safe_range(evade, &scanline, true), timeout); local_irq_disable(); } - finish_wait(wq, &wait); - /* * On VLV/CHV DSI the scanline counter would appear to * increment approx. 1/3 of a scanline before start of vblank. diff --git a/drivers/gpu/drm/i915/display/intel_vblank.h b/drivers/gpu/drm/i915/display/intel_vblank.h index 98d04cacd65f8..aa1974400e9fc 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.h +++ b/drivers/gpu/drm/i915/display/intel_vblank.h @@ -38,6 +38,7 @@ u32 g4x_get_vblank_counter(struct drm_crtc *crtc); bool intel_crtc_get_vblank_timestamp(struct drm_crtc *crtc, int *max_error, ktime_t *vblank_time, bool in_vblank_irq); int intel_get_crtc_scanline(struct intel_crtc *crtc); +int __intel_get_crtc_scanline(struct intel_crtc *crtc); void intel_wait_for_pipe_scanline_stopped(struct intel_crtc *crtc); void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc); void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state, -- 2.53.0