public inbox for linux-rt-users@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT
@ 2024-05-27 14:25 Ulf Hansson
  2024-05-27 14:25 ` [PATCH v2 1/7] pmdomain: core: Enable s2idle for CPU PM domains " Ulf Hansson
                   ` (9 more replies)
  0 siblings, 10 replies; 23+ messages in thread
From: Ulf Hansson @ 2024-05-27 14:25 UTC (permalink / raw)
  To: Rafael J . Wysocki, Sudeep Holla, linux-pm
  Cc: Lorenzo Pieralisi, Nikunj Kela, Prasad Sodagudi, Maulik Shah,
	Daniel Lezcano, Krzysztof Kozlowski, Ulf Hansson, linux-rt-users,
	linux-arm-kernel, linux-kernel

Updates in v2:
	- Rebased and fixed a small issue in genpd, see patch3.
	- Re-tested on v6.9-rt5 (PREEMPT_RT enabled)
	- Re-tested on v6.10-rc1 (for regressions, PREEMPT_RT disabled)

The hierarchical PM domain topology and the corresponding domain-idle-states
are currently disabled on a PREEMPT_RT based configuration. The main reason is
because spinlocks are turned into sleepable locks on PREEMPT_RT, which means
genpd and runtime PM can't be use in the atomic idle-path when
selecting/entering an idle-state.

For s2idle/s2ram this is an unnecessary limitation that this series intends to
address. Note that, the support for cpuhotplug is left to future improvements.
More information about this are available in the commit messages.

I have tested this on a Dragonboard 410c.

Kind regards
Ulf Hansson


