Received: by 10.192.165.156 with SMTP id m28csp1273327imm; Wed, 11 Apr 2018 16:01:09 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/5SbAN8mlMWt1rD7glYUWA+VGdPVj5V9HgCwxQsKU5qqXIvhhCPnxO9GUW8k2EEdNlXkjw X-Received: by 2002:a17:902:7d10:: with SMTP id z16-v6mr4741941pll.79.1523487669840; Wed, 11 Apr 2018 16:01:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1523487669; cv=none; d=google.com; s=arc-20160816; b=OTr5tnorRwhP8woxay+KzO3h97cJo+woZmjWCUAm5mxKccM9CKXy4x4AFAF0tpTp2r 8nfICDAsWVLmVKMhblCFWDodU2s6Ra0L2O+8N03u/B4GcLthuSOH3BSG7/0kZssrumbK t4Nn3OHfq6840im/NBiMB6XZ4KTIx14e9KuG2FxuW/XSoOP/728eSga5g1PMHATxMnpy CJVQ4tUm0Uwhmy0l21QkAeo2Uzu7YX2a1MkWq87K9BbnGxGYSYzExkS0wDQfa1hEBKaH f0K5CDMEfjGB37qM3pVvDFFEAMptchnmpYtqqGaTXH0noIVBHkg2eIN86F0pXtE152YY FSIQ== 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 :arc-authentication-results; bh=G5OWdWBGuiUc5UWc7qCv7sEih2c79OLyi+T2/1EJ92g=; b=ycPp3cBp7US8sJW0vikeVqamE9f7YY9k59eFPcvLMJ1hT0RwHwQfXTMhaxF8uFgErb Dk9zhSROBaswolGqNwrmanHsz2h/VhKvFVZgpd6gNQ/1lSiP4JMc6OI6ojKkgmHzsiqd m6QeVCLpf2cqIi9VFbRXqjdZRRFtIfmINr5CMQ1giE7c6uJda6MGcZiUVwQyqFk1gZgx Xr0MEKf795mcBu1MyClGaLi/se5+rv+7HJSlNHBDYcrPByUJSt7sUV7Wt0acZL46lmfO t7HNb8g5yauL+4T3ymC2TJ4+k8dLmd0kn4VeiEC27czW5tXOH+UzcasjM91+DUEu/pEA qzxQ== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a24si1524582pff.256.2018.04.11.16.00.31; Wed, 11 Apr 2018 16:01:09 -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; 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=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752894AbeDKW4n (ORCPT + 99 others); Wed, 11 Apr 2018 18:56:43 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:58372 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752662AbeDKWzf (ORCPT ); Wed, 11 Apr 2018 18:55:35 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8B18E11E2F3; Wed, 11 Apr 2018 22:55:34 +0000 (UTC) Received: from malachite.bss.redhat.com (dhcp-10-20-1-55.bss.redhat.com [10.20.1.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 362832026985; Wed, 11 Apr 2018 22:55:34 +0000 (UTC) From: Lyude Paul To: intel-gfx@lists.freedesktop.org Cc: Manasi Navare , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi , David Airlie , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH v7 08/10] drm/i915: Make intel_dp_mst_atomic_check() idempotent Date: Wed, 11 Apr 2018 18:54:45 -0400 Message-Id: <20180411225501.26751-9-lyude@redhat.com> In-Reply-To: <20180411225501.26751-1-lyude@redhat.com> References: <20180411225501.26751-1-lyude@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Wed, 11 Apr 2018 22:55:34 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Wed, 11 Apr 2018 22:55:34 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'lyude@redhat.com' RCPT:'' Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The current way of handling changing VCPI allocations doesn't make a whole ton of sense. Since drm_atomic_helper_check_modeset() can be called multiple times which means that intel_dp_mst_atomic_check() can also be called multiple times. However, since we make the silly mistake of trying to free VCPI slots based off the /new/ atomic state instead of the old atomic state, we'll end up potentially double freeing the vcpi slots for the ports. This also has another unintended consequence that came back up while implementing MST fallback retraining: if a modeset is forced on a connector that's already part of the state, but it's atomic_check() has already been run once and doesn't get run again, we'll end up not freeing the VCPI allocations on the connector at all. The easiest way to solve this is to be clever and, with the exception of connectors that are being disabled and thus will never have compute_config() ran on them, move vcpi freeing out of the atomic check and into compute_config(). Cc: Manasi Navare Cc: Ville Syrjälä Signed-off-by: Lyude Paul V7: - Fix CHECKPATCH errors Signed-off-by: Lyude Paul --- drivers/gpu/drm/i915/intel_dp_mst.c | 84 +++++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 19de0b5a7a40..31b37722cd89 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -30,6 +30,38 @@ #include #include +static int +intel_dp_mst_atomic_release_vcpi_slots(struct drm_atomic_state *state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct drm_crtc_state *new_crtc_state; + struct intel_crtc_state *intel_crtc_state = + to_intel_crtc_state(crtc_state); + struct drm_encoder *encoder; + struct drm_dp_mst_topology_mgr *mgr; + int slots, ret; + + slots = intel_crtc_state->dp_m_n.tu; + if (slots <= 0) + return 0; + + encoder = conn_state->best_encoder; + mgr = &enc_to_mst(encoder)->primary->dp.mst_mgr; + + ret = drm_dp_atomic_release_vcpi_slots(state, mgr, slots); + if (ret) { + DRM_DEBUG_KMS("failed releasing %d vcpi slots:%d\n", + slots, ret); + } else { + new_crtc_state = drm_atomic_get_crtc_state(state, + crtc_state->crtc); + to_intel_crtc_state(new_crtc_state)->dp_m_n.tu = 0; + } + + return ret; +} + static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) @@ -44,10 +76,14 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, struct drm_dp_mst_topology_state *mst_state = drm_atomic_dp_mst_get_topology_state(state, &intel_dp->mst_mgr); struct intel_dp_mst_topology_state *intel_mst_state; + struct drm_connector_state *old_conn_state = + drm_atomic_get_old_connector_state(state, &connector->base); + struct drm_crtc *old_crtc; int bpp; int slots; const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; int mst_pbn; + int ret; bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_LIMITED_M_N); @@ -80,6 +116,21 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp); pipe_config->pbn = mst_pbn; + /* Free any VCPI allocations on this connector from the previous + * state + */ + old_crtc = old_conn_state->crtc; + if (old_crtc) { + struct drm_crtc_state *old_crtc_state = + drm_atomic_get_old_crtc_state(state, old_crtc); + + ret = intel_dp_mst_atomic_release_vcpi_slots(state, + old_crtc_state, + old_conn_state); + if (ret) + return ret; + } + slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr, connector->port, mst_pbn); if (slots < 0) { @@ -109,31 +160,22 @@ static int intel_dp_mst_atomic_check(struct drm_connector *connector, { struct drm_atomic_state *state = new_conn_state->state; struct drm_connector_state *old_conn_state; - struct drm_crtc *old_crtc; - struct drm_crtc_state *crtc_state; - int slots, ret = 0; + struct drm_crtc_state *new_crtc_state; + int ret = 0; old_conn_state = drm_atomic_get_old_connector_state(state, connector); - old_crtc = old_conn_state->crtc; - if (!old_crtc) - return ret; - crtc_state = drm_atomic_get_new_crtc_state(state, old_crtc); - slots = to_intel_crtc_state(crtc_state)->dp_m_n.tu; - if (drm_atomic_crtc_needs_modeset(crtc_state) && slots > 0) { - struct drm_dp_mst_topology_mgr *mgr; - struct drm_encoder *old_encoder; - - old_encoder = old_conn_state->best_encoder; - mgr = &enc_to_mst(old_encoder)->primary->dp.mst_mgr; + /* Only free VCPI here if we're not going to be detaching the + * connector's current CRTC, since no config will be computed + */ + if (new_conn_state->crtc || !old_conn_state->crtc) + return ret; - ret = drm_dp_atomic_release_vcpi_slots(state, mgr, slots); - if (ret) - DRM_DEBUG_KMS("failed releasing %d vcpi slots:%d\n", slots, ret); - else - to_intel_crtc_state(crtc_state)->dp_m_n.tu = 0; - } - return ret; + new_crtc_state = drm_atomic_get_new_crtc_state(state, + old_conn_state->crtc); + return intel_dp_mst_atomic_release_vcpi_slots(state, + new_crtc_state, + old_conn_state); } static void intel_mst_disable_dp(struct intel_encoder *encoder, -- 2.14.3