Re: [PATCH v8 2/4] block: add runtime pm helpers

2013-01-31 Thread Alan Stern
On Thu, 31 Jan 2013, Aaron Lu wrote:

   +void blk_pm_runtime_init(struct request_queue *q, struct device *dev)
   +{
   + q-dev = dev;
   + q-rpm_status = RPM_ACTIVE;
   + pm_runtime_set_autosuspend_delay(q-dev, -1);
   + pm_runtime_use_autosuspend(q-dev);
   + pm_runtime_mark_last_busy(q-dev);
   + pm_runtime_autosuspend(q-dev);
  
  This last line is no longer needed.  It can't do anything useful, since 
  autosuspends are disabled (the delay is -1).
 
 Right, thanks.
 And the mark_last_busy can probably be removed too, it didn't make much
 sense here and we can add driver should call pm_runtime_mark_last_busy
 and pm_runtime_autosuspend in its runtime idle callback to the kernel
 doc. What do you think?

Yes, okay.

Alan Stern

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v8 2/4] block: add runtime pm helpers

2013-01-30 Thread Aaron Lu
From: Lin Ming ming.m@intel.com

Add runtime pm helper functions:

void blk_pm_runtime_init(struct request_queue *q, struct device *dev)
  - Initialization function for drivers to call.

int blk_pre_runtime_suspend(struct request_queue *q)
  - If any requests are in the queue, mark last busy and return -EBUSY.
Otherwise set q-rpm_status to RPM_SUSPENDING and return 0.

void blk_post_runtime_suspend(struct request_queue *q, int err)
  - If the suspend succeeded then set q-rpm_status to RPM_SUSPENDED.
Otherwise set it to RPM_ACTIVE.

void blk_pre_runtime_resume(struct request_queue *q)
  - Set q-rpm_status to RPM_RESUMING.

void blk_post_runtime_resume(struct request_queue *q, int err)
  - If the resume succeeded then set q-rpm_status to RPM_ACTIVE
and call __blk_run_queue, then mark last busy and autosuspend.
Otherwise set q-rpm_status to RPM_SUSPENDED.

Signed-off-by: Lin Ming ming.m@intel.com
Signed-off-by: Aaron Lu aaron...@intel.com
---
 block/blk-core.c   | 143 +
 include/linux/blkdev.h |  27 ++
 2 files changed, 170 insertions(+)

diff --git a/block/blk-core.c b/block/blk-core.c
index 66d3168..1ec09f6 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -30,6 +30,7 @@
 #include linux/list_sort.h
 #include linux/delay.h
 #include linux/ratelimit.h
+#include linux/pm_runtime.h
 
 #define CREATE_TRACE_POINTS
 #include trace/events/block.h
@@ -3043,6 +3044,148 @@ void blk_finish_plug(struct blk_plug *plug)
 }
 EXPORT_SYMBOL(blk_finish_plug);
 
+#ifdef CONFIG_PM_RUNTIME
+/**
+ * blk_pm_runtime_init - Block layer runtime PM initialization routine
+ * @q: the queue of the device
+ * @dev: the device the queue belongs to
+ *
+ * Description:
+ *Initialize runtime-PM-related fields for @q and start auto suspend for
+ *@dev. Drivers that want to take advantage of request-based runtime PM
+ *should call this function after @dev has been initialized, and its
+ *request queue @q has been allocated, and runtime PM for it can not happen
+ *yet(either due to disabled/forbidden or its usage_count  0). In most
+ *cases, driver should call this function before any I/O has taken place.
+ *
+ *This function takes care of setting up using auto suspend for the device,
+ *the autosuspend delay is set to -1 to make runtime suspend impossible
+ *until an updated value is either set by user or by driver. Drivers do
+ *not need to touch other autosuspend settings.
+ *
+ *The block layer runtime PM is request based, so only works for drivers
+ *that use request as their IO unit instead of those directly use bio's.
+ */
+void blk_pm_runtime_init(struct request_queue *q, struct device *dev)
+{
+   q-dev = dev;
+   q-rpm_status = RPM_ACTIVE;
+   pm_runtime_set_autosuspend_delay(q-dev, -1);
+   pm_runtime_use_autosuspend(q-dev);
+   pm_runtime_mark_last_busy(q-dev);
+   pm_runtime_autosuspend(q-dev);
+}
+EXPORT_SYMBOL(blk_pm_runtime_init);
+
+/**
+ * blk_pre_runtime_suspend - Pre runtime suspend check
+ * @q: the queue of the device
+ *
+ * Description:
+ *This function will check if runtime suspend is allowed for the device
+ *by examining if there are any requests pending in the queue. If there
+ *are requests pending, the device can not be runtime suspended; otherwise,
+ *the queue's status will be updated to SUSPENDING and the driver can
+ *proceed to suspend the device.
+ *
+ *For the not allowed case, we mark last busy for the device so that
+ *runtime PM core will try to autosuspend it some time later.
+ *
+ *This function should be called near the start of the device's
+ *runtime_suspend callback.
+ *
+ * Return:
+ *0- OK to runtime suspend the device
+ *-EBUSY   - Device should not be runtime suspended
+ */
+int blk_pre_runtime_suspend(struct request_queue *q)
+{
+   int ret = 0;
+
+   spin_lock_irq(q-queue_lock);
+   if (q-nr_pending) {
+   ret = -EBUSY;
+   pm_runtime_mark_last_busy(q-dev);
+   } else {
+   q-rpm_status = RPM_SUSPENDING;
+   }
+   spin_unlock_irq(q-queue_lock);
+   return ret;
+}
+EXPORT_SYMBOL(blk_pre_runtime_suspend);
+
+/**
+ * blk_post_runtime_suspend - Post runtime suspend processing
+ * @q: the queue of the device
+ * @err: return value of the device's runtime_suspend function
+ *
+ * Description:
+ *Update the queue's runtime status according to the return value of the
+ *device's runtime suspend function.
+ *
+ *This function should be called near the end of the device's
+ *runtime_suspend callback.
+ */
+void blk_post_runtime_suspend(struct request_queue *q, int err)
+{
+   spin_lock_irq(q-queue_lock);
+   if (!err)
+   q-rpm_status = RPM_SUSPENDED;
+   else
+   q-rpm_status = RPM_ACTIVE;
+   spin_unlock_irq(q-queue_lock);
+}

