All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: pm list <linux-pm@lists.linux-foundation.org>,
	ACPI Devel Maling List <linux-acpi@vger.kernel.org>,
	Greg KH <greg@kroah.com>, Len Brown <lenb@kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Alexey Starikovskiy <astarikovskiy@suse.de>,
	David Brownell <david-b@pacbell.net>, Pavel Machek <pavel@ucw.cz>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>
Subject: Re: [RFC][PATCH] PM: Introduce new top level suspend and hibernation callbacks (rev. 2)
Date: Sat, 22 Mar 2008 23:17:57 +0100	[thread overview]
Message-ID: <200803222317.58206.rjw@sisk.pl> (raw)
In-Reply-To: <Pine.LNX.4.44L0.0803202229060.16520-100000@netrider.rowland.org>

On Friday, 21 of March 2008, Alan Stern wrote:
> On Fri, 21 Mar 2008, Rafael J. Wysocki wrote:
> 
> > > One trivial problem is that your dpm_prepare and dpm_complete routines 
> > > go through the list in the wrong order.
> > 
> > I'm not all so sure that the order is actually wrong.  What would be the
> > advantage of the forward order over the current one?
> 
> The advantage is that races no longer matter.
> 
> Suppose you're going through the list backwards and a race occurs, so
> that a child is registered while the parent's prepare() is running.  
> That new child will of course be at the end of dpm_active, so the loop
> in dpm_prepare won't see it (assuming you adopt the approach of using
> only a single list).  But if you go through the list forwards and a new
> child is added, you will naturally see the child when you reach the end
> of the list.  You don't even have to go through the business about
> changing the parent's state back to DPM_ON.
> 
> There are other ways of describing the situation, but they all come 
> down to the same thing.  For instance, this is the way Ben was talking 
> about doing things.
> 
> > > Since dpm_prepare is supposed to go through the list in the forward
> > > direction, logically the "root" of the device tree should be the first
> > > thing "prepared".  This means you should not allow parentless devices
> > > to be registered any time after dpm_prepare has started.  Is that 
> > > liable to cause problems?
> > 
> > I'm still not seeing the advantage of the forward direction in the first place.
> > 
> > Although I don't see what particular problems that may cause, I think the
> > current approach (first, block registrations of new children for each
> > ->prepare()d device and finally block any registrations of new devices) is
> > more natural.
> 
> I suppose for parentless devices it doesn't really matter.  You could
> safely allow them to be registered any time up until dpm_prepare()  
> finishes -- which is what your patch does.  Perhaps the "all_inactive"
> flag should be renamed to "all_prepared".
> 
> > > There may be similar problems with complete().  A number of drivers
> > > check during their resume method for the presence of new children
> > > plugged in while the system was asleep.  All these drivers would have
> > > to be converted over to the new scheme if they weren't permitted to
> > > register the new children before complete() was called.  Of course,
> > > this is easily fixed by permitting new children starting from when
> > > resume() is called rather than when complete() is called.
> > 
> > Well, the problem here was the protection of the correct ordering of the
> > various lists.  However, if the approach with changing 'status' is adopted
> > instead, which seems to be better, we'll be able to unblock the registering
> > of new children before ->resume().
> 
> Yep.  The only thing to watch out for is in device_pm_remove(); it
> would be a disaster if somehow a device was removed while it was being
> prepared/suspended/resumed/completed/whatever.  I know that's not
> supposed to happen but there's nothing to prevent it, especially if
> the device in question doesn't have a driver.  No doubt you can invent
> a way to allow this to happen safely.

Well, that's a separate issue that IMO should be addressed in a separate patch.
Something like the one below comes to mind.

The comment removed by the patch is wrong IMO, because it implies that
device_add() may be called with the device semaphore held and that might
deadlock in bus_attach_device().  Thus, I think we can acquire dev->sem
in device_pm_add() and in device_pm_remove().

Thanks,
Rafael

---
 drivers/base/power/main.c |   21 ++++++++++++++-------
 include/linux/pm.h        |    1 +
 2 files changed, 15 insertions(+), 7 deletions(-)

Index: linux-2.6/drivers/base/power/main.c
===================================================================
--- linux-2.6.orig/drivers/base/power/main.c
+++ linux-2.6/drivers/base/power/main.c
@@ -41,10 +41,6 @@
  * from the bottom (i.e., end) up and resumed in the opposite order.
  * That way no parent will be suspended while it still has an active
  * child.
