From patchwork Fri May 8 06:23:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 48158 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f69.google.com (mail-la0-f69.google.com [209.85.215.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id AA9D52121F for ; Fri, 8 May 2015 06:25:30 +0000 (UTC) Received: by labgx2 with SMTP id gx2sf20207082lab.1 for ; Thu, 07 May 2015 23:25:29 -0700 (PDT) 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=KdtVGoN0PL6JY6oJGDdzskKT2FNDcbb4QcYUcb7zegM=; b=EiR5bCKIreTwhPzgAo6Lz5L8A+VWPRSF3WDdAGWCvDVLx3N1uIEjILGT+7eEnpyqBY mLExLZrUZ1npcQrl8bscmmt9zO2YIC6ZHwZh1dGVjbCBuqyccRQNeAYI3WmwxIp+KKU7 o5dPilthPeV5W88vh5NY5PoCrgiGDmRBVNZuYXWzTN5ZjRDIwXErn5Aav7RC1yHkfnZV BQvIcFT6U5VeiZ4uIipQioLZDYSdLqgiwmgXKo0ndbS2QvRxPdHMOsSyYiY7182hIksZ Nv1/H29x6xP4VlUOqkug86bI8tUKlNegjnWETuPrhz1xwezGyT25JtUDY+DrgLCeJrT1 JrWQ== X-Gm-Message-State: ALoCoQmbazMHCb3noec2PqR5qbqeWmFHE2yK/OjRsI86cKdi0aljcIOUXDomzCfaWA4ejPgSmoDJ X-Received: by 10.180.105.226 with SMTP id gp2mr1037095wib.1.1431066329700; Thu, 07 May 2015 23:25:29 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.153.8.171 with SMTP id dl11ls275989lad.55.gmail; Thu, 07 May 2015 23:25:29 -0700 (PDT) X-Received: by 10.112.220.34 with SMTP id pt2mr1670399lbc.81.1431066329540; Thu, 07 May 2015 23:25:29 -0700 (PDT) Received: from mail-la0-f44.google.com (mail-la0-f44.google.com. [209.85.215.44]) by mx.google.com with ESMTPS id e4si2664530lab.140.2015.05.07.23.25.29 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 May 2015 23:25:29 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.44 as permitted sender) client-ip=209.85.215.44; Received: by lagv1 with SMTP id v1so45997895lag.3 for ; Thu, 07 May 2015 23:25:29 -0700 (PDT) X-Received: by 10.152.29.161 with SMTP id l1mr1649793lah.76.1431066329435; Thu, 07 May 2015 23:25:29 -0700 (PDT) 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.108.230 with SMTP id hn6csp269443lbb; Thu, 7 May 2015 23:25:28 -0700 (PDT) X-Received: by 10.69.1.3 with SMTP id bc3mr4041467pbd.36.1431066327400; Thu, 07 May 2015 23:25:27 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t17si5783046pdi.227.2015.05.07.23.25.26; Thu, 07 May 2015 23:25:27 -0700 (PDT) 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 S1750994AbbEHGZ0 (ORCPT + 11 others); Fri, 8 May 2015 02:25:26 -0400 Received: from mail-pd0-f182.google.com ([209.85.192.182]:35968 "EHLO mail-pd0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751474AbbEHGZZ (ORCPT ); Fri, 8 May 2015 02:25:25 -0400 Received: by pdea3 with SMTP id a3so67146557pde.3 for ; Thu, 07 May 2015 23:25:25 -0700 (PDT) X-Received: by 10.66.121.227 with SMTP id ln3mr4066351pab.68.1431066308153; Thu, 07 May 2015 23:25:08 -0700 (PDT) Received: from localhost ([122.172.243.237]) by mx.google.com with ESMTPSA id l1sm3987533pdp.71.2015.05.07.23.25.06 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 07 May 2015 23:25:07 -0700 (PDT) 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, Srivatsa Bhat , Viresh Kumar Subject: [PATCH V3 14/14] cpufreq: Add support for physical hoplug of CPUs Date: Fri, 8 May 2015 11:53:57 +0530 Message-Id: <22ea2a0dd3e860d9b0e8703f49d07ca32e2fc490.1431065963.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.4.0 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.44 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. 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 6bbc7b112e7a..234ced430057 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -973,6 +973,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) @@ -980,27 +1000,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; @@ -1234,11 +1241,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; @@ -1495,8 +1514,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);