Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp3753531pxv; Mon, 19 Jul 2021 08:00:44 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzckwhw648Ayg8fgxwVLyZP3ej2O8SmMSeGrUAF4A0boYGIT2bkAKU6/DcbBRxTw7fbZhkG X-Received: by 2002:a02:380c:: with SMTP id b12mr22164477jaa.68.1626706844051; Mon, 19 Jul 2021 08:00:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626706844; cv=none; d=google.com; s=arc-20160816; b=Izd8GC39yGhCHjBauyYu1kQnzyam7l+tYDEULH8tTp7bChsyMF703UibjnFMXB0Fnm +duerGP53vh+uCS9YlGRqWgm8dIlMYjSD1/ude3AzOAlk8vLuoLXd89DTvdLkAl5u+cW UghgBVo02P1gHcHT/nNsGP90h5F7whc2pj386lgEwZ2QtC2sI0fkXmtbvzFl3FTgSnHW 34vQikMZHOD+3lezwsJXUBOl9bU09+RC4JCYTwE3ZF2bgVr+7YeVvZXP2MpqnV13y95E jCkeHZL9ubM3S9WMxL3ZRkxNw4KfEt12G3bEZHCoNCk68EFoFC14YbY2nRumc5djjZJt FNyg== 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=LmiOGorXDCPaY+xM1/JAe7XIRT24PnIgNKM9Pmm/T04=; b=pr9aQVUeM9H6eRJpKu5YN7qXIKqb6RhU02zPwX/7UzKLIMb/8rkh+HQ6FmoD0pZ1n9 gmM12+2nR9WuuAuGQ0LtK5m0TqaY5eCEeGivD8qwMBXCQFsWONbIsNfttgVkkXjNHGH5 i0Ds6ubK6VW1L73bqt1vGMN18WjSHHfJHvtnBssJfn/Rm7+LgC80Wa4rsHwkhOrKYCqc 4qc6L3HGAnUK0BjMUBQZPI5d06e8ZI2wF3as7aadditxeqL4sUTHzOladWft44q7AU2a pQwYJ71sg8wOYiKuHggQZ1mnzQsCObpFcFfgLrccLiIXp/sHhnQIfb5+GeMRe6S7lKXd KxYw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=avKmp65g; 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 t15si19360737ilg.47.2021.07.19.08.00.30; Mon, 19 Jul 2021 08:00:44 -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=avKmp65g; 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 S242138AbhGSOTD (ORCPT + 99 others); Mon, 19 Jul 2021 10:19:03 -0400 Received: from mail.kernel.org ([198.145.29.99]:53200 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242141AbhGSOSP (ORCPT ); Mon, 19 Jul 2021 10:18:15 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 33731610D2; Mon, 19 Jul 2021 14:58:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1626706734; bh=CI4jYarbWrt2iBArbBgIdntQThqTJhVm7C3TvtGzvqw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=avKmp65gkJ5RYl7Gs8m3QjhrHyd6/NrUUziRG4LqGt1WTNcPGWsB1XN3sNn5pFosR +Jw/S38u/8+124fb4HJSYVL8V/aBNt9gVEHEguQeZ6ru/WT/nVc+nmEPkG0MyqFWTo /Xnu7RBj/wHDhKgCw9zSUIWvM3ZPQTaIYq4EfhGc= 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 4.4 041/188] ACPI: processor idle: Fix up C-state latency if not ordered Date: Mon, 19 Jul 2021 16:50:25 +0200 Message-Id: <20210719144922.729964959@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210719144913.076563739@linuxfoundation.org> References: <20210719144913.076563739@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 175c86bee3a9..69fec2d3a1f5 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -28,6 +28,7 @@ #include #include #include /* need_resched() */ +#include #include #include #include @@ -572,10 +573,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; @@ -599,12 +627,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