Re: [PATCH v8 2/4] block: add runtime pm helpers

2013-01-30 Thread Alan Stern
On Wed, 30 Jan 2013, Aaron Lu wrote:

 From: Lin Ming ming.m@intel.com
 
 Add runtime pm helper functions:
 
 void blk_pm_runtime_init(struct request_queue *q, struct device *dev)
   - Initialization function for drivers to call.
 
 int blk_pre_runtime_suspend(struct request_queue *q)
   - If any requests are in the queue, mark last busy and return -EBUSY.
 Otherwise set q-rpm_status to RPM_SUSPENDING and return 0.
 
 void blk_post_runtime_suspend(struct request_queue *q, int err)
   - If the suspend succeeded then set q-rpm_status to RPM_SUSPENDED.
 Otherwise set it to RPM_ACTIVE.
 
 void blk_pre_runtime_resume(struct request_queue *q)
   - Set q-rpm_status to RPM_RESUMING.
 
 void blk_post_runtime_resume(struct request_queue *q, int err)
   - If the resume succeeded then set q-rpm_status to RPM_ACTIVE
 and call __blk_run_queue, then mark last busy and autosuspend.
 Otherwise set q-rpm_status to RPM_SUSPENDED.
 
 Signed-off-by: Lin Ming ming.m@intel.com
 Signed-off-by: Aaron Lu aaron...@intel.com

 +void blk_pm_runtime_init(struct request_queue *q, struct device *dev)
 +{
 + q-dev = dev;
 + q-rpm_status = RPM_ACTIVE;
 + pm_runtime_set_autosuspend_delay(q-dev, -1);
 + pm_runtime_use_autosuspend(q-dev);
 + pm_runtime_mark_last_busy(q-dev);
 + pm_runtime_autosuspend(q-dev);

This last line is no longer needed.  It can't do anything useful, since 
autosuspends are disabled (the delay is -1).

Alan Stern

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v8 2/4] block: add runtime pm helpers

2013-01-30 Thread Aaron Lu
On Wed, Jan 30, 2013 at 10:54:53AM -0500, Alan Stern wrote:
 On Wed, 30 Jan 2013, Aaron Lu wrote:
 
  From: Lin Ming ming.m@intel.com
  
  Add runtime pm helper functions:
  
  void blk_pm_runtime_init(struct request_queue *q, struct device *dev)
- Initialization function for drivers to call.
  
  int blk_pre_runtime_suspend(struct request_queue *q)
- If any requests are in the queue, mark last busy and return -EBUSY.
  Otherwise set q-rpm_status to RPM_SUSPENDING and return 0.
  
  void blk_post_runtime_suspend(struct request_queue *q, int err)
- If the suspend succeeded then set q-rpm_status to RPM_SUSPENDED.
  Otherwise set it to RPM_ACTIVE.
  
  void blk_pre_runtime_resume(struct request_queue *q)
- Set q-rpm_status to RPM_RESUMING.
  
  void blk_post_runtime_resume(struct request_queue *q, int err)
- If the resume succeeded then set q-rpm_status to RPM_ACTIVE
  and call __blk_run_queue, then mark last busy and autosuspend.
  Otherwise set q-rpm_status to RPM_SUSPENDED.
  
  Signed-off-by: Lin Ming ming.m@intel.com
  Signed-off-by: Aaron Lu aaron...@intel.com
 
  +void blk_pm_runtime_init(struct request_queue *q, struct device *dev)
  +{
  +   q-dev = dev;
  +   q-rpm_status = RPM_ACTIVE;
  +   pm_runtime_set_autosuspend_delay(q-dev, -1);
  +   pm_runtime_use_autosuspend(q-dev);
  +   pm_runtime_mark_last_busy(q-dev);
  +   pm_runtime_autosuspend(q-dev);
 
 This last line is no longer needed.  It can't do anything useful, since 
 autosuspends are disabled (the delay is -1).

Right, thanks.
And the mark_last_busy can probably be removed too, it didn't make much
sense here and we can add driver should call pm_runtime_mark_last_busy
and pm_runtime_autosuspend in its runtime idle callback to the kernel
doc. What do you think?

Thanks,
Aaron

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html