Ulf Hansson (7):
  pmdomain: core: Enable s2idle for CPU PM domains on PREEMPT_RT
  pmdomain: core: Don't hold the genpd-lock when calling
    dev_pm_domain_set()
  pmdomain: core: Use dev_name() instead of kobject_get_path() in
    debugfs
  cpuidle: psci-domain: Enable system-wide suspend on PREEMPT_RT
  cpuidle: psci: Drop redundant assignment of CPUIDLE_FLAG_RCU_IDLE
  cpuidle: psci: Enable the hierarchical topology for s2ram on
    PREEMPT_RT
  cpuidle: psci: Enable the hierarchical topology for s2idle on
    PREEMPT_RT

 drivers/cpuidle/cpuidle-psci-domain.c | 10 ++--
 drivers/cpuidle/cpuidle-psci.c        | 26 ++++++----
 drivers/pmdomain/core.c               | 75 +++++++++++++++++++--------
 include/linux/pm_domain.h             |  5 +-
 4 files changed, 80 insertions(+), 36 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v2 1/7] pmdomain: core: Enable s2idle for CPU PM domains on PREEMPT_RT
  2024-05-27 14:25 [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT Ulf Hansson
@ 2024-05-27 14:25 ` Ulf Hansson
  2024-05-28 19:55   ` Nikunj Kela
  2024-05-27 14:25 ` [PATCH v2 2/7] pmdomain: core: Don't hold the genpd-lock when calling dev_pm_domain_set() Ulf Hansson
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Ulf Hansson @ 2024-05-27 14:25 UTC (permalink / raw)
  To: Rafael J . Wysocki, Sudeep Holla, linux-pm
  Cc: Lorenzo Pieralisi, Nikunj Kela, Prasad Sodagudi, Maulik Shah,
	Daniel Lezcano, Krzysztof Kozlowski, Ulf Hansson, linux-rt-users,
	linux-arm-kernel, linux-kernel

To allow a genpd provider for a CPU PM domain to enter a domain-idle-state
during s2idle on a PREEMPT_RT based configuration, we can't use the regular
spinlock, as they are turned into sleepable locks on PREEMPT_RT.

To address this problem, let's convert into using the raw spinlock, but
only for genpd providers that have the GENPD_FLAG_CPU_DOMAIN bit set. In
this way, the lock can still be acquired/released in atomic context, which
is needed in the idle-path for PREEMPT_RT.

Do note that the genpd power-on/off notifiers may also be fired during
s2idle, but these are already prepared for PREEMPT_RT as they are based on
the raw notifiers. However, consumers of them may need to adopt accordingly
to work properly on PREEMPT_RT.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- None.

---
 drivers/pmdomain/core.c   | 47 ++++++++++++++++++++++++++++++++++++++-
 include/linux/pm_domain.h |  5 ++++-
 2 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 623d15b68707..072e6bdb6ee6 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -117,6 +117,48 @@ static const struct genpd_lock_ops genpd_spin_ops = {
 	.unlock = genpd_unlock_spin,
 };
 
+static void genpd_lock_raw_spin(struct generic_pm_domain *genpd)
+	__acquires(&genpd->raw_slock)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&genpd->raw_slock, flags);
+	genpd->raw_lock_flags = flags;
+}
+
+static void genpd_lock_nested_raw_spin(struct generic_pm_domain *genpd,
+					int depth)
+	__acquires(&genpd->raw_slock)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave_nested(&genpd->raw_slock, flags, depth);
+	genpd->raw_lock_flags = flags;
+}
+
+static int genpd_lock_interruptible_raw_spin(struct generic_pm_domain *genpd)
+	__acquires(&genpd->raw_slock)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&genpd->raw_slock, flags);
+	genpd->raw_lock_flags = flags;
+	return 0;
+}
+
+static void genpd_unlock_raw_spin(struct generic_pm_domain *genpd)
+	__releases(&genpd->raw_slock)
+{
+	raw_spin_unlock_irqrestore(&genpd->raw_slock, genpd->raw_lock_flags);
+}
+
+static const struct genpd_lock_ops genpd_raw_spin_ops = {
+	.lock = genpd_lock_raw_spin,
+	.lock_nested = genpd_lock_nested_raw_spin,
+	.lock_interruptible = genpd_lock_interruptible_raw_spin,
+	.unlock = genpd_unlock_raw_spin,
+};
+
 #define genpd_lock(p)			p->lock_ops->lock(p)
 #define genpd_lock_nested(p, d)		p->lock_ops->lock_nested(p, d)
 #define genpd_lock_interruptible(p)	p->lock_ops->lock_interruptible(p)
@@ -2079,7 +2121,10 @@ static void genpd_free_data(struct generic_pm_domain *genpd)
 
 static void genpd_lock_init(struct generic_pm_domain *genpd)
 {
-	if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
+	if (genpd->flags & GENPD_FLAG_CPU_DOMAIN) {
+		raw_spin_lock_init(&genpd->raw_slock);
+		genpd->lock_ops = &genpd_raw_spin_ops;
+	} else if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
 		spin_lock_init(&genpd->slock);
 		genpd->lock_ops = &genpd_spin_ops;
 	} else {
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index f24546a3d3db..0d7fc47de3bc 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -194,8 +194,11 @@ struct generic_pm_domain {
 			spinlock_t slock;
 			unsigned long lock_flags;
 		};
+		struct {
+			raw_spinlock_t raw_slock;
+			unsigned long raw_lock_flags;
+		};
 	};
-
 };
 
 static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 2/7] pmdomain: core: Don't hold the genpd-lock when calling dev_pm_domain_set()
  2024-05-27 14:25 [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT Ulf Hansson
  2024-05-27 14:25 ` [PATCH v2 1/7] pmdomain: core: Enable s2idle for CPU PM domains " Ulf Hansson
@ 2024-05-27 14:25 ` Ulf Hansson
  2024-05-27 14:25 ` [PATCH v2 3/7] pmdomain: core: Use dev_name() instead of kobject_get_path() in debugfs Ulf Hansson
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 23+ messages in thread
From: Ulf Hansson @ 2024-05-27 14:25 UTC (permalink / raw)
  To: Rafael J . Wysocki, Sudeep Holla, linux-pm
  Cc: Lorenzo Pieralisi, Nikunj Kela, Prasad Sodagudi, Maulik Shah,
	Daniel Lezcano, Krzysztof Kozlowski, Ulf Hansson, linux-rt-users,
	linux-arm-kernel, linux-kernel

There is no need to hold the genpd-lock, while assigning the
dev->pm_domain. In fact, it becomes a problem on a PREEMPT_RT based
configuration as the genpd-lock may be a raw spinlock, while the lock
acquired through the call to dev_pm_domain_set() is a regular spinlock.

To fix the problem, let's simply move the calls to dev_pm_domain_set()
outside the genpd-lock.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes in v2:
	- None.

---
 drivers/pmdomain/core.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 072e6bdb6ee6..454fccc38df1 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -1736,7 +1736,6 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
 	genpd_lock(genpd);
 
 	genpd_set_cpumask(genpd, gpd_data->cpu);
-	dev_pm_domain_set(dev, &genpd->domain);
 
 	genpd->device_count++;
 	if (gd)
@@ -1745,6 +1744,7 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
 	list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
 
 	genpd_unlock(genpd);
+	dev_pm_domain_set(dev, &genpd->domain);
  out:
 	if (ret)
 		genpd_free_dev_data(dev, gpd_data);
@@ -1801,12 +1801,13 @@ static int genpd_remove_device(struct generic_pm_domain *genpd,
 		genpd->gd->max_off_time_changed = true;
 
 	genpd_clear_cpumask(genpd, gpd_data->cpu);
-	dev_pm_domain_set(dev, NULL);
 
 	list_del_init(&pdd->list_node);
 
 	genpd_unlock(genpd);
 
+	dev_pm_domain_set(dev, NULL);
+
 	if (genpd->detach_dev)
 		genpd->detach_dev(genpd, dev);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 3/7] pmdomain: core: Use dev_name() instead of kobject_get_path() in debugfs
  2024-05-27 14:25 [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT Ulf Hansson
  2024-05-27 14:25 ` [PATCH v2 1/7] pmdomain: core: Enable s2idle for CPU PM domains " Ulf Hansson
  2024-05-27 14:25 ` [PATCH v2 2/7] pmdomain: core: Don't hold the genpd-lock when calling dev_pm_domain_set() Ulf Hansson
@ 2024-05-27 14:25 ` Ulf Hansson
  2024-08-20  8:55   ` Geert Uytterhoeven
  2024-05-27 14:25 ` [PATCH v2 4/7] cpuidle: psci-domain: Enable system-wide suspend on PREEMPT_RT Ulf Hansson
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Ulf Hansson @ 2024-05-27 14:25 UTC (permalink / raw)
  To: Rafael J . Wysocki, Sudeep Holla, linux-pm
  Cc: Lorenzo Pieralisi, Nikunj Kela, Prasad Sodagudi, Maulik Shah,
	Daniel Lezcano, Krzysztof Kozlowski, Ulf Hansson, linux-rt-users,
	linux-arm-kernel, linux-kernel

Using kobject_get_path() means a dynamic memory allocation gets done, which
doesn't work on a PREEMPT_RT based configuration while holding genpd's raw
spinlock.

To fix the problem, let's convert into using the simpler dev_name(). This
means the information about the path doesn't get presented in debugfs, but
hopefully this shouldn't be an issue.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes in v2:
	- New patch.
---
 drivers/pmdomain/core.c | 23 +++--------------------
 1 file changed, 3 insertions(+), 20 deletions(-)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 454fccc38df1..90a65bd09d52 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -3182,7 +3182,6 @@ static int genpd_summary_one(struct seq_file *s,
 		[GENPD_STATE_OFF] = "off"
 	};
 	struct pm_domain_data *pm_data;
-	const char *kobj_path;
 	struct gpd_link *link;
 	char state[16];
 	int ret;
@@ -3215,16 +3214,9 @@ static int genpd_summary_one(struct seq_file *s,
 	}
 
 	list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
-		kobj_path = kobject_get_path(&pm_data->dev->kobj,
-				genpd_is_irq_safe(genpd) ?
-				GFP_ATOMIC : GFP_KERNEL);
-		if (kobj_path == NULL)
-			continue;
-
-		seq_printf(s, "\n    %-50s  ", kobj_path);
+		seq_printf(s, "\n    %-50s  ", dev_name(pm_data->dev));
 		rtpm_status_str(s, pm_data->dev);
 		perf_status_str(s, pm_data->dev);
-		kfree(kobj_path);
 	}
 
 	seq_puts(s, "\n");
@@ -3393,23 +3385,14 @@ static int devices_show(struct seq_file *s, void *data)
 {
 	struct generic_pm_domain *genpd = s->private;
 	struct pm_domain_data *pm_data;
-	const char *kobj_path;
 	int ret = 0;
 
 	ret = genpd_lock_interruptible(genpd);
 	if (ret)
 		return -ERESTARTSYS;
 
-	list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
-		kobj_path = kobject_get_path(&pm_data->dev->kobj,
-				genpd_is_irq_safe(genpd) ?
-				GFP_ATOMIC : GFP_KERNEL);
-		if (kobj_path == NULL)
-			continue;
-
-		seq_printf(s, "%s\n", kobj_path);
-		kfree(kobj_path);
-	}
+	list_for_each_entry(pm_data, &genpd->dev_list, list_node)
+		seq_printf(s, "%s\n", dev_name(pm_data->dev));
 
 	genpd_unlock(genpd);
 	return ret;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 4/7] cpuidle: psci-domain: Enable system-wide suspend on PREEMPT_RT
  2024-05-27 14:25 [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT Ulf Hansson
                   ` (2 preceding siblings ...)
  2024-05-27 14:25 ` [PATCH v2 3/7] pmdomain: core: Use dev_name() instead of kobject_get_path() in debugfs Ulf Hansson
@ 2024-05-27 14:25 ` Ulf Hansson
  2024-05-27 14:25 ` [PATCH v2 5/7] cpuidle: psci: Drop redundant assignment of CPUIDLE_FLAG_RCU_IDLE Ulf Hansson
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 23+ messages in thread
From: Ulf Hansson @ 2024-05-27 14:25 UTC (permalink / raw)
  To: Rafael J . Wysocki, Sudeep Holla, linux-pm
  Cc: Lorenzo Pieralisi, Nikunj Kela, Prasad Sodagudi, Maulik Shah,
	Daniel Lezcano, Krzysztof Kozlowski, Ulf Hansson, linux-rt-users,
	linux-arm-kernel, linux-kernel

The domain-idle-states are currently disabled on a PREEMPT_RT based
configuration for the cpuidle-psci-domain. To enable them to be used for
system-wide suspend and in particular during s2idle, let's set the
GENPD_FLAG_RPM_ALWAYS_ON instead of GENPD_FLAG_ALWAYS_ON for the
corresponding genpd provider.

In this way, the runtime PM path remains disabled in genpd for its attached
devices, while powering-on/off the PM domain during system-wide suspend
becomes allowed.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes in v2:
	- None.
---
 drivers/cpuidle/cpuidle-psci-domain.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c
index fae958794339..ea28b73ef3fb 100644
--- a/drivers/cpuidle/cpuidle-psci-domain.c
+++ b/drivers/cpuidle/cpuidle-psci-domain.c
@@ -67,12 +67,16 @@ static int psci_pd_init(struct device_node *np, bool use_osi)
 
 	/*
 	 * Allow power off when OSI has been successfully enabled.
-	 * PREEMPT_RT is not yet ready to enter domain idle states.
+	 * On a PREEMPT_RT based configuration the domain idle states are
+	 * supported, but only during system-wide suspend.
 	 */
-	if (use_osi && !IS_ENABLED(CONFIG_PREEMPT_RT))
+	if (use_osi) {
 		pd->power_off = psci_pd_power_off;
-	else
+		if (IS_ENABLED(CONFIG_PREEMPT_RT))
+			pd->flags |= GENPD_FLAG_RPM_ALWAYS_ON;
+	} else {
 		pd->flags |= GENPD_FLAG_ALWAYS_ON;
+	}
 
 	/* Use governor for CPU PM domains if it has some states to manage. */
 	pd_gov = pd->states ? &pm_domain_cpu_gov : NULL;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 5/7] cpuidle: psci: Drop redundant assignment of CPUIDLE_FLAG_RCU_IDLE
  2024-05-27 14:25 [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT Ulf Hansson
                   ` (3 preceding siblings ...)
  2024-05-27 14:25 ` [PATCH v2 4/7] cpuidle: psci-domain: Enable system-wide suspend on PREEMPT_RT Ulf Hansson
@ 2024-05-27 14:25 ` Ulf Hansson
  2024-05-27 14:25 ` [PATCH v2 6/7] cpuidle: psci: Enable the hierarchical topology for s2ram on PREEMPT_RT Ulf Hansson
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 23+ messages in thread
From: Ulf Hansson @ 2024-05-27 14:25 UTC (permalink / raw)
  To: Rafael J . Wysocki, Sudeep Holla, linux-pm
  Cc: Lorenzo Pieralisi, Nikunj Kela, Prasad Sodagudi, Maulik Shah,
	Daniel Lezcano, Krzysztof Kozlowski, Ulf Hansson, linux-rt-users,
	linux-arm-kernel, linux-kernel

When using the hierarchical topology and PSCI OSI-mode we may end up
overriding the deepest idle-state's ->enter|enter_s2idle() callbacks, but
there is no point to also re-assign the CPUIDLE_FLAG_RCU_IDLE for the
idle-state in question, as that has already been set when parsing the
states from DT. See init_state_node().

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes in v2:
	- None.
---
 drivers/cpuidle/cpuidle-psci.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c
index 782030a27703..d82a8bc1b194 100644
--- a/drivers/cpuidle/cpuidle-psci.c
+++ b/drivers/cpuidle/cpuidle-psci.c
@@ -234,7 +234,6 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv,
 	 * of a shared state for the domain, assumes the domain states are all
 	 * deeper states.
 	 */
-	drv->states[state_count - 1].flags |= CPUIDLE_FLAG_RCU_IDLE;
 	drv->states[state_count - 1].enter = psci_enter_domain_idle_state;
 	drv->states[state_count - 1].enter_s2idle = psci_enter_s2idle_domain_idle_state;
 	psci_cpuidle_use_cpuhp = true;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 6/7] cpuidle: psci: Enable the hierarchical topology for s2ram on PREEMPT_RT
  2024-05-27 14:25 [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT Ulf Hansson
                   ` (4 preceding siblings ...)
  2024-05-27 14:25 ` [PATCH v2 5/7] cpuidle: psci: Drop redundant assignment of CPUIDLE_FLAG_RCU_IDLE Ulf Hansson
@ 2024-05-27 14:25 ` Ulf Hansson
  2024-05-27 14:25 ` [PATCH v2 7/7] cpuidle: psci: Enable the hierarchical topology for s2idle " Ulf Hansson
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 23+ messages in thread
From: Ulf Hansson @ 2024-05-27 14:25 UTC (permalink / raw)
  To: Rafael J . Wysocki, Sudeep Holla, linux-pm
  Cc: Lorenzo Pieralisi, Nikunj Kela, Prasad Sodagudi, Maulik Shah,
	Daniel Lezcano, Krzysztof Kozlowski, Ulf Hansson, linux-rt-users,
	linux-arm-kernel, linux-kernel

The hierarchical PM domain topology are currently disabled on a PREEMPT_RT
based configuration. As a first step to enable it to be used, let's try to
attach the CPU devices to their PM domains on PREEMPT_RT. In this way the
syscore ops becomes available, allowing the PM domain topology to be
managed during s2ram.

For the moment let's leave the support for CPU hotplug outside PREEMPT_RT,
as it's depending on using runtime PM. For s2ram, this isn't a problem as
all CPUs are managed via the syscore ops.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes in v2:
	- None.
---
 drivers/cpuidle/cpuidle-psci.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c
index d82a8bc1b194..ad6ce9fe12b4 100644
--- a/drivers/cpuidle/cpuidle-psci.c
+++ b/drivers/cpuidle/cpuidle-psci.c
@@ -37,6 +37,7 @@ struct psci_cpuidle_data {
 
 static DEFINE_PER_CPU_READ_MOSTLY(struct psci_cpuidle_data, psci_cpuidle_data);
 static DEFINE_PER_CPU(u32, domain_state);
+static bool psci_cpuidle_use_syscore;
 static bool psci_cpuidle_use_cpuhp;
 
 void psci_set_domain_state(u32 state)
@@ -166,6 +167,12 @@ static struct syscore_ops psci_idle_syscore_ops = {
 	.resume = psci_idle_syscore_resume,
 };
 
+static void psci_idle_init_syscore(void)
+{
+	if (psci_cpuidle_use_syscore)
+		register_syscore_ops(&psci_idle_syscore_ops);
+}
+
 static void psci_idle_init_cpuhp(void)
 {
 	int err;
@@ -173,8 +180,6 @@ static void psci_idle_init_cpuhp(void)
 	if (!psci_cpuidle_use_cpuhp)
 		return;
 
-	register_syscore_ops(&psci_idle_syscore_ops);
-
 	err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING,
 					"cpuidle/psci:online",
 					psci_idle_cpuhp_up,
@@ -222,13 +227,16 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv,
 	if (!psci_has_osi_support())
 		return 0;
 
-	if (IS_ENABLED(CONFIG_PREEMPT_RT))
-		return 0;
-
 	data->dev = dt_idle_attach_cpu(cpu, "psci");
 	if (IS_ERR_OR_NULL(data->dev))
 		return PTR_ERR_OR_ZERO(data->dev);
 
+	psci_cpuidle_use_syscore = true;
+
+	/* The hierarchical topology is limited to s2ram on PREEMPT_RT. */
+	if (IS_ENABLED(CONFIG_PREEMPT_RT))
+		return 0;
+
 	/*
 	 * Using the deepest state for the CPU to trigger a potential selection
 	 * of a shared state for the domain, assumes the domain states are all
@@ -312,6 +320,7 @@ static void psci_cpu_deinit_idle(int cpu)
 	struct psci_cpuidle_data *data = per_cpu_ptr(&psci_cpuidle_data, cpu);
 
 	dt_idle_detach_cpu(data->dev);
+	psci_cpuidle_use_syscore = false;
 	psci_cpuidle_use_cpuhp = false;
 }
 
@@ -408,6 +417,7 @@ static int psci_cpuidle_probe(struct platform_device *pdev)
 			goto out_fail;
 	}
 
+	psci_idle_init_syscore();
 	psci_idle_init_cpuhp();
 	return 0;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 7/7] cpuidle: psci: Enable the hierarchical topology for s2idle on PREEMPT_RT
  2024-05-27 14:25 [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT Ulf Hansson
                   ` (5 preceding siblings ...)
  2024-05-27 14:25 ` [PATCH v2 6/7] cpuidle: psci: Enable the hierarchical topology for s2ram on PREEMPT_RT Ulf Hansson
@ 2024-05-27 14:25 ` Ulf Hansson
  2024-07-08 13:53 ` [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram " Sebastian Andrzej Siewior
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 23+ messages in thread
From: Ulf Hansson @ 2024-05-27 14:25 UTC (permalink / raw)
  To: Rafael J . Wysocki, Sudeep Holla, linux-pm
  Cc: Lorenzo Pieralisi, Nikunj Kela, Prasad Sodagudi, Maulik Shah,
	Daniel Lezcano, Krzysztof Kozlowski, Ulf Hansson, linux-rt-users,
	linux-arm-kernel, linux-kernel

To enable the domain-idle-states to be used during s2idle on a PREEMPT_RT
based configuration, let's allow the re-assignment of the ->enter_s2idle()
callback to psci_enter_s2idle_domain_idle_state().

Similar to s2ram, let's leave the support for CPU hotplug outside
PREEMPT_RT, as it's depending on using runtime PM. For s2idle, this means
that an offline CPU's PM domain will remain powered-on. In practise this
may lead to that a shallower idle-state than necessary gets selected, which
shouldn't be an issue (besides wasting power).

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes in v2:
	- None.
---
 drivers/cpuidle/cpuidle-psci.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c
index ad6ce9fe12b4..2562dc001fc1 100644
--- a/drivers/cpuidle/cpuidle-psci.c
+++ b/drivers/cpuidle/cpuidle-psci.c
@@ -233,18 +233,17 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv,
 
 	psci_cpuidle_use_syscore = true;
 
-	/* The hierarchical topology is limited to s2ram on PREEMPT_RT. */
-	if (IS_ENABLED(CONFIG_PREEMPT_RT))
-		return 0;
-
 	/*
 	 * Using the deepest state for the CPU to trigger a potential selection
 	 * of a shared state for the domain, assumes the domain states are all
-	 * deeper states.
+	 * deeper states. On PREEMPT_RT the hierarchical topology is limited to
+	 * s2ram and s2idle.
 	 */
-	drv->states[state_count - 1].enter = psci_enter_domain_idle_state;
 	drv->states[state_count - 1].enter_s2idle = psci_enter_s2idle_domain_idle_state;
-	psci_cpuidle_use_cpuhp = true;
+	if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
+		drv->states[state_count - 1].enter = psci_enter_domain_idle_state;
+		psci_cpuidle_use_cpuhp = true;
+	}
 
 	return 0;
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 1/7] pmdomain: core: Enable s2idle for CPU PM domains on PREEMPT_RT
  2024-05-27 14:25 ` [PATCH v2 1/7] pmdomain: core: Enable s2idle for CPU PM domains " Ulf Hansson
@ 2024-05-28 19:55   ` Nikunj Kela
  2024-05-30  8:15     ` Ulf Hansson
  0 siblings, 1 reply; 23+ messages in thread
From: Nikunj Kela @ 2024-05-28 19:55 UTC (permalink / raw)
  To: Ulf Hansson, Rafael J . Wysocki, Sudeep Holla, linux-pm
  Cc: Lorenzo Pieralisi, Nikunj Kela, Prasad Sodagudi, Maulik Shah,
	Daniel Lezcano, Krzysztof Kozlowski, linux-rt-users,
	linux-arm-kernel, linux-kernel


On 5/27/2024 7:25 AM, Ulf Hansson wrote:
> To allow a genpd provider for a CPU PM domain to enter a domain-idle-state
> during s2idle on a PREEMPT_RT based configuration, we can't use the regular
> spinlock, as they are turned into sleepable locks on PREEMPT_RT.
>
> To address this problem, let's convert into using the raw spinlock, but
> only for genpd providers that have the GENPD_FLAG_CPU_DOMAIN bit set. In
> this way, the lock can still be acquired/released in atomic context, which
> is needed in the idle-path for PREEMPT_RT.
>
> Do note that the genpd power-on/off notifiers may also be fired during
> s2idle, but these are already prepared for PREEMPT_RT as they are based on
> the raw notifiers. However, consumers of them may need to adopt accordingly
> to work properly on PREEMPT_RT.
>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>
> Changes in v2:
> 	- None.
>
> ---
>  drivers/pmdomain/core.c   | 47 ++++++++++++++++++++++++++++++++++++++-
>  include/linux/pm_domain.h |  5 ++++-
>  2 files changed, 50 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
> index 623d15b68707..072e6bdb6ee6 100644
> --- a/drivers/pmdomain/core.c
> +++ b/drivers/pmdomain/core.c
> @@ -117,6 +117,48 @@ static const struct genpd_lock_ops genpd_spin_ops = {
>  	.unlock = genpd_unlock_spin,
>  };
>  
> +static void genpd_lock_raw_spin(struct generic_pm_domain *genpd)
> +	__acquires(&genpd->raw_slock)
> +{
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&genpd->raw_slock, flags);
> +	genpd->raw_lock_flags = flags;
> +}
> +
> +static void genpd_lock_nested_raw_spin(struct generic_pm_domain *genpd,
> +					int depth)
> +	__acquires(&genpd->raw_slock)
> +{
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave_nested(&genpd->raw_slock, flags, depth);
> +	genpd->raw_lock_flags = flags;
> +}
> +
> +static int genpd_lock_interruptible_raw_spin(struct generic_pm_domain *genpd)
> +	__acquires(&genpd->raw_slock)
> +{
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&genpd->raw_slock, flags);
> +	genpd->raw_lock_flags = flags;
> +	return 0;
> +}
> +
> +static void genpd_unlock_raw_spin(struct generic_pm_domain *genpd)
> +	__releases(&genpd->raw_slock)
> +{
> +	raw_spin_unlock_irqrestore(&genpd->raw_slock, genpd->raw_lock_flags);
> +}
> +
> +static const struct genpd_lock_ops genpd_raw_spin_ops = {
> +	.lock = genpd_lock_raw_spin,
> +	.lock_nested = genpd_lock_nested_raw_spin,
> +	.lock_interruptible = genpd_lock_interruptible_raw_spin,
> +	.unlock = genpd_unlock_raw_spin,
> +};
> +
>  #define genpd_lock(p)			p->lock_ops->lock(p)
>  #define genpd_lock_nested(p, d)		p->lock_ops->lock_nested(p, d)
>  #define genpd_lock_interruptible(p)	p->lock_ops->lock_interruptible(p)
> @@ -2079,7 +2121,10 @@ static void genpd_free_data(struct generic_pm_domain *genpd)
>  
>  static void genpd_lock_init(struct generic_pm_domain *genpd)
>  {
> -	if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
> +	if (genpd->flags & GENPD_FLAG_CPU_DOMAIN) {
> +		raw_spin_lock_init(&genpd->raw_slock);
> +		genpd->lock_ops = &genpd_raw_spin_ops;
> +	} else if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {

Hi Ulf, though you are targeting only CPU domains for now, I wonder if
FLAG_IRQ_SAFE will be a better choice?  The description of the flag says
it is safe for atomic context which won't be the case for PREEMPT_RT? 


>  		spin_lock_init(&genpd->slock);
>  		genpd->lock_ops = &genpd_spin_ops;
>  	} else {
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index f24546a3d3db..0d7fc47de3bc 100644
> --- a/include/linux/pm_domain.h
> +++ b/include/linux/pm_domain.h
> @@ -194,8 +194,11 @@ struct generic_pm_domain {
>  			spinlock_t slock;
>  			unsigned long lock_flags;
>  		};
> +		struct {
> +			raw_spinlock_t raw_slock;
> +			unsigned long raw_lock_flags;
> +		};
>  	};
> -
>  };
>  
>  static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 1/7] pmdomain: core: Enable s2idle for CPU PM domains on PREEMPT_RT
  2024-05-28 19:55   ` Nikunj Kela
@ 2024-05-30  8:15     ` Ulf Hansson
  2024-05-30 14:23       ` Nikunj Kela
  0 siblings, 1 reply; 23+ messages in thread
From: Ulf Hansson @ 2024-05-30  8:15 UTC (permalink / raw)
  To: Nikunj Kela
  Cc: Rafael J . Wysocki, Sudeep Holla, linux-pm, Lorenzo Pieralisi,
	Nikunj Kela, Prasad Sodagudi, Maulik Shah, Daniel Lezcano,
	Krzysztof Kozlowski, linux-rt-users, linux-arm-kernel,
	linux-kernel

On Tue, 28 May 2024 at 21:56, Nikunj Kela <quic_nkela@quicinc.com> wrote:
>
>
> On 5/27/2024 7:25 AM, Ulf Hansson wrote:
> > To allow a genpd provider for a CPU PM domain to enter a domain-idle-state
> > during s2idle on a PREEMPT_RT based configuration, we can't use the regular
> > spinlock, as they are turned into sleepable locks on PREEMPT_RT.
> >
> > To address this problem, let's convert into using the raw spinlock, but
> > only for genpd providers that have the GENPD_FLAG_CPU_DOMAIN bit set. In
> > this way, the lock can still be acquired/released in atomic context, which
> > is needed in the idle-path for PREEMPT_RT.
> >
> > Do note that the genpd power-on/off notifiers may also be fired during
> > s2idle, but these are already prepared for PREEMPT_RT as they are based on
> > the raw notifiers. However, consumers of them may need to adopt accordingly
> > to work properly on PREEMPT_RT.
> >
> > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> > ---
> >
> > Changes in v2:
> >       - None.
> >
> > ---
> >  drivers/pmdomain/core.c   | 47 ++++++++++++++++++++++++++++++++++++++-
> >  include/linux/pm_domain.h |  5 ++++-
> >  2 files changed, 50 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
> > index 623d15b68707..072e6bdb6ee6 100644
> > --- a/drivers/pmdomain/core.c
> > +++ b/drivers/pmdomain/core.c
> > @@ -117,6 +117,48 @@ static const struct genpd_lock_ops genpd_spin_ops = {
> >       .unlock = genpd_unlock_spin,
> >  };
> >
> > +static void genpd_lock_raw_spin(struct generic_pm_domain *genpd)
> > +     __acquires(&genpd->raw_slock)
> > +{
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave(&genpd->raw_slock, flags);
> > +     genpd->raw_lock_flags = flags;
> > +}
> > +
> > +static void genpd_lock_nested_raw_spin(struct generic_pm_domain *genpd,
> > +                                     int depth)
> > +     __acquires(&genpd->raw_slock)
> > +{
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave_nested(&genpd->raw_slock, flags, depth);
> > +     genpd->raw_lock_flags = flags;
> > +}
> > +
> > +static int genpd_lock_interruptible_raw_spin(struct generic_pm_domain *genpd)
> > +     __acquires(&genpd->raw_slock)
> > +{
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave(&genpd->raw_slock, flags);
> > +     genpd->raw_lock_flags = flags;
> > +     return 0;
> > +}
> > +
> > +static void genpd_unlock_raw_spin(struct generic_pm_domain *genpd)
> > +     __releases(&genpd->raw_slock)
> > +{
> > +     raw_spin_unlock_irqrestore(&genpd->raw_slock, genpd->raw_lock_flags);
> > +}
> > +
> > +static const struct genpd_lock_ops genpd_raw_spin_ops = {
> > +     .lock = genpd_lock_raw_spin,
> > +     .lock_nested = genpd_lock_nested_raw_spin,
> > +     .lock_interruptible = genpd_lock_interruptible_raw_spin,
> > +     .unlock = genpd_unlock_raw_spin,
> > +};
> > +
> >  #define genpd_lock(p)                        p->lock_ops->lock(p)
> >  #define genpd_lock_nested(p, d)              p->lock_ops->lock_nested(p, d)
> >  #define genpd_lock_interruptible(p)  p->lock_ops->lock_interruptible(p)
> > @@ -2079,7 +2121,10 @@ static void genpd_free_data(struct generic_pm_domain *genpd)
> >
> >  static void genpd_lock_init(struct generic_pm_domain *genpd)
> >  {
> > -     if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
> > +     if (genpd->flags & GENPD_FLAG_CPU_DOMAIN) {
> > +             raw_spin_lock_init(&genpd->raw_slock);
> > +             genpd->lock_ops = &genpd_raw_spin_ops;
> > +     } else if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
>
> Hi Ulf, though you are targeting only CPU domains for now, I wonder if
> FLAG_IRQ_SAFE will be a better choice?  The description of the flag says
> it is safe for atomic context which won't be the case for PREEMPT_RT?

You have a point!

However, we also need to limit the use of raw spinlocks, from
PREEMPT_RT point of view. In other words, just because a genpd
provider is capable of executing its callbacks in atomic context,
doesn't always mean that it should use raw spinlocks too.

[...]

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 1/7] pmdomain: core: Enable s2idle for CPU PM domains on PREEMPT_RT
  2024-05-30  8:15     ` Ulf Hansson
@ 2024-05-30 14:23       ` Nikunj Kela
  2024-06-03 13:58         ` Ulf Hansson
  0 siblings, 1 reply; 23+ messages in thread
From: Nikunj Kela @ 2024-05-30 14:23 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J . Wysocki, Sudeep Holla, linux-pm, Lorenzo Pieralisi,
	Nikunj Kela, Prasad Sodagudi, Maulik Shah, Daniel Lezcano,
	Krzysztof Kozlowski, linux-rt-users, linux-arm-kernel,
	linux-kernel


On 5/30/2024 1:15 AM, Ulf Hansson wrote:
> On Tue, 28 May 2024 at 21:56, Nikunj Kela <quic_nkela@quicinc.com> wrote:
>>
>> On 5/27/2024 7:25 AM, Ulf Hansson wrote:
>>> To allow a genpd provider for a CPU PM domain to enter a domain-idle-state
>>> during s2idle on a PREEMPT_RT based configuration, we can't use the regular
>>> spinlock, as they are turned into sleepable locks on PREEMPT_RT.
>>>
>>> To address this problem, let's convert into using the raw spinlock, but
>>> only for genpd providers that have the GENPD_FLAG_CPU_DOMAIN bit set. In
>>> this way, the lock can still be acquired/released in atomic context, which
>>> is needed in the idle-path for PREEMPT_RT.
>>>
>>> Do note that the genpd power-on/off notifiers may also be fired during
>>> s2idle, but these are already prepared for PREEMPT_RT as they are based on
>>> the raw notifiers. However, consumers of them may need to adopt accordingly
>>> to work properly on PREEMPT_RT.
>>>
>>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>>> ---
>>>
>>> Changes in v2:
>>>       - None.
>>>
>>> ---
>>>  drivers/pmdomain/core.c   | 47 ++++++++++++++++++++++++++++++++++++++-
>>>  include/linux/pm_domain.h |  5 ++++-
>>>  2 files changed, 50 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
>>> index 623d15b68707..072e6bdb6ee6 100644
>>> --- a/drivers/pmdomain/core.c
>>> +++ b/drivers/pmdomain/core.c
>>> @@ -117,6 +117,48 @@ static const struct genpd_lock_ops genpd_spin_ops = {
>>>       .unlock = genpd_unlock_spin,
>>>  };
>>>
>>> +static void genpd_lock_raw_spin(struct generic_pm_domain *genpd)
>>> +     __acquires(&genpd->raw_slock)
>>> +{
>>> +     unsigned long flags;
>>> +
>>> +     raw_spin_lock_irqsave(&genpd->raw_slock, flags);
>>> +     genpd->raw_lock_flags = flags;
>>> +}
>>> +
>>> +static void genpd_lock_nested_raw_spin(struct generic_pm_domain *genpd,
>>> +                                     int depth)
>>> +     __acquires(&genpd->raw_slock)
>>> +{
>>> +     unsigned long flags;
>>> +
>>> +     raw_spin_lock_irqsave_nested(&genpd->raw_slock, flags, depth);
>>> +     genpd->raw_lock_flags = flags;
>>> +}
>>> +
>>> +static int genpd_lock_interruptible_raw_spin(struct generic_pm_domain *genpd)
>>> +     __acquires(&genpd->raw_slock)
>>> +{
>>> +     unsigned long flags;
>>> +
>>> +     raw_spin_lock_irqsave(&genpd->raw_slock, flags);
>>> +     genpd->raw_lock_flags = flags;
>>> +     return 0;
>>> +}
>>> +
>>> +static void genpd_unlock_raw_spin(struct generic_pm_domain *genpd)
>>> +     __releases(&genpd->raw_slock)
>>> +{
>>> +     raw_spin_unlock_irqrestore(&genpd->raw_slock, genpd->raw_lock_flags);
>>> +}
>>> +
>>> +static const struct genpd_lock_ops genpd_raw_spin_ops = {
>>> +     .lock = genpd_lock_raw_spin,
>>> +     .lock_nested = genpd_lock_nested_raw_spin,
>>> +     .lock_interruptible = genpd_lock_interruptible_raw_spin,
>>> +     .unlock = genpd_unlock_raw_spin,
>>> +};
>>> +
>>>  #define genpd_lock(p)                        p->lock_ops->lock(p)
>>>  #define genpd_lock_nested(p, d)              p->lock_ops->lock_nested(p, d)
>>>  #define genpd_lock_interruptible(p)  p->lock_ops->lock_interruptible(p)
>>> @@ -2079,7 +2121,10 @@ static void genpd_free_data(struct generic_pm_domain *genpd)
>>>
>>>  static void genpd_lock_init(struct generic_pm_domain *genpd)
>>>  {
>>> -     if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
>>> +     if (genpd->flags & GENPD_FLAG_CPU_DOMAIN) {
>>> +             raw_spin_lock_init(&genpd->raw_slock);
>>> +             genpd->lock_ops = &genpd_raw_spin_ops;
>>> +     } else if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
>> Hi Ulf, though you are targeting only CPU domains for now, I wonder if
>> FLAG_IRQ_SAFE will be a better choice?  The description of the flag says
>> it is safe for atomic context which won't be the case for PREEMPT_RT?
> You have a point!
>
> However, we also need to limit the use of raw spinlocks, from
> PREEMPT_RT point of view. In other words, just because a genpd
> provider is capable of executing its callbacks in atomic context,
> doesn't always mean that it should use raw spinlocks too.

Got it! Thanks. Maybe in future, if there is a need, a new GENPD FLAG
for RT, something like GENPD_FLAG_IRQ_SAFE_RT, can be added to address this.


>
> [...]
>
> Kind regards
> Uffe

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 1/7] pmdomain: core: Enable s2idle for CPU PM domains on PREEMPT_RT
  2024-05-30 14:23       ` Nikunj Kela
@ 2024-06-03 13:58         ` Ulf Hansson
  2024-06-04 17:22           ` Nikunj Kela
  0 siblings, 1 reply; 23+ messages in thread
From: Ulf Hansson @ 2024-06-03 13:58 UTC (permalink / raw)
  To: Nikunj Kela
  Cc: Rafael J . Wysocki, Sudeep Holla, linux-pm, Lorenzo Pieralisi,
	Nikunj Kela, Prasad Sodagudi, Maulik Shah, Daniel Lezcano,
	Krzysztof Kozlowski, linux-rt-users, linux-arm-kernel,
	linux-kernel

On Thu, 30 May 2024 at 16:23, Nikunj Kela <quic_nkela@quicinc.com> wrote:
>
>
> On 5/30/2024 1:15 AM, Ulf Hansson wrote:
> > On Tue, 28 May 2024 at 21:56, Nikunj Kela <quic_nkela@quicinc.com> wrote:
> >>
> >> On 5/27/2024 7:25 AM, Ulf Hansson wrote:
> >>> To allow a genpd provider for a CPU PM domain to enter a domain-idle-state
> >>> during s2idle on a PREEMPT_RT based configuration, we can't use the regular
> >>> spinlock, as they are turned into sleepable locks on PREEMPT_RT.
> >>>
> >>> To address this problem, let's convert into using the raw spinlock, but
> >>> only for genpd providers that have the GENPD_FLAG_CPU_DOMAIN bit set. In
> >>> this way, the lock can still be acquired/released in atomic context, which
> >>> is needed in the idle-path for PREEMPT_RT.
> >>>
> >>> Do note that the genpd power-on/off notifiers may also be fired during
> >>> s2idle, but these are already prepared for PREEMPT_RT as they are based on
> >>> the raw notifiers. However, consumers of them may need to adopt accordingly
> >>> to work properly on PREEMPT_RT.
> >>>
> >>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> >>> ---
> >>>
> >>> Changes in v2:
> >>>       - None.
> >>>
> >>> ---
> >>>  drivers/pmdomain/core.c   | 47 ++++++++++++++++++++++++++++++++++++++-
> >>>  include/linux/pm_domain.h |  5 ++++-
> >>>  2 files changed, 50 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
> >>> index 623d15b68707..072e6bdb6ee6 100644
> >>> --- a/drivers/pmdomain/core.c
> >>> +++ b/drivers/pmdomain/core.c
> >>> @@ -117,6 +117,48 @@ static const struct genpd_lock_ops genpd_spin_ops = {
> >>>       .unlock = genpd_unlock_spin,
> >>>  };
> >>>
> >>> +static void genpd_lock_raw_spin(struct generic_pm_domain *genpd)
> >>> +     __acquires(&genpd->raw_slock)
> >>> +{
> >>> +     unsigned long flags;
> >>> +
> >>> +     raw_spin_lock_irqsave(&genpd->raw_slock, flags);
> >>> +     genpd->raw_lock_flags = flags;
> >>> +}
> >>> +
> >>> +static void genpd_lock_nested_raw_spin(struct generic_pm_domain *genpd,
> >>> +                                     int depth)
> >>> +     __acquires(&genpd->raw_slock)
> >>> +{
> >>> +     unsigned long flags;
> >>> +
> >>> +     raw_spin_lock_irqsave_nested(&genpd->raw_slock, flags, depth);
> >>> +     genpd->raw_lock_flags = flags;
> >>> +}
> >>> +
> >>> +static int genpd_lock_interruptible_raw_spin(struct generic_pm_domain *genpd)
> >>> +     __acquires(&genpd->raw_slock)
> >>> +{
> >>> +     unsigned long flags;
> >>> +
> >>> +     raw_spin_lock_irqsave(&genpd->raw_slock, flags);
> >>> +     genpd->raw_lock_flags = flags;
> >>> +     return 0;
> >>> +}
> >>> +
> >>> +static void genpd_unlock_raw_spin(struct generic_pm_domain *genpd)
> >>> +     __releases(&genpd->raw_slock)
> >>> +{
> >>> +     raw_spin_unlock_irqrestore(&genpd->raw_slock, genpd->raw_lock_flags);
> >>> +}
> >>> +
> >>> +static const struct genpd_lock_ops genpd_raw_spin_ops = {
> >>> +     .lock = genpd_lock_raw_spin,
> >>> +     .lock_nested = genpd_lock_nested_raw_spin,
> >>> +     .lock_interruptible = genpd_lock_interruptible_raw_spin,
> >>> +     .unlock = genpd_unlock_raw_spin,
> >>> +};
> >>> +
> >>>  #define genpd_lock(p)                        p->lock_ops->lock(p)
> >>>  #define genpd_lock_nested(p, d)              p->lock_ops->lock_nested(p, d)
> >>>  #define genpd_lock_interruptible(p)  p->lock_ops->lock_interruptible(p)
> >>> @@ -2079,7 +2121,10 @@ static void genpd_free_data(struct generic_pm_domain *genpd)
> >>>
> >>>  static void genpd_lock_init(struct generic_pm_domain *genpd)
> >>>  {
> >>> -     if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
> >>> +     if (genpd->flags & GENPD_FLAG_CPU_DOMAIN) {
> >>> +             raw_spin_lock_init(&genpd->raw_slock);
> >>> +             genpd->lock_ops = &genpd_raw_spin_ops;
> >>> +     } else if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
> >> Hi Ulf, though you are targeting only CPU domains for now, I wonder if
> >> FLAG_IRQ_SAFE will be a better choice?  The description of the flag says
> >> it is safe for atomic context which won't be the case for PREEMPT_RT?
> > You have a point!
> >
> > However, we also need to limit the use of raw spinlocks, from
> > PREEMPT_RT point of view. In other words, just because a genpd
> > provider is capable of executing its callbacks in atomic context,
> > doesn't always mean that it should use raw spinlocks too.
>
> Got it! Thanks. Maybe in future, if there is a need, a new GENPD FLAG
> for RT, something like GENPD_FLAG_IRQ_SAFE_RT, can be added to address this.

Yes, I agree, something along those lines would make sense.

BTW, did you manage to get some time to test the series on your end?

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 1/7] pmdomain: core: Enable s2idle for CPU PM domains on PREEMPT_RT
  2024-06-03 13:58         ` Ulf Hansson
