Received: by 2002:a05:6a10:6744:0:0:0:0 with SMTP id w4csp306933pxu; Thu, 15 Oct 2020 04:37:34 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzq00eWHTXLSxBuIhvNgpwIhyZSEbiCxyIW0R4nDoliLL+JtsI+iV2K9vk1ofxtLhs37GGm X-Received: by 2002:a17:906:2f85:: with SMTP id w5mr3891107eji.1.1602761854414; Thu, 15 Oct 2020 04:37:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1602761854; cv=none; d=google.com; s=arc-20160816; b=ucwDm2++JSodyabvR1WejBIpkLaqJtXshLwB1Ef9LnztaOOjNTfrHxIxHVgL+KdotH /V51n4++FtqDazXV9zfJFa/f/4b0wioGjzPKi5U2sIXDais9I1vcjMh/vv/m+xyRVrFw 7qDg6nOjQU014QLpqzZXiIZNwb3+iYndBlNRaglmIZbW1dmTRHFGgvRBfRReBjUJEt9H ALhO/G9LGEaEGQ9QoA09zrjAHG72XJUtBuc3k94h8PjKWmkN3EZL7hsHAzW+zM9lgfzl jY1UnlhU875u5PkuEfrA6o11V1Zl6zo4xAtMWkL1Hh+vXzLhyXnjWDNVhff2q0uK+g1P DqXQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:message-id:date:subject:cc:to:from; bh=nVcQyyPDAPLZ67YWtaur7kv3EbUa4X0VvMPywCPLkos=; b=Evsv2cDpczvnH4Ce7SE4F0rlZKn697CES4j3pb073WHhbbRQSbO48z+j84CpkgPerx ftfOzgUv3NfUGvOwzqP3j/kxkk7A5S2IdjcTVZj9BwsKzE8Rp2AAhBUoNtnC7sJLhNlv iCDJFXQ4+HvPyalGvq1x+k8s14sGoXPM64CypUZsYB1u7/8f6sUdinvHhL5QB0pWGsO3 uG5UcLodOXYxo02pxlLeZ+sJE/P/8Bw0kCVPqQ+7E+nZIBPaJTgnl8tDWMib4QE7g8O0 Mb8d7iYwDGw/IHfEgiMdiUXImYCVLawQaJOTaurczYwSzuAz58ybRon36VBjGjgbTKCF w+JQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h26si1734597edz.138.2020.10.15.04.37.09; Thu, 15 Oct 2020 04:37:34 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730552AbgJOJPf (ORCPT + 99 others); Thu, 15 Oct 2020 05:15:35 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:61358 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726111AbgJOJPf (ORCPT ); Thu, 15 Oct 2020 05:15:35 -0400 Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 15 Oct 2020 02:15:34 -0700 X-QCInternal: smtphost Received: from ironmsg02-blr.qualcomm.com ([10.86.208.131]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/AES256-SHA; 15 Oct 2020 02:15:32 -0700 X-QCInternal: smtphost Received: from mkrishn-linux.qualcomm.com ([10.204.66.35]) by ironmsg02-blr.qualcomm.com with ESMTP; 15 Oct 2020 14:45:13 +0530 Received: by mkrishn-linux.qualcomm.com (Postfix, from userid 438394) id E4DC5214B6; Thu, 15 Oct 2020 14:45:11 +0530 (IST) From: Krishna Manikandan To: dri-devel@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, devicetree@vger.kernel.org Cc: Krishna Manikandan , linux-kernel@vger.kernel.org, robdclark@gmail.com, seanpaul@chromium.org, hoegsberg@chromium.org, kalyan_t@codeaurora.org, dianders@chromium.org Subject: [v2] drm/msm: Fix race condition in msm driver with async layer updates Date: Thu, 15 Oct 2020 14:45:10 +0530 Message-Id: <1602753310-22105-1-git-send-email-mkrishn@codeaurora.org> X-Mailer: git-send-email 2.7.4 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When there are back to back commits with async cursor update, there is a case where second commit can program the DPU hw blocks while first didn't complete flushing config to HW. Synchronize the compositions such that second commit waits until first commit flushes the composition. This change also introduces per crtc commit lock, such that commits on different crtcs are not blocked by each other. Changes in v2: - Use an array of mutexes in kms to handle commit lock per crtc. (Rob Clark) Signed-off-by: Krishna Manikandan --- drivers/gpu/drm/msm/msm_atomic.c | 32 +++++++++++++++++++------------- drivers/gpu/drm/msm/msm_kms.h | 6 ++++-- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 561bfa4..f9bd472 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -61,10 +61,10 @@ static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx) trace_msm_atomic_async_commit_start(crtc_mask); - mutex_lock(&kms->commit_lock); + mutex_lock(&kms->commit_lock[crtc_idx]); if (!(kms->pending_crtc_mask & crtc_mask)) { - mutex_unlock(&kms->commit_lock); + mutex_unlock(&kms->commit_lock[crtc_idx]); goto out; } @@ -79,7 +79,6 @@ static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx) */ trace_msm_atomic_flush_commit(crtc_mask); kms->funcs->flush_commit(kms, crtc_mask); - mutex_unlock(&kms->commit_lock); /* * Wait for flush to complete: @@ -90,9 +89,8 @@ static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx) vblank_put(kms, crtc_mask); - mutex_lock(&kms->commit_lock); kms->funcs->complete_commit(kms, crtc_mask); - mutex_unlock(&kms->commit_lock); + mutex_unlock(&kms->commit_lock[crtc_idx]); kms->funcs->disable_commit(kms); out: @@ -171,6 +169,16 @@ static unsigned get_crtc_mask(struct drm_atomic_state *state) return mask; } +static int get_crtc_id(struct msm_kms *kms, unsigned int crtc_mask) +{ + struct drm_crtc *crtc; + + for_each_crtc_mask(kms->dev, crtc, crtc_mask) + return drm_crtc_index(crtc); + + return 0; +} + void msm_atomic_commit_tail(struct drm_atomic_state *state) { struct drm_device *dev = state->dev; @@ -180,6 +188,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) unsigned crtc_mask = get_crtc_mask(state); bool async = kms->funcs->vsync_time && can_do_async(state, &async_crtc); + int crtc_idx = get_crtc_id(kms, crtc_mask); trace_msm_atomic_commit_tail_start(async, crtc_mask); @@ -189,12 +198,11 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) * Ensure any previous (potentially async) commit has * completed: */ + mutex_lock(&kms->commit_lock[crtc_idx]); trace_msm_atomic_wait_flush_start(crtc_mask); kms->funcs->wait_flush(kms, crtc_mask); trace_msm_atomic_wait_flush_finish(crtc_mask); - mutex_lock(&kms->commit_lock); - /* * Now that there is no in-progress flush, prepare the * current update: @@ -232,8 +240,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) } kms->funcs->disable_commit(kms); - mutex_unlock(&kms->commit_lock); - + mutex_unlock(&kms->commit_lock[crtc_idx]); /* * At this point, from drm core's perspective, we * are done with the atomic update, so we can just @@ -260,8 +267,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) */ trace_msm_atomic_flush_commit(crtc_mask); kms->funcs->flush_commit(kms, crtc_mask); - mutex_unlock(&kms->commit_lock); - + mutex_unlock(&kms->commit_lock[crtc_idx]); /* * Wait for flush to complete: */ @@ -271,9 +277,9 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) vblank_put(kms, crtc_mask); - mutex_lock(&kms->commit_lock); + mutex_lock(&kms->commit_lock[crtc_idx]); kms->funcs->complete_commit(kms, crtc_mask); - mutex_unlock(&kms->commit_lock); + mutex_unlock(&kms->commit_lock[crtc_idx]); kms->funcs->disable_commit(kms); drm_atomic_helper_commit_hw_done(state); diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index 1cbef6b..2049847 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -155,7 +155,7 @@ struct msm_kms { * For async commit, where ->flush_commit() and later happens * from the crtc's pending_timer close to end of the frame: */ - struct mutex commit_lock; + struct mutex commit_lock[MAX_CRTCS]; unsigned pending_crtc_mask; struct msm_pending_timer pending_timers[MAX_CRTCS]; }; @@ -165,7 +165,9 @@ static inline void msm_kms_init(struct msm_kms *kms, { unsigned i; - mutex_init(&kms->commit_lock); + for (i = 0; i < ARRAY_SIZE(kms->commit_lock); i++) + mutex_init(&kms->commit_lock[i]); + kms->funcs = funcs; for (i = 0; i < ARRAY_SIZE(kms->pending_timers); i++) -- 2.7.4