- *
- * Since device_pm_add() may be called with a device semaphore held,
- * we must never try to acquire a device semaphore while holding
- * dpm_list_mutex.
  */
 
 LIST_HEAD(dpm_active);
@@ -68,6 +64,7 @@ int device_pm_add(struct device *dev)
 	pr_debug("PM: Adding info for %s:%s\n",
 		 dev->bus ? dev->bus->name : "No Bus",
 		 kobject_name(&dev->kobj));
+	down(&dev->sem);
 	mutex_lock(&dpm_list_mtx);
 	if ((dev->parent && dev->parent->power.sleeping) || all_sleeping) {
 		if (dev->parent->power.sleeping)
@@ -80,10 +77,13 @@ int device_pm_add(struct device *dev)
 		error = -EBUSY;
 	} else {
 		error = dpm_sysfs_add(dev);
-		if (!error)
+		if (!error) {
+			dev->power.present = true;
 			list_add_tail(&dev->power.entry, &dpm_active);
+		}
 	}
 	mutex_unlock(&dpm_list_mtx);
+	up(&dev->sem);
 	return error;
 }
 
@@ -98,10 +98,13 @@ void device_pm_remove(struct device *dev
 	pr_debug("PM: Removing info for %s:%s\n",
 		 dev->bus ? dev->bus->name : "No Bus",
 		 kobject_name(&dev->kobj));
+	down(&dev->sem);
 	mutex_lock(&dpm_list_mtx);
 	dpm_sysfs_remove(dev);
+	dev->power.present = false;
 	list_del_init(&dev->power.entry);
 	mutex_unlock(&dpm_list_mtx);
+	up(&dev->sem);
 }
 
 /**
@@ -196,6 +199,8 @@ static int resume_device(struct device *
 	TRACE_RESUME(0);
 
 	down(&dev->sem);
+	if (!dev->power.present)
+		goto End;
 
 	if (dev->bus && dev->bus->resume) {
 		dev_dbg(dev,"resuming\n");
@@ -211,7 +216,7 @@ static int resume_device(struct device *
 		dev_dbg(dev,"class resume\n");
 		error = dev->class->resume(dev);
 	}
-
+ End:
 	up(&dev->sem);
 
 	TRACE_RESUME(error);
@@ -366,6 +371,8 @@ static int suspend_device(struct device 
 	int error = 0;
 
 	down(&dev->sem);
+	if (!dev->power.present)
+		goto End;
 
 	if (dev->power.power_state.event) {
 		dev_dbg(dev, "PM: suspend %d-->%d\n",
@@ -389,7 +396,7 @@ static int suspend_device(struct device 
 		error = dev->bus->suspend(dev, state);
 		suspend_report_result(dev->bus->suspend, error);
 	}
-
+ End:
 	up(&dev->sem);
 
 	return error;
Index: linux-2.6/include/linux/pm.h
===================================================================
--- linux-2.6.orig/include/linux/pm.h
+++ linux-2.6/include/linux/pm.h
@@ -185,6 +185,7 @@ struct dev_pm_info {
 	unsigned		can_wakeup:1;
 	unsigned		should_wakeup:1;
 	bool			sleeping:1;	/* Owned by the PM core */
