From patchwork Thu Jun 16 06:33:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 70141 Delivered-To: patch@linaro.org Received: by 10.140.28.4 with SMTP id 4csp105853qgy; Wed, 15 Jun 2016 23:33:52 -0700 (PDT) X-Received: by 10.107.63.198 with SMTP id m189mr5323650ioa.60.1466058832546; Wed, 15 Jun 2016 23:33:52 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id bf10si12157784pab.204.2016.06.15.23.33.51; Wed, 15 Jun 2016 23:33:52 -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; dkim=pass header.i=@linaro.org; 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=pass (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753800AbcFPGdu (ORCPT + 30 others); Thu, 16 Jun 2016 02:33:50 -0400 Received: from mail-pf0-f182.google.com ([209.85.192.182]:33828 "EHLO mail-pf0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752386AbcFPGdr (ORCPT ); Thu, 16 Jun 2016 02:33:47 -0400 Received: by mail-pf0-f182.google.com with SMTP id h14so1669827pfe.1 for ; Wed, 15 Jun 2016 23:33:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=+eOkQ/OM/wvxRX44dJHsA55ekLm/ZTgkn1p9IuNorwY=; b=TM+GaU+BRjRVsJZr8yCikscHAwzBCSlZgzee+M964KLPtMAMq4dZ5YdAeUWveNEaDn sdBbN/CLf+DE5MX6UQ8lNalwTKEC3M51fe5aYzmbgUBpcWCFsSzlaRMXgGuc4jdo2ULu vbCVAbNr7/HKidrZoX8q6Dj447iaBxB/5JqBk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=+eOkQ/OM/wvxRX44dJHsA55ekLm/ZTgkn1p9IuNorwY=; b=R+6Hp7+NmD9pzCdgCZF5NS1+ejcFrsD1cIkuVzeSJU1GacQPgyFL46VC28SVl1lFXt CsB8vjzG3jHBz2UoOJLQ2tN+QPG8VvedEAvjfvSEyrNpNHIMgr0HReLdjJ1PHWAtCmFj 3+fP2iOUQeFmVMki7eTPFNqwRPSgDN01RWNkUwUzkPx0ccBBrik86XQaQTSC788IJJVN jrJ2SXTzGjgZ4brXpPScJjrHoENE2kNPbEjaT764dh9MSnMZS2DWx5QaJ5JhD93Yq1Og jM577PBxENGn+CIucdQBb9DaavaCgydYuchauQNbFVS3RO8gA73JtG11tSL2fKza6kfD H+og== X-Gm-Message-State: ALyK8tLON+eu3gmNP9qlLgym9F3WONcLZNGiW7J+nXShpYzEyT24PBPe2IDDskov0mnF+bQT X-Received: by 10.98.12.83 with SMTP id u80mr3345880pfi.39.1466058826965; Wed, 15 Jun 2016 23:33:46 -0700 (PDT) Received: from localhost ([122.172.148.163]) by smtp.gmail.com with ESMTPSA id fn3sm57530394pab.20.2016.06.15.23.33.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 15 Jun 2016 23:33:46 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , acourbot@nvidia.com, Viresh Kumar , Nishanth Menon , Stephen Boyd Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, gnurou@gmail.com, linux-tegra@vger.kernel.org, Viresh Kumar Subject: [PATCH] PM / OPP: 'UNKNOWN' status of opp-table->shared Date: Thu, 16 Jun 2016 12:03:33 +0530 Message-Id: <87bd097db7b673b1f75ca2086dfa76f4dfbf7f8c.1466058619.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.7.1.410.g6faf27b Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org dev_pm_opp_get_sharing_cpus() returns 0 even in the case where the OPP core doesn't know if the table is shared or not. It is working for most of the platforms, as the OPP table was never created and we returned -ENODEV then. But in case of one of the platforms (Jetson TK1) at least, the situation is a bit different. The OPP table is created (somehow) before dev_pm_opp_get_sharing_cpus() is called and so we returned 0. The caller of this routine treated that as 'CPUs don't share OPPs' and that had bad consequences on performance. Fix this by converting 'shared_opp' to an integer and have an extra value when its state in undefined. dev_pm_opp_get_sharing_cpus() returns -EINVAL now in that case, so that the caller can handle it accordingly (cpufreq-dt considers that as 'all CPUs share the table'). Fixes: 6f707daa3833 ("PM / OPP: Add dev_pm_opp_get_sharing_cpus()") Reported-by: Alexandre Courbot Signed-off-by: Viresh Kumar --- Hi Alexandre, This is untested, can you please confirm if this fixes it for you? drivers/base/power/opp/core.c | 3 +++ drivers/base/power/opp/cpu.c | 12 +++++++++--- drivers/base/power/opp/of.c | 10 ++++++++-- drivers/base/power/opp/opp.h | 5 ++++- 4 files changed, 24 insertions(+), 6 deletions(-) -- 2.7.1.410.g6faf27b diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index 7c04c87738a6..14d212885098 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -764,6 +764,9 @@ static struct opp_table *_add_opp_table(struct device *dev) /* Set regulator to a non-NULL error value */ opp_table->regulator = ERR_PTR(-ENXIO); + /* Set sharing information as unknown */ + opp_table->shared_opp = OPP_TABLE_SHARED_UNKNOWN; + /* Find clk for the device */ opp_table->clk = clk_get(dev, NULL); if (IS_ERR(opp_table->clk)) { diff --git a/drivers/base/power/opp/cpu.c b/drivers/base/power/opp/cpu.c index 83d6e7ba1a34..4ca86df8a451 100644 --- a/drivers/base/power/opp/cpu.c +++ b/drivers/base/power/opp/cpu.c @@ -211,7 +211,7 @@ int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, } /* Mark opp-table as multiple CPUs are sharing it now */ - opp_table->shared_opp = true; + opp_table->shared_opp = OPP_TABLE_IS_SHARED; } unlock: mutex_unlock(&opp_table_lock); @@ -227,7 +227,8 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_set_sharing_cpus); * * This updates the @cpumask with CPUs that are sharing OPPs with @cpu_dev. * - * Returns -ENODEV if OPP table isn't already present. + * Returns -ENODEV if OPP table isn't already present and -EINVAL if the OPP + * table's status is shared-unknown. * * Locking: The internal opp_table and opp structures are RCU protected. * Hence this function internally uses RCU updater strategy with mutex locks @@ -249,9 +250,14 @@ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask) goto unlock; } + if (opp_table->shared_opp == OPP_TABLE_SHARED_UNKNOWN) { + ret = -EINVAL; + goto unlock; + } + cpumask_clear(cpumask); - if (opp_table->shared_opp) { + if (opp_table->shared_opp == OPP_TABLE_IS_SHARED) { list_for_each_entry(opp_dev, &opp_table->dev_list, node) cpumask_set_cpu(opp_dev->dev->id, cpumask); } else { diff --git a/drivers/base/power/opp/of.c b/drivers/base/power/opp/of.c index 94d2010558e3..83ad3a6a16f1 100644 --- a/drivers/base/power/opp/of.c +++ b/drivers/base/power/opp/of.c @@ -34,7 +34,10 @@ static struct opp_table *_managed_opp(const struct device_node *np) * But the OPPs will be considered as shared only if the * OPP table contains a "opp-shared" property. */ - return opp_table->shared_opp ? opp_table : NULL; + if (opp_table->shared_opp == OPP_TABLE_IS_SHARED) + return opp_table; + + return NULL; } } @@ -353,7 +356,10 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np) } opp_table->np = opp_np; - opp_table->shared_opp = of_property_read_bool(opp_np, "opp-shared"); + if (of_property_read_bool(opp_np, "opp-shared")) + opp_table->shared_opp = OPP_TABLE_IS_SHARED; + else + opp_table->shared_opp = OPP_TABLE_IS_NOT_SHARED; mutex_unlock(&opp_table_lock); diff --git a/drivers/base/power/opp/opp.h b/drivers/base/power/opp/opp.h index 20f3be22e060..ffd0b54e7894 100644 --- a/drivers/base/power/opp/opp.h +++ b/drivers/base/power/opp/opp.h @@ -166,7 +166,10 @@ struct opp_table { /* For backward compatibility with v1 bindings */ unsigned int voltage_tolerance_v1; - bool shared_opp; +#define OPP_TABLE_IS_NOT_SHARED 0 +#define OPP_TABLE_IS_SHARED 1 +#define OPP_TABLE_SHARED_UNKNOWN UINT_MAX + unsigned int shared_opp; struct dev_pm_opp *suspend_opp; unsigned int *supported_hw;