Received: by 2002:a25:31c3:0:0:0:0:0 with SMTP id x186csp3712242ybx; Mon, 4 Nov 2019 01:31:31 -0800 (PST) X-Google-Smtp-Source: APXvYqy7C4r2nxrWizAt8TgIccpz5R+STMxh2/jd/AKv8tdpt4hIbJ/rX9OB/SCIVCNkD9kOvqi8 X-Received: by 2002:a17:906:b74c:: with SMTP id fx12mr15073438ejb.324.1572859891736; Mon, 04 Nov 2019 01:31:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1572859891; cv=none; d=google.com; s=arc-20160816; b=fUDxj7eVdozhq03N7p1EYSrNCFg8My4BgZTvR2YNcqZtRSgyHAWZB5y+g0UF7Qb5h7 2mpbL16eL1eYnWmgOQmKWmlRsP7FkKGibuGnZNDVFdJ78NxZ8xB345voj4SZ050iQ14J XDbgvZ36bm1JO8ILQR7S3LrPqbyh4UIDGzVuvLyq1fPq0RazxUJnxRLjgMx06isXzWJR GjHJ5KmU3NBxPErI/2AkJ8RoLqUl3TQs5VLdYwvh5YndPigBLFZI3GUVAKC3XTnFrvCO caZRuqbCLmGWf5cSC92/NA+5mQvyHR16GbHxGvc/+owMtRFAIttEIuktV0tApoHu612q 4Jnw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-language :content-transfer-encoding:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject; bh=1z3QuKHlRzO81n4qvErowgD3OtDoMkKuTJXx4IP3ulk=; b=BlCCoNcT2W5xS/9ctivx/V8eMf5mTT4j7sn5Czsw75lOyXmXwIiuU6ACaojnrNNCTp 6jPsjIVyN8zRXsikwlu7pbphchwywmEZE2TSCgMqxV393zxk2DzdoxJagLi17ciaKRh+ HYjUKuO0k/X8Iuj0ToJa93G2V0Bthl4sYj/9KDCSoJqn4Hab5IGSqrMwvg7eV++RAq/e tzcJBdb+b/5525bfIUYBHy/NRtzq9jKLXcD+yeemgqKsJZwZLXxtMpq+t1pHN1bQODO/ xZzog3d4Y8sGV8AW0Fco80/Jz+Cw1LlimviHZu6bY6ZxvdE0+YyEZ9Ztaldky+Eh1qqN lgbA== 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=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q15si1383358ejm.31.2019.11.04.01.31.07; Mon, 04 Nov 2019 01:31:31 -0800 (PST) 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=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728267AbfKDJ3k (ORCPT + 99 others); Mon, 4 Nov 2019 04:29:40 -0500 Received: from mga07.intel.com ([134.134.136.100]:50239 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727138AbfKDJ3k (ORCPT ); Mon, 4 Nov 2019 04:29:40 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Nov 2019 01:29:39 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,266,1569308400"; d="scan'208";a="401550886" Received: from savicrad-mobl.ger.corp.intel.com (HELO [10.249.40.217]) ([10.249.40.217]) by fmsmga005.fm.intel.com with ESMTP; 04 Nov 2019 01:29:36 -0800 Subject: Re: [PATCH 1/2] drm/atomic: fix self-refresh helpers crtc state dereference To: Sean Paul , Rob Clark Cc: dri-devel , Sean Paul , Rob Clark , Maxime Ripard , David Airlie , Daniel Vetter , open list References: <20191101180713.5470-1-robdclark@gmail.com> From: Maarten Lankhorst Message-ID: <3a67eed5-8be7-df5b-84fa-61b133e1fea2@linux.intel.com> Date: Mon, 4 Nov 2019 10:29:21 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Content-Language: en-US Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Op 01-11-2019 om 21:06 schreef Sean Paul: > On Fri, Nov 1, 2019 at 2:09 PM Rob Clark wrote: >> From: Rob Clark >> >> drm_self_refresh_helper_update_avg_times() was incorrectly accessing the >> new incoming state after drm_atomic_helper_commit_hw_done(). But this >> state might have already been superceeded by an !nonblock atomic update >> resulting in dereferencing an already free'd crtc_state. >> >> Fixes: d4da4e33341c ("drm: Measure Self Refresh Entry/Exit times to avoid thrashing") >> Cc: Sean Paul >> Signed-off-by: Rob Clark >> --- >> TODO I *think* this will more or less do the right thing.. althought I'm >> not 100% sure if, for example, we enter psr in a nonblock commit, and >> then leave psr in a !nonblock commit that overtakes the completion of >> the nonblock commit. Not sure if this sort of scenario can happen in >> practice. But not crashing is better than crashing, so I guess we >> should either take this patch or rever the self-refresh helpers until >> Sean can figure out a better solution. >> >> drivers/gpu/drm/drm_atomic_helper.c | 2 ++ >> drivers/gpu/drm/drm_self_refresh_helper.c | 11 ++++++----- >> include/drm/drm_atomic.h | 8 ++++++++ >> 3 files changed, 16 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c >> index 3ef2ac52ce94..732bd0ce9241 100644 >> --- a/drivers/gpu/drm/drm_atomic_helper.c >> +++ b/drivers/gpu/drm/drm_atomic_helper.c >> @@ -2240,6 +2240,8 @@ void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state) >> int i; >> >> for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { >> + old_state->crtcs[i].new_self_refresh_active = new_crtc_state->self_refresh_active; >> + >> commit = new_crtc_state->commit; >> if (!commit) >> continue; >> diff --git a/drivers/gpu/drm/drm_self_refresh_helper.c b/drivers/gpu/drm/drm_self_refresh_helper.c >> index 68f4765a5896..77b9079fa578 100644 >> --- a/drivers/gpu/drm/drm_self_refresh_helper.c >> +++ b/drivers/gpu/drm/drm_self_refresh_helper.c >> @@ -143,19 +143,20 @@ void drm_self_refresh_helper_update_avg_times(struct drm_atomic_state *state, >> unsigned int commit_time_ms) >> { >> struct drm_crtc *crtc; >> - struct drm_crtc_state *old_crtc_state, *new_crtc_state; >> + struct drm_crtc_state *old_crtc_state; >> int i; >> >> - for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, >> - new_crtc_state, i) { >> + for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) { >> + bool new_self_refresh_active = >> + state->crtcs[i].new_self_refresh_active; >> struct drm_self_refresh_data *sr_data = crtc->self_refresh_data; >> struct ewma_psr_time *time; >> >> if (old_crtc_state->self_refresh_active == >> - new_crtc_state->self_refresh_active) >> + new_self_refresh_active) >> continue; >> >> - if (new_crtc_state->self_refresh_active) >> + if (new_self_refresh_active) >> time = &sr_data->entry_avg_ms; >> else >> time = &sr_data->exit_avg_ms; >> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h >> index 927e1205d7aa..86baf2b38bb3 100644 >> --- a/include/drm/drm_atomic.h >> +++ b/include/drm/drm_atomic.h >> @@ -155,6 +155,14 @@ struct __drm_crtcs_state { >> struct drm_crtc *ptr; >> struct drm_crtc_state *state, *old_state, *new_state; >> >> + /** >> + * @new_self_refresh_active: >> + * >> + * drm_atomic_helper_commit_hw_done() stashes new_crtc_state->self_refresh_active >> + * so that it can be accessed late in drm_self_refresh_helper_update_avg_times(). >> + */ >> + bool new_self_refresh_active; >> + > Instead of stashing this in crtc, we could generate a bitmask local to > commit_tail and pass that to calc_avg_times? That way we don't have to > worry about someone using this when they shouldn't Yeah would make sense to have a bitmask, instead of making the property special. :) Current solution seems a bit ugly.