From patchwork Thu Feb 22 05:59:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 129147 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp242465lja; Wed, 21 Feb 2018 22:00:15 -0800 (PST) X-Google-Smtp-Source: AH8x225A1HBOaQrTILkYweD4Wx+SLfyznGCl9BktxQcCYjpGdy5lp/fIw+DZY6dsNerwV9UrfdyP X-Received: by 10.98.186.20 with SMTP id k20mr5730059pff.170.1519279215514; Wed, 21 Feb 2018 22:00:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519279215; cv=none; d=google.com; s=arc-20160816; b=gO1vzQTqvjhq4eki97tO903Y2s0/tmckWt3gt2a07LdSGdGZ1ggD5TrreB0jueeiVC CxI7zozpMIKceOYKPPOxRntVmvDVrFLjeJ7Bx1bRYmSnRfuFXnGFQEZxlbu88KwR/n8H A89JLksv2V0Ybp6FZy9jGavHl2QMa8dD3gmYv7GH/h/nSO5S28DIHAGOPBy3h9umFIsD m2E80gHocFbkcxV/th4FQAPxgDM4mDStoMkgdml8iDgSGmL4rBVWuOTRzvkDbX55Nm2T UShlF5eZQAuoHTO5Qa+n8AC1OXxNMZig/SOfrCmfAFX15WpDWTuI+p0SVZqXDElMrU/1 EdFw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=ICxF2yRTvWAPYGtY+eFFxrFkiw7ewW7Go8F1UDvV3s4=; b=mGwQqwOTpiLw5Udx+GOiZSwxvfTilBl4JrPhz2F34C0lNuzWeoQJAwNLq6gDfCZXkI L0qFZFa02hO1QsXdrSZNCTMhr41izOgjMvPIp8hmjvU7EnHOzlgRThNXhS3ktVq+pNr5 f39Y70EU7UF+0SnoLZ2ThZm5tBpumLm8xsxoabvbe5hdNAwxxAY/ASaTANm26LGoq37N 5LOCPn2dSz0z9PoWk/WDF6AAiZr6ya6wyCOdylMLtvT/ct6fITqs0EYARnG0xl52k1ce dWi6R3+2qz3ZHkVNpTbWpSUBQE3q5ABjTVT2Zy/1cX8FCx2gscb9EVMC4rmn6UNxfKH2 iFVQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=kkhP55bq; 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 sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 126si10878100pfd.48.2018.02.21.22.00.12; Wed, 21 Feb 2018 22:00:15 -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; dkim=pass header.i=@linaro.org header.s=google header.b=kkhP55bq; 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 sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752499AbeBVGAD (ORCPT + 28 others); Thu, 22 Feb 2018 01:00:03 -0500 Received: from mail-pl0-f66.google.com ([209.85.160.66]:35747 "EHLO mail-pl0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752225AbeBVGAA (ORCPT ); Thu, 22 Feb 2018 01:00:00 -0500 Received: by mail-pl0-f66.google.com with SMTP id bb3so2363988plb.2 for ; Wed, 21 Feb 2018 22:00:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=ICxF2yRTvWAPYGtY+eFFxrFkiw7ewW7Go8F1UDvV3s4=; b=kkhP55bq/udTOzQoPx6hKzESc1wYQbiepKQ3qtPwDbMYRyxYxMhWW81soz/fVFg7uF rX+KFk5L39X9Lob/eAhYoYELQxv+WsHnZFO/m7Yd2kDvbo0K2wioesYMrtRWN3hvBg7e 25ycwLFmYUvdaorjd72xwLAkTEf/9OiZiw3Fc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=ICxF2yRTvWAPYGtY+eFFxrFkiw7ewW7Go8F1UDvV3s4=; b=F8BC6u+nbnvb4HKxIYSubyrpzcalNQQZY0zfBP0hntAXTeXmRhKbYWB7WPlZxZ9itW o0gVCepSt+ORe2hfzcgL8JwokOclPgSoz3Jggqd6PUvRJ5K5+t9zlDM0mRsoBAYJ7sH1 nmnQpD80hhb5Uq2DXCvrC0oU82Rb6J1ua7u9uAFZsPUuckA20DlY/tig1A4Qmo8BopvU EhR+7dtDZVOEuG4kOOLdMBk4dWmJ8yQ2i8Apj/aycbgji1ukaMgC6STXDHEu+dEKXyMV B8LmEIWOBLRN6IgWKfT2YTW7bMDZvK+DRM78BeAl02GZ+Hm+p+arsQSo3hupxWqjJ0lt /1oQ== X-Gm-Message-State: APf1xPCWtKfPIjSB0JWHrJuCqSQYliLneqSchtOqu0jNSfiWlTAWcuYP a80Rueapk6MYVakfgXZ7ruKt7Q== X-Received: by 2002:a17:902:14b:: with SMTP id 69-v6mr5573619plb.209.1519279200385; Wed, 21 Feb 2018 22:00:00 -0800 (PST) Received: from localhost ([122.167.232.138]) by smtp.gmail.com with ESMTPSA id y4sm49421942pfm.16.2018.02.21.21.59.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 21:59:59 -0800 (PST) From: Viresh Kumar To: Rafael Wysocki Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , Michael Ellerman , linux-kernel@vger.kernel.org Subject: [PATCH 2/2] cpufreq: Validate cpufreq table from core Date: Thu, 22 Feb 2018 11:29:44 +0530 Message-Id: X-Mailer: git-send-email 2.15.0.194.g9af6a3dea062 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org By design, it is responsibility of the cpufreq drivers to call cpufreq_frequency_table_cpuinfo() from their ->init() callback to validate the cpufreq table. But what if the cpufreq driver is buggy and fails to do so properly? It may then result in unexpected behavior from the driver or the cpufreq core at a later point of time. It would be better if the core can validate the cpufreq table at the initial stage. This commit adds another routine cpufreq_table_validate_and_sort() and calls it right after calling the ->init() callback of the driver and destroys the cpufreq policy if the table is invalid. For the moment the validation of the table happens twice, once from the driver and then from the core. The individual drivers would be updated separately to drop table validation if they don't need it for other purposes. The cpufreq table is marked "sorted" or "unsorted" from the new helper now instead of cpufreq_table_validate_and_show(), as we should be doing that only after validating the table (which the drivers wouldn't do going forward). Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 13 +++++++++---- drivers/cpufreq/freq_table.c | 16 +++++++++++++++- include/linux/cpufreq.h | 1 + 3 files changed, 25 insertions(+), 5 deletions(-) -- 2.15.0.194.g9af6a3dea062 diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 8814c572e263..239063fb6afc 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1219,6 +1219,10 @@ static int cpufreq_online(unsigned int cpu) goto out_free_policy; } + ret = cpufreq_table_validate_and_sort(policy); + if (ret) + goto out_exit_policy; + down_write(&policy->rwsem); if (new_policy) { @@ -1249,7 +1253,7 @@ static int cpufreq_online(unsigned int cpu) policy->cur = cpufreq_driver->get(policy->cpu); if (!policy->cur) { pr_err("%s: ->get() failed\n", __func__); - goto out_exit_policy; + goto out_destroy_policy; } } @@ -1296,7 +1300,7 @@ static int cpufreq_online(unsigned int cpu) if (new_policy) { ret = cpufreq_add_dev_interface(policy); if (ret) - goto out_exit_policy; + goto out_destroy_policy; cpufreq_stats_create_table(policy); @@ -1311,7 +1315,7 @@ static int cpufreq_online(unsigned int cpu) __func__, cpu, ret); /* cpufreq_policy_free() will notify based on this */ new_policy = false; - goto out_exit_policy; + goto out_destroy_policy; } up_write(&policy->rwsem); @@ -1326,12 +1330,13 @@ static int cpufreq_online(unsigned int cpu) return 0; -out_exit_policy: +out_destroy_policy: for_each_cpu(j, policy->real_cpus) remove_cpu_dev_symlink(policy, get_cpu_device(j)); up_write(&policy->rwsem); +out_exit_policy: if (cpufreq_driver->exit) cpufreq_driver->exit(policy); diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 6d007f824ca7..10e119ae66dd 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -362,10 +362,24 @@ int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, return ret; policy->freq_table = table; - return set_freq_table_sorted(policy); + return 0; } EXPORT_SYMBOL_GPL(cpufreq_table_validate_and_show); +int cpufreq_table_validate_and_sort(struct cpufreq_policy *policy) +{ + int ret; + + if (!policy->freq_table) + return 0; + + ret = cpufreq_frequency_table_cpuinfo(policy, policy->freq_table); + if (ret) + return ret; + + return set_freq_table_sorted(policy); +} + MODULE_AUTHOR("Dominik Brodowski "); MODULE_DESCRIPTION("CPUfreq frequency table helpers"); MODULE_LICENSE("GPL"); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 21e8d248d956..1fe49724da9e 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -962,6 +962,7 @@ extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs; extern struct freq_attr *cpufreq_generic_attr[]; int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table); +int cpufreq_table_validate_and_sort(struct cpufreq_policy *policy); unsigned int cpufreq_generic_get(unsigned int cpu); int cpufreq_generic_init(struct cpufreq_policy *policy,