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 185FDEB1067 for ; Tue, 10 Mar 2026 11:57:36 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 07CF310E28E; Tue, 10 Mar 2026 11:57:28 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=lankhorst.se header.i=@lankhorst.se header.b="MoX3F0gk"; dkim-atps=neutral Received: from lankhorst.se (unknown [141.105.120.124]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6471110E27E; Tue, 10 Mar 2026 11:57:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=lankhorst.se; s=default; t=1773143846; bh=DLbtDzPUzGBKCRN3ajcwkSfLaaYYbYIvLJsGpVhl8jk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MoX3F0gkEXy95OMaFnU7pi0YIFfYg94ymzA1APfsSfu96xodC9ZCp99RtkL/69XxU JC7Tjvs3K7z1u3k+ImGAD9bB19zcpDFDE/q6PEunLHaWlztdiqN13u53QUP0KdMg/C mnKrPd/gOIV/MtGn5cjqBuEDGxmQFFHr0naLu1uDTaVNowu8gqxg8OEOyca6UBps+7 203k2hoOSY3reSQM0+UnstXQrbAVq530ic/TrVKnpSldTHvVQgPWjABzUU9j4C60TS Gj5pXQsnh0Ti8ifK6xwTmE0/6Y0vw/XuRTjR81H9PovFihkv5o+RVQl+6+28KaQ/TC qh/9CONkX7r2A== From: Maarten Lankhorst To: intel-xe@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org, Maarten Lankhorst Subject: [PATCH v7 06/26] drm/i915/display: Remove locking from intel_vblank_evade critical section Date: Tue, 10 Mar 2026 12:56:48 +0100 Message-ID: <20260310115709.2276203-7-dev@lankhorst.se> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260310115709.2276203-1-dev@lankhorst.se> References: <20260310115709.2276203-1-dev@lankhorst.se> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 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 ca85b6fe50c6f..1022c2cf4eec2 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -688,7 +688,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 1b7cfe226ff8f..73676d8ccec8b 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.51.0