From patchwork Thu Feb 19 11:32:22 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 44833 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f69.google.com (mail-wg0-f69.google.com [74.125.82.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 3630021554 for ; Thu, 19 Feb 2015 11:35:00 +0000 (UTC) Received: by mail-wg0-f69.google.com with SMTP id k14sf4639319wgh.0 for ; Thu, 19 Feb 2015 03:34:59 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:in-reply-to:references :sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=368TFlt+kwEBve4ciSftR64QOm1ELYmaMJEzgHdANhY=; b=aSuH6KD8gF4JVUb/zlzHfTdPW+5ILCM5q+HqqY1FLgPmI7XakMoiOg2uxjU/bt4zJv gJTFqXx6YjJ/JjzqjuE79/4xhBSxBnQjtt+A3xoA5eJ0suIQ8GCn9OAsWFA6A0B9bo+9 Q1OZytV9hHSORWBSRez7YiwNdulRo9mecNsTk4Sq/L0K/OICwxlY6TiL5IQ8+Sg+ceOS jqLtA6gOJgM1OZgQxh9emzqfa0/vWsXS838an7xTZZn+1n2h8+kwIBAo+3wfB7ZKFZdJ FVe7p59rRfWCYfYGuLjVyBhwPcAy8GvXql0+j2TdVCgrhp/vj7igcEoumFAChynsKB12 1fOw== X-Gm-Message-State: ALoCoQmY6aIgBGDhWqov+QfIyncpXT71PHm09Ydqs5Z8vJhrIEJdfHBdoe4No8gmF5c8dnqecnGc X-Received: by 10.194.161.194 with SMTP id xu2mr511447wjb.1.1424345699552; Thu, 19 Feb 2015 03:34:59 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.87.14 with SMTP id t14ls142778laz.61.gmail; Thu, 19 Feb 2015 03:34:59 -0800 (PST) X-Received: by 10.112.141.34 with SMTP id rl2mr3668087lbb.26.1424345699363; Thu, 19 Feb 2015 03:34:59 -0800 (PST) Received: from mail-la0-f49.google.com (mail-la0-f49.google.com. [209.85.215.49]) by mx.google.com with ESMTPS id m6si14814812lah.141.2015.02.19.03.34.59 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Feb 2015 03:34:59 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.49 as permitted sender) client-ip=209.85.215.49; Received: by labgf13 with SMTP id gf13so6964433lab.9 for ; Thu, 19 Feb 2015 03:34:59 -0800 (PST) X-Received: by 10.112.56.139 with SMTP id a11mr3655513lbq.36.1424345699254; Thu, 19 Feb 2015 03:34:59 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.35.133 with SMTP id h5csp432132lbj; Thu, 19 Feb 2015 03:34:58 -0800 (PST) X-Received: by 10.68.132.67 with SMTP id os3mr6945283pbb.1.1424345697392; Thu, 19 Feb 2015 03:34:57 -0800 (PST) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u14si364614pdi.41.2015.02.19.03.34.56; Thu, 19 Feb 2015 03:34:57 -0800 (PST) Received-SPF: none (google.com: linux-pm-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753493AbbBSLen (ORCPT + 11 others); Thu, 19 Feb 2015 06:34:43 -0500 Received: from mail-pa0-f45.google.com ([209.85.220.45]:45626 "EHLO mail-pa0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753487AbbBSLel (ORCPT ); Thu, 19 Feb 2015 06:34:41 -0500 Received: by pablf10 with SMTP id lf10so8797014pab.12 for ; Thu, 19 Feb 2015 03:34:40 -0800 (PST) X-Received: by 10.67.6.225 with SMTP id cx1mr6898208pad.1.1424345680815; Thu, 19 Feb 2015 03:34:40 -0800 (PST) Received: from localhost ([122.172.249.58]) by mx.google.com with ESMTPSA id os6sm23751238pac.28.2015.02.19.03.34.39 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 19 Feb 2015 03:34:40 -0800 (PST) From: Viresh Kumar To: Rafael Wysocki Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, sboyd@codeaurora.org, prarit@redhat.com, skannan@codeaurora.org, Viresh Kumar , Srivatsa Bhat Subject: [PATCH V2 20/20] cpufreq: Add support for physical hoplug of CPUs Date: Thu, 19 Feb 2015 17:02:22 +0530 Message-Id: X-Mailer: git-send-email 2.3.0.rc0.44.ga94655d In-Reply-To: References: In-Reply-To: References: Sender: linux-pm-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: viresh.kumar@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.49 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , It is possible to physically hotplug the CPUs and it happens in this sequence. Hot removal: - CPU is offlined first, ~ 'echo 0 > /sys/devices/system/cpu/cpuX/online' - Then its device is removed along with all sysfs files, cpufreq core notified with cpufreq_remove_dev() callback from subsys-interface.. Hot addition: - First the device along with its sysfs files is added, cpufreq core notified with cpufreq_add_dev() callback from subsys-interface.. - CPU is onlined, ~ 'echo 1 > /sys/devices/system/cpu/cpuX/online' This needs to be handled specially as current code isn't taking care of this case. Because we will hit the same routines with both hotplug and subsys callbacks, we can handle most of the stuff with regular hotplug callback paths. We only need to take care of adding/removing cpufreq sysfs links or freeing policy from subsys callbacks. And that can be sensed easily as cpu would be offline in those cases. This patch adds special code in those paths to take care of policy and its links. cpufreq_add_remove_dev_symlink() is also broken into another routine add_remove_cpu_dev_symlink() to reuse code at several places. Cc: Srivatsa Bhat Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 87 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 22 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index ffb6700c7195..3213d81a822c 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -972,6 +972,26 @@ void cpufreq_sysfs_remove_file(const struct attribute *attr) } EXPORT_SYMBOL(cpufreq_sysfs_remove_file); +static inline int add_remove_cpu_dev_symlink(struct cpufreq_policy *policy, + int cpu, bool add) +{ + struct device *cpu_dev; + + pr_debug("%s: %s symlink for CPU: %u\n", __func__, + add ? "Adding" : "Removing", cpu); + + cpu_dev = get_cpu_device(cpu); + if (WARN_ON(!cpu_dev)) + return 0; + + if (add) + return sysfs_create_link(&cpu_dev->kobj, &policy->kobj, + "cpufreq"); + + sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); + return 0; +} + /* Add/remove symlinks for all related CPUs */ static int cpufreq_add_remove_dev_symlink(struct cpufreq_policy *policy, bool add) @@ -979,27 +999,14 @@ static int cpufreq_add_remove_dev_symlink(struct cpufreq_policy *policy, unsigned int j; int ret = 0; - for_each_cpu(j, policy->related_cpus) { - struct device *cpu_dev; - + /* Some related CPUs might not be present (physically hotplugged) */ + for_each_cpu_and(j, policy->related_cpus, cpu_present_mask) { if (j == policy->kobj_cpu) continue; - pr_debug("%s: %s symlink for CPU: %u\n", __func__, - add ? "Adding" : "Removing", j); - - cpu_dev = get_cpu_device(j); - if (WARN_ON(!cpu_dev)) - continue; - - if (add) { - ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, - "cpufreq"); - if (ret) - break; - } else { - sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); - } + ret = add_remove_cpu_dev_symlink(policy, j, add); + if (ret) + break; } return ret; @@ -1233,11 +1240,23 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) unsigned long flags; bool recover_policy = !sif; - if (cpu_is_offline(cpu)) - return 0; - pr_debug("adding CPU %u\n", cpu); + /* + * Only possible if 'cpu' wasn't physically present earlier and we are + * here from subsys_interface add callback. A hotplug notifier will + * follow and we will handle it like logical CPU hotplug then. For now, + * just create the sysfs link. + */ + if (cpu_is_offline(cpu)) { + policy = per_cpu(cpufreq_cpu_data, cpu); + /* No need to create link of the first cpu of a policy */ + if (!policy) + return 0; + + return add_remove_cpu_dev_symlink(policy, cpu, true); + } + if (!down_read_trylock(&cpufreq_rwsem)) return 0; @@ -1496,8 +1515,32 @@ static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) unsigned int cpu = dev->id; int ret; - if (cpu_is_offline(cpu)) + /* + * Only possible if 'cpu' is getting physically removed now. A hotplug + * notifier should have already been called and we just need to remove + * link or free policy here. + */ + if (cpu_is_offline(cpu)) { + struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); + struct cpumask mask; + + if (!policy) + return 0; + + /* Prepare mask similar to related-cpus without this 'cpu' */ + cpumask_copy(&mask, policy->related_cpus); + cpumask_clear_cpu(cpu, &mask); + + /* + * Remove link if few CPUs are still present physically, else + * free policy when all are gone. + */ + if (cpumask_intersects(&mask, cpu_present_mask)) + return add_remove_cpu_dev_symlink(policy, cpu, false); + + cpufreq_policy_free(policy, true); return 0; + } ret = __cpufreq_remove_dev_prepare(dev, sif);