Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp561880ybi; Tue, 16 Jul 2019 01:47:10 -0700 (PDT) X-Google-Smtp-Source: APXvYqwyL8gN7jjNsE3UMnWCK1aEZbgAsC8bKJdOAeUvaUQa0/9c0p7/FIAt1ztXUpOZkDlQSyKi X-Received: by 2002:a63:fa4e:: with SMTP id g14mr31955642pgk.237.1563266830234; Tue, 16 Jul 2019 01:47:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1563266830; cv=none; d=google.com; s=arc-20160816; b=roVxLFZAZOpqtLPSZ0+XoHZQh1YVzhtzMnTF7TMUJyT4utDXt9ifzK3BZfU5Q6Kye5 /5n7wgdAwhm7LQr++PedJna9dO2e5KwZXjexPD6mcha0mrkev9iWmXO9RRPg2zU96ZRu lXINijWBnU27FPvNqoFe3EaRxCh7WkTsuEKCA3KHqYGU6Odh2+z/D8MBHygycy/4TtsM +bTlmpAW7TEW0aDD36c44/Cb5u9If4mx8UNQmJXHO+glMcFh4ZHtNPHAnD+mg+uiIkvM ekDWj4GcI/asP1S1rKxZ3z5ggAh2pwgg6QqKvuBvc03EGwphWyxmMDmnmiXU935IFmzd txQQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=NBVHquOpHCj1lFm8EjHsR8Y4yEo3VOFxQv1yTdErFMI=; b=uYvE5KlKFVkfrYYb063n9xyhRUyGm3SWMojP7ijv+iL3ET4z/iveWsad4hCUY+BYL0 ffRrcKl+gHMqGGPkp1Qv2OrtGdZHRa9il5xyJ7gPZpVPJwBsIs/fkQQW8cEri6A013kb p9XCD2t63git8k3a4kfDQ+cKxa3qaHfO1a2mNMFTVKD5S39VC9HsFFctoscGP9PVBcdZ BTiT5dZm4eO+KFiqZHen0MDit8lkg4Y468k4QtVmrp6iya553+aLpATNjGlcvnxwLqNd G68CNCU0wuwUCbvXFAYJ+ZsiW5lroAwhiguJdHpIlkJuJkmBpTBRCr3Y0sDhd7PTN5d3 kN+g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ImcB64Ys; 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 v186si18514344pgd.358.2019.07.16.01.46.53; Tue, 16 Jul 2019 01:47:10 -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 header.s=google header.b=ImcB64Ys; 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 S1731402AbfGPIq2 (ORCPT + 99 others); Tue, 16 Jul 2019 04:46:28 -0400 Received: from mail-ua1-f67.google.com ([209.85.222.67]:42659 "EHLO mail-ua1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727829AbfGPIq1 (ORCPT ); Tue, 16 Jul 2019 04:46:27 -0400 Received: by mail-ua1-f67.google.com with SMTP id a97so7840247uaa.9 for ; Tue, 16 Jul 2019 01:46:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=NBVHquOpHCj1lFm8EjHsR8Y4yEo3VOFxQv1yTdErFMI=; b=ImcB64YsoZNyYRw61c36XDOwtCGTj3HynvPTU9TSL1vV4eQfqWk9cFiJzJncZbKUqZ cZFFCwdDDohk/80qZU6xQeR5vixhx5Z8UfLfdbq988cxJaPcTlE5sSARFyqIoxvaLd5p nyWveUgv1khGANlpDp2raHrCrcUMtxyhz8sAtz41ntvwMAW3LE32DbDl8apfq8dGkRDZ UX2Lz+7rWzY32m7eI9KQOfRS1Fn6G07QF3tpo7xfOGuM05xuLIkkOXk/7EpE/9skZ1c6 PyW44Ifn8NU967I5TZvxBpz7Q8x1U2J3bkLSKK43QDMMj+8+qsIUF5HdJUki448yd0WV SPdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=NBVHquOpHCj1lFm8EjHsR8Y4yEo3VOFxQv1yTdErFMI=; b=p9XEc6NhPPgFBKSdSlm8M5pb5GZoX5XOywOmkmSYqrcyLosGeBsFlH8zTPvkjTDWrk HXk7lYwkIOYfF8MA9qeEYfOUxYu8XgFnZfUUJm463D9O4QxcSp5G2ol0xQbT1KX6yoqu ND8n1zTw8oVekQw29wekCFiT0Hzjw0e0IMqgWV7NFJ8qwMLx+A77jTay4pLRBGwUavwE vZ6s3NEvQxh14vAcXtsfaVyZwksKp6X8TIa23tEcA9wGmuumMXfveoty/xUg/TJLFFCO HpEjeQQqiOpJhaDTefliJJ7WE9ycyhhBePgLCs+ONtl2IS2cNghWOtCvkqqs8/NOAD0Y QOVA== X-Gm-Message-State: APjAAAVUyjScs42NWfD9CCsgEv7ZZ7lunkFrvHx9YtIMhL1uq+P0Y1z8 e9W0AkDUhLx1b6Qy2YUm11HT/z8VfbGnyYZNVswIWQ== X-Received: by 2002:ab0:60ad:: with SMTP id f13mr8811202uam.129.1563266786313; Tue, 16 Jul 2019 01:46:26 -0700 (PDT) MIME-Version: 1.0 References: <20190513192300.653-1-ulf.hansson@linaro.org> <20190513192300.653-11-ulf.hansson@linaro.org> <20190709153138.GA22871@e121166-lin.cambridge.arm.com> In-Reply-To: <20190709153138.GA22871@e121166-lin.cambridge.arm.com> From: Ulf Hansson Date: Tue, 16 Jul 2019 10:45:49 +0200 Message-ID: Subject: Re: [PATCH 10/18] drivers: firmware: psci: Add hierarchical domain idle states converter To: Lorenzo Pieralisi Cc: Sudeep Holla , Mark Rutland , Linux ARM , "Rafael J . Wysocki" , Daniel Lezcano , "Raju P . L . S . S . S . N" , Amit Kucheria , Bjorn Andersson , Stephen Boyd , Niklas Cassel , Tony Lindgren , Kevin Hilman , Lina Iyer , Viresh Kumar , Vincent Guittot , Geert Uytterhoeven , Souvik Chakravarty , Linux PM , linux-arm-msm , Linux Kernel Mailing List Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Lorenzo, Just wanted to give some feedback to you in public, even if we have already discussed this series, offlist, last week. On Tue, 9 Jul 2019 at 17:31, Lorenzo Pieralisi wrote: > > On Mon, May 13, 2019 at 09:22:52PM +0200, Ulf Hansson wrote: > > If the hierarchical CPU topology is used, but the OS initiated mode isn't > > supported, we need to rely solely on the regular cpuidle framework to > > manage the idle state selection, rather than using genpd and its governor. > > > > For this reason, introduce a new PSCI DT helper function, > > psci_dt_pm_domains_parse_states(), which parses and converts the > > hierarchically described domain idle states from DT, into regular flattened > > cpuidle states. The converted states are added to the existing cpuidle > > driver's array of idle states, which make them available for cpuidle. > > > > Signed-off-by: Ulf Hansson > > --- > > > > Changes: > > - Some simplification of the code. > > > > --- > > drivers/firmware/psci/psci.h | 5 ++ > > drivers/firmware/psci/psci_pm_domain.c | 118 +++++++++++++++++++++++++ > > 2 files changed, 123 insertions(+) > > > > diff --git a/drivers/firmware/psci/psci.h b/drivers/firmware/psci/psci.h > > index 00d2e3dcef49..c36e0e6649e9 100644 > > --- a/drivers/firmware/psci/psci.h > > +++ b/drivers/firmware/psci/psci.h > > @@ -3,6 +3,7 @@ > > #ifndef __PSCI_H > > #define __PSCI_H > > > > +struct cpuidle_driver; > > struct device_node; > > > > int psci_set_osi_mode(void); > > @@ -13,8 +14,12 @@ void psci_set_domain_state(u32 state); > > int psci_dt_parse_state_node(struct device_node *np, u32 *state); > > #ifdef CONFIG_PM_GENERIC_DOMAINS_OF > > int psci_dt_init_pm_domains(struct device_node *np); > > +int psci_dt_pm_domains_parse_states(struct cpuidle_driver *drv, > > + struct device_node *cpu_node, u32 *psci_states); > > #else > > static inline int psci_dt_init_pm_domains(struct device_node *np) { return 0; } > > +static inline int psci_dt_pm_domains_parse_states(struct cpuidle_driver *drv, > > + struct device_node *cpu_node, u32 *psci_states) { return 0; } > > #endif > > #endif > > > > diff --git a/drivers/firmware/psci/psci_pm_domain.c b/drivers/firmware/psci/psci_pm_domain.c > > index 3c6ca846caf4..3aa645dba81b 100644 > > --- a/drivers/firmware/psci/psci_pm_domain.c > > +++ b/drivers/firmware/psci/psci_pm_domain.c > > @@ -14,6 +14,10 @@ > > #include > > #include > > #include > > +#include > > +#include > > + > > +#include > > > > #include "psci.h" > > > > @@ -104,6 +108,53 @@ static void psci_pd_free_states(struct genpd_power_state *states, > > kfree(states); > > } > > > > +static int psci_pd_enter_pc(struct cpuidle_device *dev, > > + struct cpuidle_driver *drv, int idx) > > +{ > > + return CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, idx); > > +} > > + > > +static void psci_pd_enter_s2idle_pc(struct cpuidle_device *dev, > > + struct cpuidle_driver *drv, int idx) > > +{ > > + psci_pd_enter_pc(dev, drv, idx); > > +} > > + > > +static void psci_pd_convert_states(struct cpuidle_state *idle_state, > > + u32 *psci_state, struct genpd_power_state *state) > > +{ > > + u32 *state_data = state->data; > > + u64 target_residency_us = state->residency_ns; > > + u64 exit_latency_us = state->power_on_latency_ns + > > + state->power_off_latency_ns; > > + > > + *psci_state = *state_data; > > + do_div(target_residency_us, 1000); > > + idle_state->target_residency = target_residency_us; > > + do_div(exit_latency_us, 1000); > > + idle_state->exit_latency = exit_latency_us; > > + idle_state->enter = &psci_pd_enter_pc; > > + idle_state->enter_s2idle = &psci_pd_enter_s2idle_pc; > > + idle_state->flags |= CPUIDLE_FLAG_TIMER_STOP; > > This is arbitrary and not necessarily true. The arbitrary thing you refer to here, is that the CPUIDLE_FLAG_TIMER_STOP? Or are you referring to the complete function psci_pd_convert_states()? > > I think that this patch is useful to represent my reservations about the > current approach. As a matter of fact, idle state entry will always be a > CPUidle decision. > > You only need PM domain information to understand when all CPUs > in a power domain are actually idle but that's all genPD can do > in this respect. > > I think this patchset would be much simpler if both CPUidle and > genPD governor would work on *one* set of idle states, globally > indexed (and that would be true for PSCI suspend parameters too). > > To work with a unified set of idle states between CPUidle and genPD > (tossing some ideas around): > > - We can implement a genPD CPUidle governor that in its select method > takes into account genPD information (for instance by avoiding > selection of idle states that require multiple cpus to be in idle > to be effectively active) > - We can use genPD to enable/disable CPUidle states through runtime > PM information I don't understand how to make this work. The CPUidle governor works on per CPU basis. The genpd governor works on per PM domain basis, which typically can be a group of CPUs (and even other devices) via subdomains, for example. 1. In case of Linux being in *charge* of what idle state to pick for a group of CPUs, that decision is best done by the genpd governor as it operates on "groups" of CPUs. This is used for PSCI OSI mode. Of course, there are idle states also per CPU, which potentially could be managed by the genpd governor as well, but at this point I decided to re-use the cpuidle governor as it's already doing the job. 2. In case the decision of what idle state to enter for the group is done by the FW, we can rely solely on the cpuidle governor and let it select states per CPU basis. This is used for PSCI PC mode. > > There may be other ways. My point is that current code, with two (or > more if the hierarchy grows) sets of idle states across two subsystems > (CPUidle and genPD) is not very well defined and honestly very hard to > grasp and prone to errors. The complexity is there, I admit that. I guess some deeper insight about genpd+its governor+runtime PM are needed when reviewing this, of course. As an option, you may also have a look at my slides [1] from OSPM (Pisa) in May this year, which via flow charts try to describes things in more detail. In our offlist meeting, we discussed that perhaps moving some of the new PSCI code introduced in this series, into a cpuidle driver instead, could make things more clear. For sure, I can explore that option, but before I go there, I think we should agree on it publicly. In principle what it means is to invent a special cpuidle driver for PSCI, so we would need access to some of the PSCI internal functions, for example. One thing though, the initialization of the PSCI PM domain topology is a separate step, managed via the new initcall, psci_dt_topology_init() (introduced in patch 11). That part still seems to be belong to the PSCI code, don't you think? > > > + > > + strncpy(idle_state->name, to_of_node(state->fwnode)->name, > > + CPUIDLE_NAME_LEN - 1); > > + strncpy(idle_state->desc, to_of_node(state->fwnode)->name, > > + CPUIDLE_NAME_LEN - 1); > > +} > > + > > +static bool psci_pd_is_provider(struct device_node *np) > > +{ > > + struct psci_pd_provider *pd_prov, *it; > > + > > + list_for_each_entry_safe(pd_prov, it, &psci_pd_providers, link) { > > + if (pd_prov->node == np) > > + return true; > > + } > > + > > + return false; > > +} > > + > > static int psci_pd_init(struct device_node *np) > > { > > struct generic_pm_domain *pd; > > @@ -265,4 +316,71 @@ int psci_dt_init_pm_domains(struct device_node *np) > > pr_err("failed to create CPU PM domains ret=%d\n", ret); > > return ret; > > } > > + > > +int psci_dt_pm_domains_parse_states(struct cpuidle_driver *drv, > > + struct device_node *cpu_node, u32 *psci_states) > > +{ > > + struct genpd_power_state *pd_states; > > + struct of_phandle_args args; > > + int ret, pd_state_count, i, state_idx, psci_idx; > > + u32 cpu_psci_state = psci_states[drv->state_count - 2]; > > This (-2) is very dodgy and I doubt it would work on hierarchies going > above "cluster" level. > > As I say above, I think we should work towards a single array of > idle states to be selected by a CPUidle governor using genPD > runtime information to bias the results according to the number > of CPUs in a genPD that entered/exit idle. > > To be more precise, all idles states should be "domain-idle-state" > compatible, even the CPU ones, the distinction between what CPUidle > and genPD manage is a bit stretched IMO in this patchset. > > We will have a chance to talk about this but I thought I would > comment publically if anyone else is willing to chime in, this > is not a PSCI problem at all, it is a CPUidle/genPD coexistence > design problem which is much broader. To move this forward, I think we need to move from vague ideas to clear and distinct plans. Whatever that means. :-) I understand you are concerned about the level of changes introduced to the PSCI code. As I stated somewhere in earlier replies, I picked that approach as I thought it was better to implement things in a PSCI specific manner to start with, then we could move things around, when we realize that it make sense. Anyway, as a suggestion to address your concern, how about this: 1. Move some things out to a PSCI cpuidle driver. We need to decide more exactly on what to move and find the right level for the interfaces. 2. Don't attach the CPU to the PM domain topology in case the PSCI PC mode is used. I think this makes it easier, at least as a first step, to understand when runtime PM needs to be used/enabled. 3. Would it help if I volunteer to help you guys as a maintainer for PSCI. At least for the part of the new code that becomes introduced? [...] Kind regards Uffe