+	bool			present:1;	/* Owned by the PM core */
 #ifdef	CONFIG_PM_SLEEP
 	struct list_head	entry;
 #endif

  parent reply	other threads:[~2008-03-22 22:18 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-21  0:01 [RFC][PATCH] PM: Introduce new top level suspend and hibernation callbacks (rev. 2) Rafael J. Wysocki
2008-03-21  0:01 ` Rafael J. Wysocki
2008-03-21  0:21 ` [linux-pm] " Johannes Berg
2008-03-21  0:26   ` Rafael J. Wysocki
2008-03-21  0:26   ` [linux-pm] " Rafael J. Wysocki
2008-03-25  9:49   ` Oliver Neukum
2008-03-25  9:49   ` [linux-pm] " Oliver Neukum
2008-03-25 13:06     ` Rafael J. Wysocki
2008-03-25 13:15       ` Oliver Neukum
2008-03-25 13:15       ` [linux-pm] " Oliver Neukum
2008-03-25 13:15         ` Oliver Neukum
2008-03-25 14:19         ` Alan Stern
2008-03-25 14:19           ` Alan Stern
2008-03-25 14:24           ` Oliver Neukum
2008-03-25 14:24           ` [linux-pm] " Oliver Neukum
2008-03-25 14:24             ` Oliver Neukum
2008-03-25 14:33             ` Alan Stern
2008-03-25 14:33               ` Alan Stern
2008-03-25 19:48               ` Oliver Neukum
2008-03-25 19:48               ` [linux-pm] " Oliver Neukum
2008-03-25 19:48                 ` Oliver Neukum
2008-03-25 20:41                 ` Rafael J. Wysocki
2008-03-25 20:41                 ` [linux-pm] " Rafael J. Wysocki
2008-03-25 20:41                   ` Rafael J. Wysocki
2008-03-25 20:49                   ` Oliver Neukum
2008-03-25 20:49                     ` Oliver Neukum
2008-03-25 20:56                     ` Rafael J. Wysocki
2008-03-25 20:56                       ` Rafael J. Wysocki
2008-03-26 14:10                       ` Alan Stern
2008-03-26 14:10                         ` Alan Stern
2008-03-26 14:24                         ` Oliver Neukum
2008-03-26 14:24                           ` Oliver Neukum
2008-03-26 14:40                           ` Alan Stern
2008-03-26 14:40                             ` Alan Stern
2008-03-26 15:42                             ` Oliver Neukum
2008-03-26 15:42                               ` Oliver Neukum
2008-03-26 16:36                               ` Alan Stern
2008-03-26 16:36                                 ` Alan Stern
2008-03-26 20:46                                 ` Rafael J. Wysocki
2008-03-27  2:48                                   ` Alan Stern
2008-03-27  2:48                                     ` Alan Stern
2008-03-27  2:48                                   ` Alan Stern
2008-03-26 20:46                                 ` Rafael J. Wysocki
2008-03-26 16:36                               ` Alan Stern
2008-03-26 15:42                             ` Oliver Neukum
2008-03-26 14:40                           ` Alan Stern
2008-03-26 14:24                         ` Oliver Neukum
2008-03-26 14:10                       ` Alan Stern
2008-03-25 20:56                     ` Rafael J. Wysocki
2008-03-25 20:49                   ` Oliver Neukum
2008-03-25 14:33             ` Alan Stern
2008-03-25 14:19         ` Alan Stern
2008-03-25 13:06     ` Rafael J. Wysocki
2008-03-21  0:21 ` Johannes Berg
2008-03-21  1:21 ` Alan Stern
2008-03-21  1:21 ` Alan Stern
2008-03-21  2:14   ` Rafael J. Wysocki
2008-03-21  2:14   ` Rafael J. Wysocki
2008-03-21  2:53     ` Alan Stern
2008-03-22 22:17       ` Rafael J. Wysocki
2008-03-22 22:17       ` Rafael J. Wysocki [this message]
2008-03-22 23:28         ` Alan Stern
2008-03-22 23:44           ` Rafael J. Wysocki
2008-03-23  2:07             ` Alan Stern
2008-03-23 18:41               ` Rafael J. Wysocki
2008-03-23 18:41               ` Rafael J. Wysocki
2008-03-23  2:07             ` Alan Stern
2008-03-22 23:44           ` Rafael J. Wysocki
2008-03-22 23:28         ` Alan Stern
2008-03-21  2:53     ` Alan Stern
2008-03-21  8:15 ` Sam Ravnborg
2008-03-23 21:16   ` Rafael J. Wysocki
2008-03-23 21:16   ` Rafael J. Wysocki
2008-03-21  8:15 ` Sam Ravnborg
  -- strict thread matches above, loose matches on Subject: below --
2008-03-21  0:01 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=200803222317.58206.rjw@sisk.pl \
    --to=rjw@sisk.pl \
    --cc=astarikovskiy@suse.de \
    --cc=benh@kernel.crashing.org \
    --cc=david-b@pacbell.net \
    --cc=greg@kroah.com \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@lists.linux-foundation.org \
    --cc=pavel@ucw.cz \
    --cc=stern@rowland.harvard.edu \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.