Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp2706970pxv; Sun, 11 Jul 2021 23:20:54 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxvU46N5a0X5iPaDlGfv8I4EEOLnTwjxoeohIWRk+IgK9E4OflE6iRf0MxlWRyzJ6aJAbPT X-Received: by 2002:a6b:da08:: with SMTP id x8mr11338783iob.114.1626070853933; Sun, 11 Jul 2021 23:20:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626070853; cv=none; d=google.com; s=arc-20160816; b=LYX9V3ORSE0jElvoitQpInJSpo0RcGRVqUpDP0JoELEnUCti1e4WgXVUa6jpBYAQXw bdRbXL201k7SPk+tHrVgkK96K7heB568xvwWBxDrh6VOSvpd1zoXn6Lximfm9TLaE7NP wgKC1tHGRXtFQF8AkfMw4ryDScksYDctf56vBn5oHkPUr97Qn6JSjGWJAaaqIB14OW7E FfYb/YhqGgSA6lYvavOMHdP0aoPJ+fUuO53b3DN9SN3M9T5DhxxEqQrI9iLoJby5p9TX 1Sj3x0hwTZ2Nxd6MO9MP/SGKw38h6pubVJSJG5iWdIp9NwxTZviY6asof7afzLYROpvC CCTA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=mc6UmCVL1jve0WsbnQPAKupakPp9mN6iBguJjoHkMS4=; b=0abW2IkeoiHC69lkaTVWn9hFIKixo/egIgQ0i8kTezlO+7hcgkY0/KxGzj06J9dQsf R/mpidEslPETcsIBJ+wnAwlCsFr1QWMoSYdtnJMeqPkgOqTxNsfxAcfA53sWTVeUF6f+ Y5M7Ytr8O1W8dStfpXVg+3fXs5Ob23DGWOcFHnlP58T0hJlnKmnT10sNmNN/ZxWT6Sbf SH+D5hLKtGV7mdl1J+hOumrqK8IdMOauTfzeAMeNFEEOKsZRqPdfwDCkdcVMOTcA1w/b jr/xeH2UcYL3p/hsOO7XboOyK4noD6k6wrSU9OrZdf3tYPMjf6ZdvF0BjXKgRxcv1pfO wqZA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=nyD5mmi+; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d12si15775170ioi.82.2021.07.11.23.20.42; Sun, 11 Jul 2021 23:20:53 -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; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=nyD5mmi+; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233855AbhGLGXB (ORCPT + 99 others); Mon, 12 Jul 2021 02:23:01 -0400 Received: from mail.kernel.org ([198.145.29.99]:39276 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234457AbhGLGVv (ORCPT ); Mon, 12 Jul 2021 02:21:51 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 3897A610A7; Mon, 12 Jul 2021 06:18:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1626070731; bh=aQ5vHJkxuc0ZwJIL/ivo28JrPYFcDVA2PP2Pc061mZY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nyD5mmi+KqRg/GOU6tmJead5s5/wSVIG+IPDpXBJaetHboDE128Vv9IScK+CgTi3U Z5UB9sGbpDG+AbtXkkmE4i1SQA0JS94dBaf3IGR2J3wWbtZbXin47K9bSH1C9197Z1 USE+78UXpA1S1KjjAAk39CtUP01WeemWlVbXRgXw= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Prike Liang , Alex Deucher , Mario Limonciello , "Rafael J. Wysocki" , Sasha Levin Subject: [PATCH 5.4 114/348] ACPI: processor idle: Fix up C-state latency if not ordered Date: Mon, 12 Jul 2021 08:08:18 +0200 Message-Id: <20210712060716.630308563@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210712060659.886176320@linuxfoundation.org> References: <20210712060659.886176320@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Mario Limonciello [ Upstream commit 65ea8f2c6e230bdf71fed0137cf9e9d1b307db32 ] Generally, the C-state latency is provided by the _CST method or FADT, but some OEM platforms using AMD Picasso, Renoir, Van Gogh, and Cezanne set the C2 latency greater than C3's which causes the C2 state to be skipped. That will block the core entering PC6, which prevents S0ix working properly on Linux systems. In other operating systems, the latency values are not validated and this does not cause problems by skipping states. To avoid this issue on Linux, detect when latencies are not an arithmetic progression and sort them. Link: https://gitlab.freedesktop.org/agd5f/linux/-/commit/026d186e4592c1ee9c1cb44295912d0294508725 Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1230#note_712174 Suggested-by: Prike Liang Suggested-by: Alex Deucher Signed-off-by: Mario Limonciello [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/processor_idle.c | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index ed56c6d20b08..53ae679c00f0 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -16,6 +16,7 @@ #include #include #include /* need_resched() */ +#include #include #include #include @@ -540,10 +541,37 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, return; } +static int acpi_cst_latency_cmp(const void *a, const void *b) +{ + const struct acpi_processor_cx *x = a, *y = b; + + if (!(x->valid && y->valid)) + return 0; + if (x->latency > y->latency) + return 1; + if (x->latency < y->latency) + return -1; + return 0; +} +static void acpi_cst_latency_swap(void *a, void *b, int n) +{ + struct acpi_processor_cx *x = a, *y = b; + u32 tmp; + + if (!(x->valid && y->valid)) + return; + tmp = x->latency; + x->latency = y->latency; + y->latency = tmp; +} + static int acpi_processor_power_verify(struct acpi_processor *pr) { unsigned int i; unsigned int working = 0; + unsigned int last_latency = 0; + unsigned int last_type = 0; + bool buggy_latency = false; pr->power.timer_broadcast_on_state = INT_MAX; @@ -567,12 +595,24 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) } if (!cx->valid) continue; + if (cx->type >= last_type && cx->latency < last_latency) + buggy_latency = true; + last_latency = cx->latency; + last_type = cx->type; lapic_timer_check_state(i, pr, cx); tsc_check_state(cx->type); working++; } + if (buggy_latency) { + pr_notice("FW issue: working around C-state latencies out of order\n"); + sort(&pr->power.states[1], max_cstate, + sizeof(struct acpi_processor_cx), + acpi_cst_latency_cmp, + acpi_cst_latency_swap); + } + lapic_timer_propagate_broadcast(pr); return (working); -- 2.30.2