Re: Adding runtime PM support to sata_mv driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Thanks for your replies. I am ccing the ide list now (and re-pasting
the ide patch).

Let me try and elaborate on what I am trying to achieve: I would like
to add a way to move the marvell sata controller to D3hot to save some
power. For my short term use case, I am just interested in turning off
the controllers which don't have any disks attached to them. For this,
I guess I don't really need to do much as the pci pm subsystem takes
care of suspending the controller. However, my goal is to keep the
patch generic, i.e. be able to turn off any marvell controller. So, if
there are disks attached to it, then I think that it should spin down
all the disks and power off the controller.

I would think that some userspace algorithm would decide if the
sata_mv controller should be moved into auto mode (i.e runtime power
managed). This might be done when there are no disks attached or the
system doesn't expect to use the disks behind the controller. If there
is intermittent disk usage, then the user space would not move it into
auto and keep the state as ON.

I am using the ata_pci_device_suspend for the runtime _suspend method
also because AFAICT it does exactly what I am trying to achieve. This
will try and do error handling (scsi_error_handler) which tries to
resume a device if its in the suspending state causing both threads to
be stuck.

Rafael, you mentioned in one of your emails that the patch doesn't
seem to be doing anything useful. How else do I suspend the sata_mv
controller in a proper way? Do you think that there isn't a need to
suspend the disks attached to the controller?

Thanks a lot,
Priyanka


From: Priyanka Gupta <ankaguptaca@xxxxxxxxx>
Date: Tue, 28 Dec 2010 20:49:45 -0600
Subject: [PATCH] Marvell controller Runtime Power Management

---
 arch/x86/configs/x86_64_defconfig |    1 +
 drivers/ata/sata_mv.c             |   46 +++++++++++++++++++++++++++++++++++-
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/arch/x86/configs/x86_64_defconfig
b/arch/x86/configs/x86_64_defconfig
index ee01a9d..b48d6ae 100644
--- a/arch/x86/configs/x86_64_defconfig
+++ b/arch/x86/configs/x86_64_defconfig
@@ -55,6 +55,7 @@ CONFIG_KEXEC=y
 CONFIG_CRASH_DUMP=y
 # CONFIG_COMPAT_VDSO is not set
 CONFIG_PM=y
+CONFIG_PM_RUNTIME=y
 CONFIG_PM_DEBUG=y
 CONFIG_PM_TRACE_RTC=y
 CONFIG_HIBERNATION=y
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index bf74a36..34a2eed 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -65,6 +65,7 @@
 #include <linux/mbus.h>
 #include <linux/bitops.h>
 #include <linux/gfp.h>
+#include <linux/pm_runtime.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -4191,21 +4192,35 @@ static struct platform_driver mv_platform_driver = {
 #ifdef CONFIG_PCI
 static int mv_pci_init_one(struct pci_dev *pdev,
                          const struct pci_device_id *ent);
+
+void mv_pci_remove_one(struct pci_dev *pdev);
+
 #ifdef CONFIG_PM
 static int mv_pci_device_resume(struct pci_dev *pdev);
 #endif

+#ifdef CONFIG_PM_OPS
+static int mv_pci_runtime_device_suspend(struct device *dev);
+static int mv_pci_runtime_device_resume(struct device *dev);
+
+static const struct dev_pm_ops mv_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(ata_pci_device_suspend, mv_pci_device_resume)
+       SET_RUNTIME_PM_OPS(mv_pci_runtime_device_suspend,
mv_pci_runtime_device_resume, NULL)
+};
+#endif

 static struct pci_driver mv_pci_driver = {
       .name                   = DRV_NAME,
       .id_table               = mv_pci_tbl,
       .probe                  = mv_pci_init_one,
-       .remove                 = ata_pci_remove_one,
+       .remove                 = mv_pci_remove_one,
 #ifdef CONFIG_PM
       .suspend                = ata_pci_device_suspend,
       .resume                 = mv_pci_device_resume,
 #endif
-
+#ifdef CONFIG_PM_OPS
+       .driver.pm              = &mv_pm_ops,
+#endif
 };

 /* move to PCI layer or libata core? */
@@ -4284,6 +4299,18 @@ static void mv_print_info(struct ata_host *host)
 }

 /**
+ *      mv_pci_remove_one - handle a removal of the marvell controller
+ *      @pdev: PCI device to be removed
+ *
+ *      LOCKING:
+ *      Inherited from caller.
+ */
+void mv_pci_remove_one(struct pci_dev *pdev) {
+       ata_pci_remove_one(pdev);
+       pm_runtime_get_noresume(&pdev->dev);
+}
+
+/**
 *      mv_pci_init_one - handle a positive probe of a PCI Marvell host
 *      @pdev: PCI device found
 *      @ent: PCI device ID entry for the matched host
@@ -4359,10 +4386,25 @@ static int mv_pci_init_one(struct pci_dev *pdev,

       pci_set_master(pdev);
       pci_try_set_mwi(pdev);
+       pm_runtime_put_noidle(&pdev->dev);
       return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
                                IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht);
 }

+#ifdef CONFIG_PM_OPS
+static int mv_pci_runtime_device_suspend(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       return ata_pci_device_suspend(pdev, PMSG_SUSPEND);
+}
+
+static int mv_pci_runtime_device_resume(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       return mv_pci_device_resume(pdev);
+}
+#endif
+
 #ifdef CONFIG_PM
 static int mv_pci_device_resume(struct pci_dev *pdev)
 {
--
1.7.3.1


On Fri, Dec 31, 2010 at 6:01 AM, Tejun Heo <tj@xxxxxxxxxx> wrote:
>
> Hello,
>
> On Fri, Dec 31, 2010 at 12:09:11AM +0100, Rafael J. Wysocki wrote:
> > Adding Tejun to the CC list, because he's our SATA expert.
> >
> > Also appending the patch so that he can actually see it.
>
> And you forgot. :-)
>
> > [Priyanka, it usually is better do discuss such things on mailing
> > lists, so that people can look into the archives and see the patches
> > etc.]
>
> Yes, when you reply, please at least cc linux-ide@xxxxxxxxxxxxxxxx
>
> > > > already been moved to SUSPENDING state by the __pm_runtime_suspend).
> > > > This in turn invokes the scsi_error_handler to run, which ends up
> > > > calling scsi_autopm_get_host which then tries to get the device and
> > > > hence tries to resume it. And they end up stuck, one thread trying to
> > > > suspend which won't succeed, and the other thread trying to resume.
> > > > See below the stack trace for both.
> > > >
> > > > If I skip the error handling the suspend works fine as you would
> > > > expect. However, that isn't a solution. I was wondering if you can
> > > > suggest what might be the best possible solution to this problem?
> > > >
> > > > I am attaching a patch as an attachment. Hope you can help.
> > >
> > > The problem is that you call ata_pci_device_suspend().  That routine
> > > apparently was not meant for use by runtime PM.
> >
> > Agreed.
>
> Hmmm... I'm not familiar with runtime PM.  What's it supposed to
> achieve?  Should it spin down the drive and power off the controller?
> If so, the only proper way would be going through EH, but how often is
> this gonna be activated?  Even auto-spindown feature implemented in
> hardware often doesn't help much (or even consumes more power) unless
> the idle period is quite long.
>
> Thanks.
>
> --
> tejun
--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux