From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Linux PM mailing list <linux-pm@lists.linux-foundation.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
Magnus Damm <magnus.damm@gmail.com>,
linux-sh@vger.kernel.org
Subject: [PATCH 2/9] PM / Domains: Implement subdomain counters as atomic fields
Date: Sun, 31 Jul 2011 19:47:48 +0200 [thread overview]
Message-ID: <201107311947.48268.rjw@sisk.pl> (raw)
In-Reply-To: <201107311946.06654.rjw@sisk.pl>
From: Rafael J. Wysocki <rjw@sisk.pl>
Currently, pm_genpd_poweron() and pm_genpd_poweroff() need to take
the parent PM domain's lock in order to modify the parent's counter
of active subdomains in a nonracy way. This causes the locking to be
considerably complex and in fact is not necessary, because the
subdomain counters may be implemented as atomic fields and they
won't have to be modified under a lock.
Replace the unsigned in sd_count field in struct generic_pm_domain
by an atomic_t one and modify the code in drivers/base/power/domain.c
to take this change into account.
This patch doesn't change the locking yet, that is going to be done
in a separate subsequent patch.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/base/power/domain.c | 30 ++++++++++++++++++++----------
include/linux/pm_domain.h | 2 +-
2 files changed, 21 insertions(+), 11 deletions(-)
Index: linux-2.6/drivers/base/power/domain.c
===================================================================
--- linux-2.6.orig/drivers/base/power/domain.c
+++ linux-2.6/drivers/base/power/domain.c
@@ -29,10 +29,20 @@ static struct generic_pm_domain *dev_to_
return pd_to_genpd(dev->pm_domain);
}
-static void genpd_sd_counter_dec(struct generic_pm_domain *genpd)
+static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd)
{
- if (!WARN_ON(genpd->sd_count == 0))
- genpd->sd_count--;
+ bool ret = false;
+
+ if (!WARN_ON(atomic_read(&genpd->sd_count) == 0))
+ ret = !!atomic_dec_and_test(&genpd->sd_count);
+
+ return ret;
+}
+
+static void genpd_sd_counter_inc(struct generic_pm_domain *genpd)
+{
+ atomic_inc(&genpd->sd_count);
+ smp_mb__after_atomic_inc();
}
static void genpd_acquire_lock(struct generic_pm_domain *genpd)
@@ -118,7 +128,7 @@ int pm_genpd_poweron(struct generic_pm_d
genpd_set_active(genpd);
if (parent)
- parent->sd_count++;
+ genpd_sd_counter_inc(parent);
out:
mutex_unlock(&genpd->lock);
@@ -254,7 +264,7 @@ static int pm_genpd_poweroff(struct gene
|| genpd->resume_count > 0)
return 0;
- if (genpd->sd_count > 0)
+ if (atomic_read(&genpd->sd_count) > 0)
return -EBUSY;
not_suspended = 0;
@@ -325,8 +335,7 @@ static int pm_genpd_poweroff(struct gene
genpd->status = GPD_STATE_POWER_OFF;
if (parent) {
- genpd_sd_counter_dec(parent);
- if (parent->sd_count == 0)
+ if (genpd_sd_counter_dec(parent))
genpd_queue_power_off_work(parent);
genpd_release_lock(parent);
@@ -491,7 +500,8 @@ static void pm_genpd_sync_poweroff(struc
if (genpd->status == GPD_STATE_POWER_OFF)
return;
- if (genpd->suspended_count != genpd->device_count || genpd->sd_count > 0)
+ if (genpd->suspended_count != genpd->device_count
+ || atomic_read(&genpd->sd_count) > 0)
return;
if (genpd->power_off)
@@ -1152,7 +1162,7 @@ int pm_genpd_add_subdomain(struct generi
list_add_tail(&new_subdomain->sd_node, &genpd->sd_list);
new_subdomain->parent = genpd;
if (subdomain->status != GPD_STATE_POWER_OFF)
- genpd->sd_count++;
+ genpd_sd_counter_inc(genpd);
out:
mutex_unlock(&new_subdomain->lock);
@@ -1227,7 +1237,7 @@ void pm_genpd_init(struct generic_pm_dom
genpd->gov = gov;
INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
genpd->in_progress = 0;
- genpd->sd_count = 0;
+ atomic_set(&genpd->sd_count, 0);
genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE;
init_waitqueue_head(&genpd->status_wait_queue);
genpd->poweroff_task = NULL;
Index: linux-2.6/include/linux/pm_domain.h
===================================================================
--- linux-2.6.orig/include/linux/pm_domain.h
+++ linux-2.6/include/linux/pm_domain.h
@@ -33,7 +33,7 @@ struct generic_pm_domain {
struct dev_power_governor *gov;
struct work_struct power_off_work;
unsigned int in_progress; /* Number of devices being suspended now */
- unsigned int sd_count; /* Number of subdomains with power "on" */
+ atomic_t sd_count; /* Number of subdomains with power "on" */
enum gpd_status status; /* Current state of the domain */
wait_queue_head_t status_wait_queue;
struct task_struct *poweroff_task; /* Powering off task */
next prev parent reply other threads:[~2011-07-31 18:24 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-07-31 17:46 [PATCH 0/9] PM / Domains: Allow generic PM domains to have multiple parents Rafael J. Wysocki
2011-07-31 17:47 ` [PATCH 1/9] PM / Domains: Fix pm_genpd_poweron() Rafael J. Wysocki
2011-07-31 17:47 ` Rafael J. Wysocki [this message]
2011-07-31 17:48 ` [PATCH 3/9] PM / Domains: Do not take parent locks to modify subdomain counters Rafael J. Wysocki
2011-07-31 17:49 ` [PATCH 4/9] PM / Domains: Make pm_genpd_poweron() always survive parent removal Rafael J. Wysocki
2011-07-31 17:49 ` [PATCH 5/9] PM / Domains: Add "wait for parent" status for generic PM domains Rafael J. Wysocki
2011-07-31 17:50 ` [PATCH 6/9] PM / Domains: Allow generic PM domains to have multiple masters Rafael J. Wysocki
2011-07-31 17:51 ` [PATCH 7/9] PM / Domains: Rename GPD_STATE_WAIT_PARENT to GPD_STATE_WAIT_MASTER Rafael J. Wysocki
2011-07-31 17:52 ` [PATCH 8/9] PM / Domains: Rename second argument of pm_genpd_add_subdomain() Rafael J. Wysocki
2011-07-31 17:52 ` [PATCH 9/9] ARM / shmobile: Make A3RV be a subdomain of A4LC on SH7372 Rafael J. Wysocki
2011-08-13 19:43 ` [Update][PATCH " Rafael J. Wysocki
2011-08-14 14:07 ` [Update x2][PATCH " Rafael J. Wysocki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201107311947.48268.rjw@sisk.pl \
--to=rjw@sisk.pl \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@lists.linux-foundation.org \
--cc=linux-sh@vger.kernel.org \
--cc=magnus.damm@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox