public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "Arve Hjønnevåg" <arve@android.com>
To: linux-pm@lists.linux-foundation.org, linux-kernel@vger.kernel.org
Cc: "Arve Hjønnevåg" <arve@android.com>,
	"Pavel Machek" <pavel@ucw.cz>, "Rafael J. Wysocki" <rjw@sisk.pl>,
	"Len Brown" <len.brown@intel.com>
Subject: [PATCH 4/9] PM: suspend_block: Switch to list of active and inactive suspend blockers
Date: Thu, 22 Apr 2010 18:08:53 -0700	[thread overview]
Message-ID: <1271984938-13920-5-git-send-email-arve@android.com> (raw)
In-Reply-To: <1271984938-13920-4-git-send-email-arve@android.com>

This allows active suspend blockers to be listed

Signed-off-by: Arve Hjønnevåg <arve@android.com>
---
 include/linux/suspend_blocker.h |    6 ++-
 kernel/power/suspend_blocker.c  |   85 +++++++++++++++++++++++++++-----------
 2 files changed, 65 insertions(+), 26 deletions(-)

diff --git a/include/linux/suspend_blocker.h b/include/linux/suspend_blocker.h
index 21689cd..1faa433 100755
--- a/include/linux/suspend_blocker.h
+++ b/include/linux/suspend_blocker.h
@@ -16,8 +16,11 @@
 #ifndef _LINUX_SUSPEND_BLOCKER_H
 #define _LINUX_SUSPEND_BLOCKER_H
 
+#include <linux/list.h>
+
 /**
  * struct suspend_blocker - the basic suspend_blocker structure
+ * @link:	List entry for active or inactive list.
  * @flags:	Tracks initialized and active state.
  * @name:	Name used for debugging.
  *
@@ -29,7 +32,8 @@
 
 struct suspend_blocker {
 #ifdef CONFIG_SUSPEND_BLOCKERS
-	atomic_t            flags;
+	struct list_head    link;
+	int                 flags;
 	const char         *name;
 #endif
 };
diff --git a/kernel/power/suspend_blocker.c b/kernel/power/suspend_blocker.c
index 1b345d1..868e8f1 100644
--- a/kernel/power/suspend_blocker.c
+++ b/kernel/power/suspend_blocker.c
@@ -32,9 +32,11 @@ module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
 #define SB_INITIALIZED            (1U << 8)
 #define SB_ACTIVE                 (1U << 9)
 
+static DEFINE_SPINLOCK(list_lock);
 static DEFINE_SPINLOCK(state_lock);
-static atomic_t suspend_block_count;
-static atomic_t current_event_num;
+static LIST_HEAD(inactive_blockers);
+static LIST_HEAD(active_blockers);
+static int current_event_num;
 struct workqueue_struct *suspend_work_queue;
 struct suspend_blocker main_suspend_blocker;
 static suspend_state_t requested_suspend_state = PM_SUSPEND_MEM;
@@ -52,6 +54,14 @@ static bool enable_suspend_blockers;
 			tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec); \
 	} while (0);
 
+static void print_active_blockers_locked(void)
+{
+	struct suspend_blocker *blocker;
+
+	list_for_each_entry(blocker, &active_blockers, link)
+		pr_info("active suspend blocker %s\n", blocker->name);
+}
+
 /**
  * suspend_is_blocked() - Check if suspend should be blocked
  *
@@ -65,7 +75,7 @@ bool suspend_is_blocked(void)
 {
 	if (!enable_suspend_blockers)
 		return 0;
-	return !!atomic_read(&suspend_block_count);
+	return !list_empty(&active_blockers);
 }
 
 static void suspend_worker(struct work_struct *work)
@@ -75,13 +85,13 @@ static void suspend_worker(struct work_struct *work)
 
 	enable_suspend_blockers = true;
 	while (!suspend_is_blocked()) {
-		entry_event_num = atomic_read(&current_event_num);
+		entry_event_num = current_event_num;
 		if (debug_mask & DEBUG_SUSPEND)
 			pr_info("suspend: enter suspend\n");
 		ret = pm_suspend(requested_suspend_state);
 		if (debug_mask & DEBUG_EXIT_SUSPEND)
 			pr_info_time("suspend: exit suspend, ret = %d ", ret);
-		if (atomic_read(&current_event_num) == entry_event_num)
+		if (current_event_num == entry_event_num)
 			pr_info("suspend: pm_suspend returned with no event\n");
 	}
 	enable_suspend_blockers = false;
@@ -98,13 +108,20 @@ static DECLARE_WORK(suspend_work, suspend_worker);
  */
 void suspend_blocker_init(struct suspend_blocker *blocker, const char *name)
 {
+	unsigned long irqflags = 0;
+
 	WARN_ON(!name);
 
 	if (debug_mask & DEBUG_SUSPEND_BLOCKER)
 		pr_info("suspend_blocker_init name=%s\n", name);
 
 	blocker->name = name;
-	atomic_set(&blocker->flags, SB_INITIALIZED);
+	blocker->flags = SB_INITIALIZED;
+	INIT_LIST_HEAD(&blocker->link);
+
+	spin_lock_irqsave(&list_lock, irqflags);
+	list_add(&blocker->link, &inactive_blockers);
+	spin_unlock_irqrestore(&list_lock, irqflags);
 }
 EXPORT_SYMBOL(suspend_blocker_init);
 
@@ -114,15 +131,17 @@ EXPORT_SYMBOL(suspend_blocker_init);
  */
 void suspend_blocker_destroy(struct suspend_blocker *blocker)
 {
-	int flags;
+	unsigned long irqflags;
+	if (WARN_ON(!(blocker->flags & SB_INITIALIZED)))
+		return;
 	if (debug_mask & DEBUG_SUSPEND_BLOCKER)
 		pr_info("suspend_blocker_destroy name=%s\n", blocker->name);
-	flags = atomic_xchg(&blocker->flags, 0);
-	WARN(!(flags & SB_INITIALIZED), "suspend_blocker_destroy called on "
-					"uninitialized suspend_blocker\n");
-	if (flags == (SB_INITIALIZED | SB_ACTIVE))
-		if (atomic_dec_and_test(&suspend_block_count))
-			queue_work(suspend_work_queue, &suspend_work);
+	spin_lock_irqsave(&list_lock, irqflags);
+	blocker->flags &= ~SB_INITIALIZED;
+	list_del(&blocker->link);
+	if ((blocker->flags & SB_ACTIVE) && list_empty(&active_blockers))
+		queue_work(suspend_work_queue, &suspend_work);
+	spin_unlock_irqrestore(&list_lock, irqflags);
 }
 EXPORT_SYMBOL(suspend_blocker_destroy);
 
@@ -132,15 +151,20 @@ EXPORT_SYMBOL(suspend_blocker_destroy);
  */
 void suspend_block(struct suspend_blocker *blocker)
 {
-	WARN_ON(!(atomic_read(&blocker->flags) & SB_INITIALIZED));
+	unsigned long irqflags;
+
+	if (WARN_ON(!(blocker->flags & SB_INITIALIZED)))
+		return;
 
+	spin_lock_irqsave(&list_lock, irqflags);
+	blocker->flags |= SB_ACTIVE;
+	list_del(&blocker->link);
 	if (debug_mask & DEBUG_SUSPEND_BLOCKER)
 		pr_info("suspend_block: %s\n", blocker->name);
-	if (atomic_cmpxchg(&blocker->flags, SB_INITIALIZED,
-	    SB_INITIALIZED | SB_ACTIVE) == SB_INITIALIZED)
-		atomic_inc(&suspend_block_count);
+	list_add(&blocker->link, &active_blockers);
 
-	atomic_inc(&current_event_num);
+	current_event_num++;
+	spin_unlock_irqrestore(&list_lock, irqflags);
 }
 EXPORT_SYMBOL(suspend_block);
 
@@ -152,15 +176,26 @@ EXPORT_SYMBOL(suspend_block);
  */
 void suspend_unblock(struct suspend_blocker *blocker)
 {
-	WARN_ON(!(atomic_read(&blocker->flags) & SB_INITIALIZED));
+	unsigned long irqflags;
+
+	if (WARN_ON(!(blocker->flags & SB_INITIALIZED)))
+		return;
+
+	spin_lock_irqsave(&list_lock, irqflags);
 
 	if (debug_mask & DEBUG_SUSPEND_BLOCKER)
 		pr_info("suspend_unblock: %s\n", blocker->name);
+	list_del(&blocker->link);
+	list_add(&blocker->link, &inactive_blockers);
 
-	if (atomic_cmpxchg(&blocker->flags, SB_INITIALIZED | SB_ACTIVE,
-	    SB_INITIALIZED) == (SB_INITIALIZED | SB_ACTIVE))
-		if (atomic_dec_and_test(&suspend_block_count))
-			queue_work(suspend_work_queue, &suspend_work);
+	if ((blocker->flags & SB_ACTIVE) && list_empty(&active_blockers))
+		queue_work(suspend_work_queue, &suspend_work);
+	blocker->flags &= ~(SB_ACTIVE);
+	if (blocker == &main_suspend_blocker) {
+		if (debug_mask & DEBUG_SUSPEND)
+			print_active_blockers_locked();
+	}
+	spin_unlock_irqrestore(&list_lock, irqflags);
 }
 EXPORT_SYMBOL(suspend_unblock);
 
@@ -172,9 +207,9 @@ EXPORT_SYMBOL(suspend_unblock);
  */
 bool suspend_blocker_is_active(struct suspend_blocker *blocker)
 {
-	WARN_ON(!(atomic_read(&blocker->flags) & SB_INITIALIZED));
+	WARN_ON(!(blocker->flags & SB_INITIALIZED));
 
-	return !!(atomic_read(&blocker->flags) & SB_ACTIVE);
+	return !!(blocker->flags & SB_ACTIVE);
 }
 EXPORT_SYMBOL(suspend_blocker_is_active);
 
-- 
1.6.5.1


  reply	other threads:[~2010-04-23  1:10 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-23  1:08 [PATCH 0/9] Suspend block api (version 4) Arve Hjønnevåg
2010-04-23  1:08 ` [PATCH 1/9] PM: Add suspend block api Arve Hjønnevåg
2010-04-23  1:08   ` [PATCH 2/9] PM: suspend_block: Add driver to access suspend blockers from user-space Arve Hjønnevåg
2010-04-23  1:08     ` [PATCH 3/9] PM: suspend_block: Abort task freezing if a suspend_blocker is active Arve Hjønnevåg
2010-04-23  1:08       ` Arve Hjønnevåg [this message]
2010-04-23  1:08         ` [PATCH 5/9] PM: suspend_block: Add debugfs file Arve Hjønnevåg
2010-04-23  1:08           ` [PATCH 6/9] PM: suspend_block: Add suspend_blocker stats Arve Hjønnevåg
2010-04-23  1:08             ` [PATCH 7/9] PM: Add suspend blocking work Arve Hjønnevåg
2010-04-23  1:08               ` [PATCH 8/9] Input: Block suspend while event queue is not empty Arve Hjønnevåg
2010-04-23  1:08                 ` [PATCH 9/9] power_supply: Block suspend while power supply change notifications are pending Arve Hjønnevåg
2010-04-23 20:56                 ` [PATCH 8/9] Input: Block suspend while event queue is not empty Randy Dunlap
2010-04-23 21:08                   ` Dmitry Torokhov
2010-04-24  5:02                     ` Arve Hjønnevåg
2010-04-24 14:36                       ` [linux-pm] " Alan Stern
2010-04-25  2:30                         ` Rafael J. Wysocki
2010-04-25 15:29                           ` Alan Stern
2010-04-25 22:41                             ` Arve Hjønnevåg
2010-04-24  4:58                   ` Arve Hjønnevåg
2010-04-23  8:16               ` [PATCH 7/9] PM: Add suspend blocking work Tejun Heo
2010-04-23 12:20                 ` Oleg Nesterov
2010-04-23 22:49                   ` Arve Hjønnevåg
2010-04-24  5:21                     ` Arve Hjønnevåg
2010-04-24  6:33                     ` Tejun Heo
2010-04-24  7:21                       ` Arve Hjønnevåg
2010-04-24  7:43                         ` Tejun Heo
2010-04-26 14:06                     ` Oleg Nesterov
2010-04-23 20:58           ` [PATCH 5/9] PM: suspend_block: Add debugfs file Randy Dunlap
2010-04-24  3:23             ` Arve Hjønnevåg
2010-04-24  4:24               ` Randy Dunlap
2010-04-24  4:54                 ` Arve Hjønnevåg
2010-04-25 18:15             ` Greg KH
2010-04-25 19:53               ` Randy Dunlap
2010-04-26  0:00                 ` tytso
2010-04-26  0:23                   ` Randy Dunlap
2010-04-26  0:45                     ` tytso
2010-04-26  0:50                       ` Randy Dunlap
2010-04-26  1:39                     ` [linux-pm] " Alan Stern
2010-04-26  6:24                 ` Brian Swetland
2010-04-26 13:28                   ` Randy Dunlap
2010-04-23  2:25     ` [linux-pm] [PATCH 2/9] PM: suspend_block: Add driver to access suspend blockers from user-space Matt Helsley
2010-04-23  3:54       ` Arve Hjønnevåg
2010-04-23  4:38       ` Greg KH
2010-04-23  8:43     ` Pavel Machek
2010-04-23 16:43       ` [linux-pm] " Alan Stern
2010-04-24  3:20         ` Arve Hjønnevåg
2010-04-24  5:55           ` Pavel Machek
2010-04-24 14:44             ` Alan Stern
2010-04-25 22:34               ` Arve Hjønnevåg
2010-04-26 19:25                 ` Alan Stern
2010-04-27  4:04                   ` Arve Hjønnevåg
2010-04-27 18:33                     ` Alan Stern
2010-04-27 22:03                       ` Rafael J. Wysocki
2010-04-27 23:22                         ` Arve Hjønnevåg
2010-04-24  1:53       ` tytso
2010-04-24  5:39         ` Pavel Machek
2010-04-23 16:33   ` [PATCH 1/9] PM: Add suspend block api Alan Stern
2010-04-23 16:45     ` [linux-pm] " Alan Stern
2010-04-24  2:15     ` Arve Hjønnevåg
2010-04-24  2:30       ` Alan Stern
2010-04-24  3:14         ` Arve Hjønnevåg
2010-04-23  4:39 ` [linux-pm] [PATCH 0/9] Suspend block api (version 4) Greg KH

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=1271984938-13920-5-git-send-email-arve@android.com \
    --to=arve@android.com \
    --cc=len.brown@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@lists.linux-foundation.org \
    --cc=pavel@ucw.cz \
    --cc=rjw@sisk.pl \
    /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