diff mbox series

[net-next,1/2] e1000e: Leverage direct_complete to speed up s2ram

Message ID 20210315190231.3302869-2-anthony.l.nguyen@intel.com
State Superseded
Headers show
Series 1GbE Intel Wired LAN Driver Updates 2021-03-15 | expand

Commit Message

Tony Nguyen March 15, 2021, 7:02 p.m. UTC
From: Chen Yu <yu.c.chen@intel.com>

The NIC is put in runtime suspend status when there is no cable connected.
As a result, it is safe to keep non-wakeup NIC in runtime suspended during
s2ram because the system does not rely on the NIC plug event nor WoL to wake
up the system. Besides that, unlike the s2idle, s2ram does not need to
manipulate S0ix settings during suspend.

This patch introduces the .prepare() for e1000e so that if the NIC is runtime
suspended the subsequent suspend/resume hooks will be skipped so as to speed
up the s2ram. The pm core will check whether the NIC is a wake up device so
there's no need to check it again in .prepare(). DPM_FLAG_SMART_PREPARE flag
should be set during probe to ask the pci subsystem to honor the driver's
prepare() result. Besides, the NIC remains runtime suspended after resumed
from s2ram as there is no need to resume it.

Tested on i7-2600K with 82579V NIC
Before the patch:
e1000e 0000:00:19.0: pci_pm_suspend+0x0/0x160 returned 0 after 225146 usecs
e1000e 0000:00:19.0: pci_pm_resume+0x0/0x90 returned 0 after 140588 usecs

After the patch:
echo disabled > //sys/devices/pci0000\:00/0000\:00\:19.0/power/wakeup
becomes 0 usecs because the hooks will be skipped.

Suggested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Signed-off-by: Chen Yu <yu.c.chen@intel.com>
Tested-by: Dvora Fuxbrumer <dvorax.fuxbrumer@linux.intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
 drivers/net/ethernet/intel/e1000e/netdev.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

Comments

Jakub Kicinski March 15, 2021, 9:04 p.m. UTC | #1
On Mon, 15 Mar 2021 12:02:30 -0700 Tony Nguyen wrote:
> +static __maybe_unused int e1000e_pm_prepare(struct device *dev)
> +{
> +	return pm_runtime_suspended(dev) &&
> +		pm_suspend_via_firmware();

nit: I don't think you need to mark functions called by __maybe_unused
     as __maybe_unused, do you?

The series LGTM although I don't know much about PM.
Chen Yu March 16, 2021, 7:53 a.m. UTC | #2
Hi Jakub,
thanks for taking a look!
On Mon, Mar 15, 2021 at 02:04:22PM -0700, Jakub Kicinski wrote:
> On Mon, 15 Mar 2021 12:02:30 -0700 Tony Nguyen wrote:

> > +static __maybe_unused int e1000e_pm_prepare(struct device *dev)

> > +{

> > +	return pm_runtime_suspended(dev) &&

> > +		pm_suspend_via_firmware();

> 

> nit: I don't think you need to mark functions called by __maybe_unused

>      as __maybe_unused, do you?

> 

Not sure which function do you refer to having the __maybe_unused attribute
and invokes this e1000e_pm_prepare()?
I copied the definition from e1000e_pm_suspend() that if CONFIG_PM_SLEEP is not
set, we might get compile error of such PM hooks in this driver.
> The series LGTM although I don't know much about PM.

Thanks!

Best,
Chenyu
diff mbox series

Patch

diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index e9b82c209c2d..8cd1b3e9e514 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -25,6 +25,7 @@ 
 #include <linux/pm_runtime.h>
 #include <linux/aer.h>
 #include <linux/prefetch.h>
+#include <linux/suspend.h>
 
 #include "e1000.h"
 
@@ -6918,6 +6919,12 @@  static int __e1000_resume(struct pci_dev *pdev)
 	return 0;
 }
 
+static __maybe_unused int e1000e_pm_prepare(struct device *dev)
+{
+	return pm_runtime_suspended(dev) &&
+		pm_suspend_via_firmware();
+}
+
 static __maybe_unused int e1000e_pm_suspend(struct device *dev)
 {
 	struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
@@ -7626,7 +7633,7 @@  static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	e1000_print_device_info(adapter);
 
-	dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NO_DIRECT_COMPLETE);
+	dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_SMART_PREPARE);
 
 	if (pci_dev_run_wake(pdev) && hw->mac.type < e1000_pch_cnp)
 		pm_runtime_put_noidle(&pdev->dev);
@@ -7851,6 +7858,7 @@  MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
 
 static const struct dev_pm_ops e1000_pm_ops = {
 #ifdef CONFIG_PM_SLEEP
+	.prepare	= e1000e_pm_prepare,
 	.suspend	= e1000e_pm_suspend,
 	.resume		= e1000e_pm_resume,
 	.freeze		= e1000e_pm_freeze,