@ 2024-06-04 17:22           ` Nikunj Kela
  0 siblings, 0 replies; 23+ messages in thread
From: Nikunj Kela @ 2024-06-04 17:22 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J . Wysocki, Sudeep Holla, linux-pm, Lorenzo Pieralisi,
	Nikunj Kela, Prasad Sodagudi, Maulik Shah, Daniel Lezcano,
	Krzysztof Kozlowski, linux-rt-users, linux-arm-kernel,
	linux-kernel


On 6/3/2024 6:58 AM, Ulf Hansson wrote:
> On Thu, 30 May 2024 at 16:23, Nikunj Kela <quic_nkela@quicinc.com> wrote:
>>
>> On 5/30/2024 1:15 AM, Ulf Hansson wrote:
>>> On Tue, 28 May 2024 at 21:56, Nikunj Kela <quic_nkela@quicinc.com> wrote:
>>>> On 5/27/2024 7:25 AM, Ulf Hansson wrote:
>>>>> To allow a genpd provider for a CPU PM domain to enter a domain-idle-state
>>>>> during s2idle on a PREEMPT_RT based configuration, we can't use the regular
>>>>> spinlock, as they are turned into sleepable locks on PREEMPT_RT.
>>>>>
>>>>> To address this problem, let's convert into using the raw spinlock, but
>>>>> only for genpd providers that have the GENPD_FLAG_CPU_DOMAIN bit set. In
>>>>> this way, the lock can still be acquired/released in atomic context, which
>>>>> is needed in the idle-path for PREEMPT_RT.
>>>>>
>>>>> Do note that the genpd power-on/off notifiers may also be fired during
>>>>> s2idle, but these are already prepared for PREEMPT_RT as they are based on
>>>>> the raw notifiers. However, consumers of them may need to adopt accordingly
>>>>> to work properly on PREEMPT_RT.
>>>>>
>>>>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>>>>> ---
>>>>>
>>>>> Changes in v2:
>>>>>       - None.
>>>>>
>>>>> ---
>>>>>  drivers/pmdomain/core.c   | 47 ++++++++++++++++++++++++++++++++++++++-
>>>>>  include/linux/pm_domain.h |  5 ++++-
>>>>>  2 files changed, 50 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
>>>>> index 623d15b68707..072e6bdb6ee6 100644
>>>>> --- a/drivers/pmdomain/core.c
>>>>> +++ b/drivers/pmdomain/core.c
>>>>> @@ -117,6 +117,48 @@ static const struct genpd_lock_ops genpd_spin_ops = {
>>>>>       .unlock = genpd_unlock_spin,
>>>>>  };
>>>>>
>>>>> +static void genpd_lock_raw_spin(struct generic_pm_domain *genpd)
>>>>> +     __acquires(&genpd->raw_slock)
>>>>> +{
>>>>> +     unsigned long flags;
>>>>> +
>>>>> +     raw_spin_lock_irqsave(&genpd->raw_slock, flags);
>>>>> +     genpd->raw_lock_flags = flags;
>>>>> +}
>>>>> +
>>>>> +static void genpd_lock_nested_raw_spin(struct generic_pm_domain *genpd,
>>>>> +                                     int depth)
>>>>> +     __acquires(&genpd->raw_slock)
>>>>> +{
>>>>> +     unsigned long flags;
>>>>> +
>>>>> +     raw_spin_lock_irqsave_nested(&genpd->raw_slock, flags, depth);
>>>>> +     genpd->raw_lock_flags = flags;
>>>>> +}
>>>>> +
>>>>> +static int genpd_lock_interruptible_raw_spin(struct generic_pm_domain *genpd)
>>>>> +     __acquires(&genpd->raw_slock)
>>>>> +{
>>>>> +     unsigned long flags;
>>>>> +
>>>>> +     raw_spin_lock_irqsave(&genpd->raw_slock, flags);
>>>>> +     genpd->raw_lock_flags = flags;
>>>>> +     return 0;
>>>>> +}
>>>>> +
>>>>> +static void genpd_unlock_raw_spin(struct generic_pm_domain *genpd)
>>>>> +     __releases(&genpd->raw_slock)
>>>>> +{
>>>>> +     raw_spin_unlock_irqrestore(&genpd->raw_slock, genpd->raw_lock_flags);
>>>>> +}
>>>>> +
>>>>> +static const struct genpd_lock_ops genpd_raw_spin_ops = {
>>>>> +     .lock = genpd_lock_raw_spin,
>>>>> +     .lock_nested = genpd_lock_nested_raw_spin,
>>>>> +     .lock_interruptible = genpd_lock_interruptible_raw_spin,
>>>>> +     .unlock = genpd_unlock_raw_spin,
>>>>> +};
>>>>> +
>>>>>  #define genpd_lock(p)                        p->lock_ops->lock(p)
>>>>>  #define genpd_lock_nested(p, d)              p->lock_ops->lock_nested(p, d)
>>>>>  #define genpd_lock_interruptible(p)  p->lock_ops->lock_interruptible(p)
>>>>> @@ -2079,7 +2121,10 @@ static void genpd_free_data(struct generic_pm_domain *genpd)
>>>>>
>>>>>  static void genpd_lock_init(struct generic_pm_domain *genpd)
>>>>>  {
>>>>> -     if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
>>>>> +     if (genpd->flags & GENPD_FLAG_CPU_DOMAIN) {
>>>>> +             raw_spin_lock_init(&genpd->raw_slock);
>>>>> +             genpd->lock_ops = &genpd_raw_spin_ops;
>>>>> +     } else if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
>>>> Hi Ulf, though you are targeting only CPU domains for now, I wonder if
>>>> FLAG_IRQ_SAFE will be a better choice?  The description of the flag says
>>>> it is safe for atomic context which won't be the case for PREEMPT_RT?
>>> You have a point!
>>>
>>> However, we also need to limit the use of raw spinlocks, from
>>> PREEMPT_RT point of view. In other words, just because a genpd
>>> provider is capable of executing its callbacks in atomic context,
>>> doesn't always mean that it should use raw spinlocks too.
>> Got it! Thanks. Maybe in future, if there is a need, a new GENPD FLAG
>> for RT, something like GENPD_FLAG_IRQ_SAFE_RT, can be added to address this.
> Yes, I agree, something along those lines would make sense.
>
> BTW, did you manage to get some time to test the series on your end?

I haven't been able spend time testing it but I have requested Maulik to
test it and update you. Thanks


> Kind regards
> Uffe

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT
  2024-05-27 14:25 [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT Ulf Hansson
                   ` (6 preceding siblings ...)
  2024-05-27 14:25 ` [PATCH v2 7/7] cpuidle: psci: Enable the hierarchical topology for s2idle " Ulf Hansson
@ 2024-07-08 13:53 ` Sebastian Andrzej Siewior
  2024-07-09 15:31   ` Ulf Hansson
  2024-07-25 10:32 ` Raghavendra Kakarla
  2024-08-05 11:35 ` Ulf Hansson
  9 siblings, 1 reply; 23+ messages in thread
From: Sebastian Andrzej Siewior @ 2024-07-08 13:53 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J . Wysocki, Sudeep Holla, linux-pm, Lorenzo Pieralisi,
	Nikunj Kela, Prasad Sodagudi, Maulik Shah, Daniel Lezcano,
	Krzysztof Kozlowski, linux-rt-users, linux-arm-kernel,
	linux-kernel

On 2024-05-27 16:25:50 [+0200], Ulf Hansson wrote:
> Updates in v2:
> 	- Rebased and fixed a small issue in genpd, see patch3.
> 	- Re-tested on v6.9-rt5 (PREEMPT_RT enabled)
> 	- Re-tested on v6.10-rc1 (for regressions, PREEMPT_RT disabled)
> 
> The hierarchical PM domain topology and the corresponding domain-idle-states
> are currently disabled on a PREEMPT_RT based configuration. The main reason is
> because spinlocks are turned into sleepable locks on PREEMPT_RT, which means
> genpd and runtime PM can't be use in the atomic idle-path when
> selecting/entering an idle-state.
> 
> For s2idle/s2ram this is an unnecessary limitation that this series intends to
> address. Note that, the support for cpuhotplug is left to future improvements.
> More information about this are available in the commit messages.

I looked at it and it seems limited to pmdomain/core.c, also I don't
know if there is a ->set_performance_state callback set since the one I
checked have mutex_t locking ;)
So if this is needed, then be it. s2ram wouldn't be used in "production"
but in "safe state" so I wouldn't worry too much about latency spikes.
Not sure what it means for the other modes.
I am not to worried for now, please don't let spread more than needed ;)

> Kind regards
> Ulf Hansson

Sebastian

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT
  2024-07-08 13:53 ` [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram " Sebastian Andrzej Siewior
@ 2024-07-09 15:31   ` Ulf Hansson
  2024-07-31  8:15     ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 23+ messages in thread
From: Ulf Hansson @ 2024-07-09 15:31 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: Rafael J . Wysocki, Sudeep Holla, linux-pm, Lorenzo Pieralisi,
	Nikunj Kela, Prasad Sodagudi, Maulik Shah, Daniel Lezcano,
	Krzysztof Kozlowski, linux-rt-users, linux-arm-kernel,
	linux-kernel

On Mon, 8 Jul 2024 at 15:53, Sebastian Andrzej Siewior
<bigeasy@linutronix.de> wrote:
>
> On 2024-05-27 16:25:50 [+0200], Ulf Hansson wrote:
> > Updates in v2:
> >       - Rebased and fixed a small issue in genpd, see patch3.
> >       - Re-tested on v6.9-rt5 (PREEMPT_RT enabled)
> >       - Re-tested on v6.10-rc1 (for regressions, PREEMPT_RT disabled)
> >
> > The hierarchical PM domain topology and the corresponding domain-idle-states
> > are currently disabled on a PREEMPT_RT based configuration. The main reason is
> > because spinlocks are turned into sleepable locks on PREEMPT_RT, which means
> > genpd and runtime PM can't be use in the atomic idle-path when
> > selecting/entering an idle-state.
> >
> > For s2idle/s2ram this is an unnecessary limitation that this series intends to
> > address. Note that, the support for cpuhotplug is left to future improvements.
> > More information about this are available in the commit messages.
>
> I looked at it and it seems limited to pmdomain/core.c, also I don't
> know if there is a ->set_performance_state callback set since the one I
> checked have mutex_t locking ;)
> So if this is needed, then be it. s2ram wouldn't be used in "production"
> but in "safe state" so I wouldn't worry too much about latency spikes.
> Not sure what it means for the other modes.
> I am not to worried for now, please don't let spread more than needed ;)

Thanks for taking a look and for providing your thoughts. Can I
consider that as an "ack" for the whole series?

Before I decide to apply this I am awaiting some additional
confirmation from Qcom guys. It's getting late for v6.11, so I may
need to make another re-spin, but let's see.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT
  2024-05-27 14:25 [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT Ulf Hansson
                   ` (7 preceding siblings ...)
  2024-07-08 13:53 ` [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram " Sebastian Andrzej Siewior
@ 2024-07-25 10:32 ` Raghavendra Kakarla
  2024-08-05 11:35 ` Ulf Hansson
  9 siblings, 0 replies; 23+ messages in thread
From: Raghavendra Kakarla @ 2024-07-25 10:32 UTC (permalink / raw)
  To: Ulf Hansson, Rafael J . Wysocki, Sudeep Holla, linux-pm
  Cc: Lorenzo Pieralisi, Nikunj Kela, Prasad Sodagudi, Maulik Shah,
	Daniel Lezcano, Krzysztof Kozlowski, linux-rt-users,
	linux-arm-kernel, linux-kernel



On 5/27/2024 7:55 PM, Ulf Hansson wrote:
> Updates in v2:
> 	- Rebased and fixed a small issue in genpd, see patch3.
> 	- Re-tested on v6.9-rt5 (PREEMPT_RT enabled)
> 	- Re-tested on v6.10-rc1 (for regressions, PREEMPT_RT disabled)
> 
> The hierarchical PM domain topology and the corresponding domain-idle-states
> are currently disabled on a PREEMPT_RT based configuration. The main reason is
> because spinlocks are turned into sleepable locks on PREEMPT_RT, which means
> genpd and runtime PM can't be use in the atomic idle-path when
> selecting/entering an idle-state.
> 
> For s2idle/s2ram this is an unnecessary limitation that this series intends to
> address. Note that, the support for cpuhotplug is left to future improvements.
> More information about this are available in the commit messages.
> 
> I have tested this on a Dragonboard 410c.
This series is tested on qcm6490 with PREEMPT_RT enabled. For the series,

Tested-by: Raghavendra Kakarla <quic_rkakarla@quicinc.com>  # qcm6490 
with PREEMPT_RT enabled

Tested APSS suspend and then SoC power collapse through s2idle and s2ram 
paths.
APSS and soc power collapse stats are incremented.
/sys/kernel/debug/pm_genpd/power-domain-cluster/idle_states
/sys/kernel/debug/qcom_stats/cxsd

Without this series, they are not incremented.

Thanks,
Raghavendra K.
> 
> Kind regards
> Ulf Hansson
> 
> 
> Ulf Hansson (7):
>    pmdomain: core: Enable s2idle for CPU PM domains on PREEMPT_RT
>    pmdomain: core: Don't hold the genpd-lock when calling
>      dev_pm_domain_set()
>    pmdomain: core: Use dev_name() instead of kobject_get_path() in
>      debugfs
>    cpuidle: psci-domain: Enable system-wide suspend on PREEMPT_RT
>    cpuidle: psci: Drop redundant assignment of CPUIDLE_FLAG_RCU_IDLE
>    cpuidle: psci: Enable the hierarchical topology for s2ram on
>      PREEMPT_RT
>    cpuidle: psci: Enable the hierarchical topology for s2idle on
>      PREEMPT_RT
> 
>   drivers/cpuidle/cpuidle-psci-domain.c | 10 ++--
>   drivers/cpuidle/cpuidle-psci.c        | 26 ++++++----
>   drivers/pmdomain/core.c               | 75 +++++++++++++++++++--------
>   include/linux/pm_domain.h             |  5 +-
>   4 files changed, 80 insertions(+), 36 deletions(-)
> 

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT
  2024-07-09 15:31   ` Ulf Hansson
@ 2024-07-31  8:15     ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 23+ messages in thread
From: Sebastian Andrzej Siewior @ 2024-07-31  8:15 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J . Wysocki, Sudeep Holla, linux-pm, Lorenzo Pieralisi,
	Nikunj Kela, Prasad Sodagudi, Maulik Shah, Daniel Lezcano,
	Krzysztof Kozlowski, linux-rt-users, linux-arm-kernel,
	linux-kernel

On 2024-07-09 17:31:12 [+0200], Ulf Hansson wrote:
> 
> Thanks for taking a look and for providing your thoughts. Can I
> consider that as an "ack" for the whole series?

Yes.

Sebastian

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT
  2024-05-27 14:25 [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT Ulf Hansson
                   ` (8 preceding siblings ...)
  2024-07-25 10:32 ` Raghavendra Kakarla
@ 2024-08-05 11:35 ` Ulf Hansson
  9 siblings, 0 replies; 23+ messages in thread
From: Ulf Hansson @ 2024-08-05 11:35 UTC (permalink / raw)
  To: Rafael J . Wysocki, Sudeep Holla, linux-pm, quic_rkakarla,
	Sebastian Andrzej Siewior
  Cc: Lorenzo Pieralisi, Nikunj Kela, Prasad Sodagudi, Maulik Shah,
	Daniel Lezcano, Krzysztof Kozlowski, linux-rt-users,
	linux-arm-kernel, linux-kernel

+ Raghavendra Kakarla, Sebastian Andrzej Siewior

On Mon, 27 May 2024 at 16:26, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>
> Updates in v2:
>         - Rebased and fixed a small issue in genpd, see patch3.
>         - Re-tested on v6.9-rt5 (PREEMPT_RT enabled)
>         - Re-tested on v6.10-rc1 (for regressions, PREEMPT_RT disabled)
>
> The hierarchical PM domain topology and the corresponding domain-idle-states
> are currently disabled on a PREEMPT_RT based configuration. The main reason is
> because spinlocks are turned into sleepable locks on PREEMPT_RT, which means
> genpd and runtime PM can't be use in the atomic idle-path when
> selecting/entering an idle-state.
>
> For s2idle/s2ram this is an unnecessary limitation that this series intends to
> address. Note that, the support for cpuhotplug is left to future improvements.
> More information about this are available in the commit messages.
>
> I have tested this on a Dragonboard 410c.
>
> Kind regards
> Ulf Hansson
>
>
> Ulf Hansson (7):
>   pmdomain: core: Enable s2idle for CPU PM domains on PREEMPT_RT
>   pmdomain: core: Don't hold the genpd-lock when calling
>     dev_pm_domain_set()
>   pmdomain: core: Use dev_name() instead of kobject_get_path() in
>     debugfs
>   cpuidle: psci-domain: Enable system-wide suspend on PREEMPT_RT
>   cpuidle: psci: Drop redundant assignment of CPUIDLE_FLAG_RCU_IDLE
>   cpuidle: psci: Enable the hierarchical topology for s2ram on
>     PREEMPT_RT
>   cpuidle: psci: Enable the hierarchical topology for s2idle on
>     PREEMPT_RT
>
>  drivers/cpuidle/cpuidle-psci-domain.c | 10 ++--
>  drivers/cpuidle/cpuidle-psci.c        | 26 ++++++----
>  drivers/pmdomain/core.c               | 75 +++++++++++++++++++--------
>  include/linux/pm_domain.h             |  5 +-
>  4 files changed, 80 insertions(+), 36 deletions(-)
>

Just wanted to let you all know that I have queued up this series via
my pmdomain tree. Please let me know if you have any further
comments/suggestions.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 3/7] pmdomain: core: Use dev_name() instead of kobject_get_path() in debugfs
  2024-05-27 14:25 ` [PATCH v2 3/7] pmdomain: core: Use dev_name() instead of kobject_get_path() in debugfs Ulf Hansson
@ 2024-08-20  8:55   ` Geert Uytterhoeven
  2024-08-20  8:57     ` Ulf Hansson
  0 siblings, 1 reply; 23+ messages in thread
From: Geert Uytterhoeven @ 2024-08-20  8:55 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J . Wysocki, Sudeep Holla, linux-pm, Lorenzo Pieralisi,
	Nikunj Kela, Prasad Sodagudi, Maulik Shah, Daniel Lezcano,
	Krzysztof Kozlowski, linux-rt-users, linux-arm-kernel,
	linux-kernel

Hi Ulf,

On Mon, May 27, 2024 at 4:27 PM Ulf Hansson <ulf.hansson@linaro.org> wrote:
> Using kobject_get_path() means a dynamic memory allocation gets done, which
> doesn't work on a PREEMPT_RT based configuration while holding genpd's raw
> spinlock.
>
> To fix the problem, let's convert into using the simpler dev_name(). This
> means the information about the path doesn't get presented in debugfs, but
> hopefully this shouldn't be an issue.
>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
> Changes in v2:
>         - New patch.

Thanks for your patch, which is now commit 9094e53ff5c86ebe ("pmdomain:
core: Use dev_name() instead of kobject_get_path() in debugfs")
in pmdomain/next.

> --- a/drivers/pmdomain/core.c
> +++ b/drivers/pmdomain/core.c
> @@ -3215,16 +3214,9 @@ static int genpd_summary_one(struct seq_file *s,
>         }
>
>         list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
> -               kobj_path = kobject_get_path(&pm_data->dev->kobj,
> -                               genpd_is_irq_safe(genpd) ?
> -                               GFP_ATOMIC : GFP_KERNEL);
> -               if (kobj_path == NULL)
> -                       continue;
> -
> -               seq_printf(s, "\n    %-50s  ", kobj_path);
> +               seq_printf(s, "\n    %-50s  ", dev_name(pm_data->dev));

While some of the old names didn't even fit in 50 characters, the new
names need much less space, so perhaps this is a good opportunity to
decrease the table width?

>                 rtpm_status_str(s, pm_data->dev);
>                 perf_status_str(s, pm_data->dev);
> -               kfree(kobj_path);
>         }
>
>         seq_puts(s, "\n");

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 3/7] pmdomain: core: Use dev_name() instead of kobject_get_path() in debugfs
  2024-08-20  8:55   ` Geert Uytterhoeven
@ 2024-08-20  8:57     ` Ulf Hansson
  2024-08-30 15:50       ` Geert Uytterhoeven
  0 siblings, 1 reply; 23+ messages in thread
From: Ulf Hansson @ 2024-08-20  8:57 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Rafael J . Wysocki, Sudeep Holla, linux-pm, Lorenzo Pieralisi,
	Nikunj Kela, Prasad Sodagudi, Maulik Shah, Daniel Lezcano,
	Krzysztof Kozlowski, linux-rt-users, linux-arm-kernel,
	linux-kernel

On Tue, 20 Aug 2024 at 10:55, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> Hi Ulf,
>
> On Mon, May 27, 2024 at 4:27 PM Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > Using kobject_get_path() means a dynamic memory allocation gets done, which
> > doesn't work on a PREEMPT_RT based configuration while holding genpd's raw
> > spinlock.
> >
> > To fix the problem, let's convert into using the simpler dev_name(). This
> > means the information about the path doesn't get presented in debugfs, but
> > hopefully this shouldn't be an issue.
> >
> > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> > ---
> > Changes in v2:
> >         - New patch.
>
> Thanks for your patch, which is now commit 9094e53ff5c86ebe ("pmdomain:
> core: Use dev_name() instead of kobject_get_path() in debugfs")
> in pmdomain/next.
>
> > --- a/drivers/pmdomain/core.c
> > +++ b/drivers/pmdomain/core.c
> > @@ -3215,16 +3214,9 @@ static int genpd_summary_one(struct seq_file *s,
> >         }
> >
> >         list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
> > -               kobj_path = kobject_get_path(&pm_data->dev->kobj,
> > -                               genpd_is_irq_safe(genpd) ?
> > -                               GFP_ATOMIC : GFP_KERNEL);
> > -               if (kobj_path == NULL)
> > -                       continue;
> > -
> > -               seq_printf(s, "\n    %-50s  ", kobj_path);
> > +               seq_printf(s, "\n    %-50s  ", dev_name(pm_data->dev));
>
> While some of the old names didn't even fit in 50 characters, the new
> names need much less space, so perhaps this is a good opportunity to
> decrease the table width?

Sure, it seems reasonable! Do you want to send a patch?

>
> >                 rtpm_status_str(s, pm_data->dev);
> >                 perf_status_str(s, pm_data->dev);
> > -               kfree(kobj_path);
> >         }
> >
> >         seq_puts(s, "\n");

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 3/7] pmdomain: core: Use dev_name() instead of kobject_get_path() in debugfs
  2024-08-20  8:57     ` Ulf Hansson
@ 2024-08-30 15:50       ` Geert Uytterhoeven
  2024-09-02 14:42         ` Geert Uytterhoeven
  0 siblings, 1 reply; 23+ messages in thread
From: Geert Uytterhoeven @ 2024-08-30 15:50 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J . Wysocki, Sudeep Holla, linux-pm, Lorenzo Pieralisi,
	Nikunj Kela, Prasad Sodagudi, Maulik Shah, Daniel Lezcano,
	Krzysztof Kozlowski, linux-rt-users, linux-arm-kernel,
	linux-kernel, open list:TI ETHERNET SWITCH DRIVER (CPSW)

Hi Ulf,

On Tue, Aug 20, 2024 at 10:58 AM Ulf Hansson <ulf.hansson@linaro.org> wrote:
> On Tue, 20 Aug 2024 at 10:55, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> > On Mon, May 27, 2024 at 4:27 PM Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > > Using kobject_get_path() means a dynamic memory allocation gets done, which
> > > doesn't work on a PREEMPT_RT based configuration while holding genpd's raw
> > > spinlock.
> > >
> > > To fix the problem, let's convert into using the simpler dev_name(). This
> > > means the information about the path doesn't get presented in debugfs, but
> > > hopefully this shouldn't be an issue.
> > >
> > > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> > > ---
> > > Changes in v2:
> > >         - New patch.
> >
> > Thanks for your patch, which is now commit 9094e53ff5c86ebe ("pmdomain:
> > core: Use dev_name() instead of kobject_get_path() in debugfs")
> > in pmdomain/next.
> >
> > > --- a/drivers/pmdomain/core.c
> > > +++ b/drivers/pmdomain/core.c
> > > @@ -3215,16 +3214,9 @@ static int genpd_summary_one(struct seq_file *s,
> > >         }
> > >
> > >         list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
> > > -               kobj_path = kobject_get_path(&pm_data->dev->kobj,
> > > -                               genpd_is_irq_safe(genpd) ?
> > > -                               GFP_ATOMIC : GFP_KERNEL);
> > > -               if (kobj_path == NULL)
> > > -                       continue;
> > > -
> > > -               seq_printf(s, "\n    %-50s  ", kobj_path);
> > > +               seq_printf(s, "\n    %-50s  ", dev_name(pm_data->dev));
> >
> > While some of the old names didn't even fit in 50 characters, the new
> > names need much less space, so perhaps this is a good opportunity to
> > decrease the table width?
>
> Sure, it seems reasonable! Do you want to send a patch?

I started looking into it.  Then I noticed that on some systems
(e.g. TI am335x) the device names may have a longer format than
the typical <unit-address>.<nodename>. So I wanted to verify on
BeagleBone Black, but recent kernels crash during early boot.
Apparently that platform was broken between v6.8 and v6.9-rc1.
And during bisection, I encountered 3 different failure modes...

To be continued...

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 3/7] pmdomain: core: Use dev_name() instead of kobject_get_path() in debugfs
  2024-08-30 15:50       ` Geert Uytterhoeven
@ 2024-09-02 14:42         ` Geert Uytterhoeven
  2024-09-03 10:13           ` Ulf Hansson
  0 siblings, 1 reply; 23+ messages in thread
From: Geert Uytterhoeven @ 2024-09-02 14:42 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J . Wysocki, Sudeep Holla, linux-pm, Lorenzo Pieralisi,
	Nikunj Kela, Prasad Sodagudi, Maulik Shah, Daniel Lezcano,
	Krzysztof Kozlowski, linux-rt-users, linux-arm-kernel,
	linux-kernel, open list:TI ETHERNET SWITCH DRIVER (CPSW)

Hi Ulf,

On Fri, Aug 30, 2024 at 5:50 PM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> On Tue, Aug 20, 2024 at 10:58 AM Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > On Tue, 20 Aug 2024 at 10:55, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> > > On Mon, May 27, 2024 at 4:27 PM Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > > > Using kobject_get_path() means a dynamic memory allocation gets done, which
> > > > doesn't work on a PREEMPT_RT based configuration while holding genpd's raw
> > > > spinlock.
> > > >
> > > > To fix the problem, let's convert into using the simpler dev_name(). This
> > > > means the information about the path doesn't get presented in debugfs, but
> > > > hopefully this shouldn't be an issue.
> > > >
> > > > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> > > > ---
> > > > Changes in v2:
> > > >         - New patch.
> > >
> > > Thanks for your patch, which is now commit 9094e53ff5c86ebe ("pmdomain:
> > > core: Use dev_name() instead of kobject_get_path() in debugfs")
> > > in pmdomain/next.
> > >
> > > > --- a/drivers/pmdomain/core.c
> > > > +++ b/drivers/pmdomain/core.c
> > > > @@ -3215,16 +3214,9 @@ static int genpd_summary_one(struct seq_file *s,
> > > >         }
> > > >
> > > >         list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
> > > > -               kobj_path = kobject_get_path(&pm_data->dev->kobj,
> > > > -                               genpd_is_irq_safe(genpd) ?
> > > > -                               GFP_ATOMIC : GFP_KERNEL);
> > > > -               if (kobj_path == NULL)
> > > > -                       continue;
> > > > -
> > > > -               seq_printf(s, "\n    %-50s  ", kobj_path);
> > > > +               seq_printf(s, "\n    %-50s  ", dev_name(pm_data->dev));
> > >
> > > While some of the old names didn't even fit in 50 characters, the new
> > > names need much less space, so perhaps this is a good opportunity to
> > > decrease the table width?
> >
> > Sure, it seems reasonable! Do you want to send a patch?
>
> I started looking into it.  Then I noticed that on some systems
> (e.g. TI am335x) the device names may have a longer format than
> the typical <unit-address>.<nodename>. So I wanted to verify on
> BeagleBone Black, but recent kernels crash during early boot.
> Apparently that platform was broken between v6.8 and v6.9-rc1.
> And during bisection, I encountered 3 different failure modes...
>
> To be continued...

The longest generic node names documented in the Devicetree
Specification are "air-pollution-sensor" and "interrupt-controller"
(both counting 20 characters), so a typical device name needs 8
(32-bit unit address) + 1 (dot) + 20 = 29 characters.
However, I assume some devices lie outside the 32-bit address space,
and thus need more space?

With the BeagleBone Black boot issue fixed:
"/devices/platform/ocp/5600fe00.target-module"
resp. "/devices/platform/ocp/44c00000.interconnect/44c00000.interconnect:segment@200000/44e3e074.target-module"
are now shortened to "5600fe00.target-module" resp. "44e3e074.target-module".
However, "/devices/platform/ocp/48000000.interconnect/48000000.interconnect:segment@200000/48000000.interconnect:segment@200000:target-module@0"
is shortened to "48000000.interconnect:segment@200000:target-module@0",
which is still longer than the old column width...

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 3/7] pmdomain: core: Use dev_name() instead of kobject_get_path() in debugfs
  2024-09-02 14:42         ` Geert Uytterhoeven
@ 2024-09-03 10:13           ` Ulf Hansson
  0 siblings, 0 replies; 23+ messages in thread
From: Ulf Hansson @ 2024-09-03 10:13 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Rafael J . Wysocki, Sudeep Holla, linux-pm, Lorenzo Pieralisi,
	Nikunj Kela, Prasad Sodagudi, Maulik Shah, Daniel Lezcano,
	Krzysztof Kozlowski, linux-rt-users, linux-arm-kernel,
	linux-kernel, open list:TI ETHERNET SWITCH DRIVER (CPSW)

On Mon, 2 Sept 2024 at 16:43, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> Hi Ulf,
>
> On Fri, Aug 30, 2024 at 5:50 PM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> > On Tue, Aug 20, 2024 at 10:58 AM Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > > On Tue, 20 Aug 2024 at 10:55, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> > > > On Mon, May 27, 2024 at 4:27 PM Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > > > > Using kobject_get_path() means a dynamic memory allocation gets done, which
> > > > > doesn't work on a PREEMPT_RT based configuration while holding genpd's raw
> > > > > spinlock.
> > > > >
> > > > > To fix the problem, let's convert into using the simpler dev_name(). This
> > > > > means the information about the path doesn't get presented in debugfs, but
> > > > > hopefully this shouldn't be an issue.
> > > > >
> > > > > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> > > > > ---
> > > > > Changes in v2:
> > > > >         - New patch.
> > > >
> > > > Thanks for your patch, which is now commit 9094e53ff5c86ebe ("pmdomain:
> > > > core: Use dev_name() instead of kobject_get_path() in debugfs")
> > > > in pmdomain/next.
> > > >
> > > > > --- a/drivers/pmdomain/core.c
> > > > > +++ b/drivers/pmdomain/core.c
> > > > > @@ -3215,16 +3214,9 @@ static int genpd_summary_one(struct seq_file *s,
> > > > >         }
> > > > >
> > > > >         list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
> > > > > -               kobj_path = kobject_get_path(&pm_data->dev->kobj,
> > > > > -                               genpd_is_irq_safe(genpd) ?
> > > > > -                               GFP_ATOMIC : GFP_KERNEL);
> > > > > -               if (kobj_path == NULL)
> > > > > -                       continue;
> > > > > -
> > > > > -               seq_printf(s, "\n    %-50s  ", kobj_path);
> > > > > +               seq_printf(s, "\n    %-50s  ", dev_name(pm_data->dev));
> > > >
> > > > While some of the old names didn't even fit in 50 characters, the new
> > > > names need much less space, so perhaps this is a good opportunity to
> > > > decrease the table width?
> > >
> > > Sure, it seems reasonable! Do you want to send a patch?
> >
> > I started looking into it.  Then I noticed that on some systems
> > (e.g. TI am335x) the device names may have a longer format than
> > the typical <unit-address>.<nodename>. So I wanted to verify on
> > BeagleBone Black, but recent kernels crash during early boot.
> > Apparently that platform was broken between v6.8 and v6.9-rc1.
> > And during bisection, I encountered 3 different failure modes...
> >
> > To be continued...
>
> The longest generic node names documented in the Devicetree
> Specification are "air-pollution-sensor" and "interrupt-controller"
> (both counting 20 characters), so a typical device name needs 8
> (32-bit unit address) + 1 (dot) + 20 = 29 characters.
> However, I assume some devices lie outside the 32-bit address space,
> and thus need more space?
>
> With the BeagleBone Black boot issue fixed:
> "/devices/platform/ocp/5600fe00.target-module"
> resp. "/devices/platform/ocp/44c00000.interconnect/44c00000.interconnect:segment@200000/44e3e074.target-module"
> are now shortened to "5600fe00.target-module" resp. "44e3e074.target-module".
> However, "/devices/platform/ocp/48000000.interconnect/48000000.interconnect:segment@200000/48000000.interconnect:segment@200000:target-module@0"
> is shortened to "48000000.interconnect:segment@200000:target-module@0",
> which is still longer than the old column width...

Should we really care about those silly long names? And are those
really a problem from genpd debugfs point of view?

That said, I don't have a suggestion for a new value of the table
width, but I am certainly open to adjusting it to whatever you
propose.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2024-09-03 10:13 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-27 14:25 [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram on PREEMPT_RT Ulf Hansson
2024-05-27 14:25 ` [PATCH v2 1/7] pmdomain: core: Enable s2idle for CPU PM domains " Ulf Hansson
2024-05-28 19:55   ` Nikunj Kela
2024-05-30  8:15     ` Ulf Hansson
2024-05-30 14:23       ` Nikunj Kela
2024-06-03 13:58         ` Ulf Hansson
2024-06-04 17:22           ` Nikunj Kela
2024-05-27 14:25 ` [PATCH v2 2/7] pmdomain: core: Don't hold the genpd-lock when calling dev_pm_domain_set() Ulf Hansson
2024-05-27 14:25 ` [PATCH v2 3/7] pmdomain: core: Use dev_name() instead of kobject_get_path() in debugfs Ulf Hansson
2024-08-20  8:55   ` Geert Uytterhoeven
2024-08-20  8:57     ` Ulf Hansson
2024-08-30 15:50       ` Geert Uytterhoeven
2024-09-02 14:42         ` Geert Uytterhoeven
2024-09-03 10:13           ` Ulf Hansson
2024-05-27 14:25 ` [PATCH v2 4/7] cpuidle: psci-domain: Enable system-wide suspend on PREEMPT_RT Ulf Hansson
2024-05-27 14:25 ` [PATCH v2 5/7] cpuidle: psci: Drop redundant assignment of CPUIDLE_FLAG_RCU_IDLE Ulf Hansson
2024-05-27 14:25 ` [PATCH v2 6/7] cpuidle: psci: Enable the hierarchical topology for s2ram on PREEMPT_RT Ulf Hansson
2024-05-27 14:25 ` [PATCH v2 7/7] cpuidle: psci: Enable the hierarchical topology for s2idle " Ulf Hansson
2024-07-08 13:53 ` [PATCH v2 0/7] pmdomain/cpuidle-psci: Support s2idle/s2ram " Sebastian Andrzej Siewior
2024-07-09 15:31   ` Ulf Hansson
2024-07-31  8:15     ` Sebastian Andrzej Siewior
2024-07-25 10:32 ` Raghavendra Kakarla
2024-08-05 11:35 ` Ulf Hansson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox