Thread (74 messages) 74 messages, 7 authors, 2018-11-20

[PATCH v8 04/26] PM / Domains: Add support for CPU devices to genpd

From: rafael@kernel.org (Rafael J. Wysocki)
Date: 2018-08-06 09:36:07
Also in: linux-arm-msm, linux-pm, lkml

On Fri, Aug 3, 2018 at 1:43 PM, Ulf Hansson [off-list ref] wrote:
On 19 July 2018 at 12:25, Rafael J. Wysocki [off-list ref] wrote:
quoted
On Wednesday, June 20, 2018 7:22:04 PM CEST Ulf Hansson wrote:
quoted
To enable a device belonging to a CPU to be attached to a PM domain managed
by genpd, let's do a few changes to genpd as to make it convenient to
manage the specifics around CPUs.

First, as to be able to quickly find out what CPUs that are attached to a
genpd, which typically becomes useful from a genpd governor as following
changes is about to show, let's add a cpumask 'cpus' to the struct
generic_pm_domain.

At the point when a device that belongs to a CPU, is attached/detached to
its corresponding PM domain via genpd_add_device(), let's update the
cpumask in genpd->cpus. Moreover, propagate the update of the cpumask to
the master domains, which makes the genpd->cpus to contain a cpumask that
hierarchically reflect all CPUs for a genpd, including CPUs attached to
subdomains.

Second, to unconditionally manage CPUs and the cpumask in genpd->cpus, is
unnecessary for cases when only non-CPU devices are parts of a genpd.
Let's avoid this by adding a new configuration bit, GENPD_FLAG_CPU_DOMAIN.
Clients must set the bit before they call pm_genpd_init(), as to instruct
genpd that it shall deal with CPUs and thus manage the cpumask in
genpd->cpus.

Cc: Lina Iyer <redacted>
Co-developed-by: Lina Iyer <redacted>
Signed-off-by: Ulf Hansson <redacted>
---
 drivers/base/power/domain.c | 69 ++++++++++++++++++++++++++++++++++++-
 include/linux/pm_domain.h   |  3 ++
 2 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 21d298e1820b..6149ce0bfa7b 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -20,6 +20,7 @@
 #include <linux/sched.h>
 #include <linux/suspend.h>
 #include <linux/export.h>
+#include <linux/cpu.h>

 #include "power.h"
@@ -126,6 +127,7 @@ static const struct genpd_lock_ops genpd_spin_ops = {
 #define genpd_is_irq_safe(genpd)     (genpd->flags & GENPD_FLAG_IRQ_SAFE)
 #define genpd_is_always_on(genpd)    (genpd->flags & GENPD_FLAG_ALWAYS_ON)
 #define genpd_is_active_wakeup(genpd)        (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP)
+#define genpd_is_cpu_domain(genpd)   (genpd->flags & GENPD_FLAG_CPU_DOMAIN)

 static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev,
              const struct generic_pm_domain *genpd)
@@ -1377,6 +1379,62 @@ static void genpd_free_dev_data(struct device *dev,
      dev_pm_put_subsys_data(dev);
 }

+static void __genpd_update_cpumask(struct generic_pm_domain *genpd,
+                                int cpu, bool set, unsigned int depth)
+{
+     struct gpd_link *link;
+
+     if (!genpd_is_cpu_domain(genpd))
+             return;
+
+     list_for_each_entry(link, &genpd->slave_links, slave_node) {
+             struct generic_pm_domain *master = link->master;
+
+             genpd_lock_nested(master, depth + 1);
+             __genpd_update_cpumask(master, cpu, set, depth + 1);
+             genpd_unlock(master);
+     }
+
+     if (set)
+             cpumask_set_cpu(cpu, genpd->cpus);
+     else
+             cpumask_clear_cpu(cpu, genpd->cpus);
+}
As noted elsewhere, there is a concern about the possible weight of this
cpumask and I think that it would be good to explicitly put a limit on it.
I have been digesting your comments on the series, but wonder if this
is still a relevant concern?
Well, there are systems with very large cpumasks and it is sort of
good to have that in mind when designing any code using them.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help