Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp3764536pxv; Mon, 19 Jul 2021 08:13:19 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx/NSTOs6yRnmYho/POuq+ouuFUgMUdXaaGf7PuMv1DFOrIyW8EX3P7Ab0WsHkOGkb0B0Y0 X-Received: by 2002:a05:6402:22aa:: with SMTP id cx10mr34452637edb.0.1626707598846; Mon, 19 Jul 2021 08:13:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626707598; cv=none; d=google.com; s=arc-20160816; b=XiH1tNx15sQFK31vphP4vMeAFN9SfjVnP9vA3eqUviYD8XHGcZflkcgXyHExEn7bD0 Xsz/4QO5YhcpENjBl7yjJnk+wb8+nlVn0IfbW4GxKoAcWutUrIaup1IDPIVH9b5i7Fd0 AnogLGOW7pzhdnWaBH5hKkxRUSzF+yjsg4hiELtCTxCXM2+XCI+ZBCj9Znz4iNutOI8d nWnwaHRSWm8VTfd4Bs/qWn/XNqAcB6Y4p4E6EyTcXPYJ2xnAeJ7UgGD6RZRC8YWCEeWr 3gQ/2o6GKNvCue2WjqMmZodmaINUFxO/X2Eqa45W4y5J56Mq+7KEhDXDirICdUPNO12V 8b8w== 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=cQXGhl84Gt/e27by9ieaNJVVVieueVr7Q/taL7XZVOE=; b=fUfg1V4nd8fzRwSdbTf0+t/0vZww5+5dLAB3ocwE1qbMJo97jr7m7a/PAnoJRaGUzu 6DvLMoEx/gV7qpQV/AscEjA1Nbw/fe0AWoTn+fmXBjI0EMgrxv8byCVIgVYsvXUAml5c tGSYxeyRT81MqJwlkt2VsqEVfCt94QCEj67ae23RftfGKzSpy7zwwex55j6LlKEuOlIm pc8E+WkLEYH9SkRSlwoPvrotky8WBh5X+p4idHhQkTQkzJlYno4C4TYHAMClio3J7F3U m5E19etqxqineTCWgEfB1TNTA2NW67G5xZRiVyMIGruu0u+C1swcKPRdUQaW0L9+yTk0 Qxqg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=a9XDeinw; 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 y6si22342980edr.409.2021.07.19.08.12.56; Mon, 19 Jul 2021 08:13:18 -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=a9XDeinw; 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 S244675AbhGSO34 (ORCPT + 99 others); Mon, 19 Jul 2021 10:29:56 -0400 Received: from mail.kernel.org ([198.145.29.99]:37344 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244531AbhGSOZL (ORCPT ); Mon, 19 Jul 2021 10:25:11 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 4275D60FDC; Mon, 19 Jul 2021 15:05:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1626707150; bh=xgmsrfGkC+gkkkdJMrsvG1N/yAnLc31sKa/2Km/fPgI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a9XDeinwVjoW8dHdwWyzMrHgOm0pXvgwHjd6dxmTOuWcL3YHC7k7oNDimFcneDgmE DR6825WkDIO1VJkU6vndaL4ebXFKjRF2PO7Xr2EtmAr4K+QY0Nq3qE+2bcohLi8Lxk ksAgHebaNQWQlHPZIePBIbEmew5leUZclYc6F3Ts= 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.9 048/245] ACPI: processor idle: Fix up C-state latency if not ordered Date: Mon, 19 Jul 2021 16:49:50 +0200 Message-Id: <20210719144941.952739593@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210719144940.288257948@linuxfoundation.org> References: <20210719144940.288257948@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 2237d3f24f0e..8242e16f57c6 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -29,6 +29,7 @@ #include #include #include /* need_resched() */ +#include #include #include #include @@ -538,10 +539,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; @@ -565,12 +593,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