Linux Power Management development
 help / color / mirror / Atom feed
* Re: [alsa-devel] [PATCH] usb: add USB_QUIRK_RESET_RESUME for M-Audio 49
From: Clemens Ladisch @ 2012-11-25 22:01 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, Steffen Müller,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-pm-u79uwXL29TY76Z2rM5mHXA, Olivier MATZ,
	stable-u79uwXL29TY76Z2rM5mHXA, David Banks, Ralf Lang,
	Oliver Neukum
In-Reply-To: <20121125212100.GE24024-fcEM2ccDkbL2nhBuCrrZHw@public.gmane.org>

Jonathan Nieder wrote:
> Some USB MIDI keyboards fail to operate after a USB autosuspend.

Make that *all* USB MIDI devices with input ports.

This is not a bug in the device, but one of the many bugs introduced
with the autosuspend code in <http://git.kernel.org/linus/88a8516a2128>.

That patch does not handle input at all, i.e., when the driver wants to
read from the device, it just doesn't take it out of suspend mode.

> A workaround is to disable USB autosuspend for these devices by
> putting AUTOSUSPEND_USBID_BLACKLIST="0763:2027" (resp. 0763:019b) in
> /etc/laptop-mode/conf.d/usb-autosuspend.conf.  In the spirit of commit
> 166cb70e97bd ("usb: add USB_QUIRK_RESET_RESUME for M-Audio 88es"),
> reset the device on resume so this workaround is not needed any more.

It is not feasible to add the IDs of all USB MIDI devices.

I'm working on a fix that adds proper power management for input ports,
but this requires the driver to be reorganized a little ...


Regards,
Clemens
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH] usb: add USB_QUIRK_RESET_RESUME for M-Audio 49
From: Jonathan Nieder @ 2012-11-25 21:21 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-pm, alsa-devel, David Banks, Olivier MATZ, Ralf Lang,
	Steffen Müller, stable
In-Reply-To: <50B2815E.2090105@droids-corp.org>

Some USB MIDI keyboards fail to operate after a USB autosuspend.  The
device is recognized by ALSA, but no events are received and the
device goes quiet.

	$ amidi -l
	Dir Device    Name
	IO  hw:1,0,0  Oxygen 49 MIDI 1
	$ amidi -p hw:1,0,0 -d
	<... play some notes ...>
	^C
	0 bytes read

A workaround is to disable USB autosuspend for these devices by
putting AUTOSUSPEND_USBID_BLACKLIST="0763:2027" (resp. 0763:019b) in
/etc/laptop-mode/conf.d/usb-autosuspend.conf.  In the spirit of commit
166cb70e97bd ("usb: add USB_QUIRK_RESET_RESUME for M-Audio 88es"),
reset the device on resume so this workaround is not needed any more.

Noticed on a kernel close to 3.2.10.  Tested against 3.6.5.  Debian's
2.6.32.54-based kernel did not seem to be affected, though it's not
clear whether that is due to code or configuration.

Addresses http://bugs.debian.org/664068

Reported-and-tested-by: David Banks <amoebae@gmail.com> # Oxygen 49
Reported-and-tested-by: Olivier MATZ <zer0@droids-corp.org> # KeyRig 49
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Cc: stable@vger.kernel.org
---
Thoughts?

 drivers/usb/core/quirks.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index fdefd9c7f7af..998c6a8290f6 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -105,6 +105,12 @@ static const struct usb_device_id usb_quirk_list[] = {
 	/* Midiman M-Audio Keystation 88es */
 	{ USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* Midiman M-Audio KeyRig 49 */
+	{ USB_DEVICE(0x0763, 0x019b), .driver_info = USB_QUIRK_RESET_RESUME },
+
+	/* Midiman M-Audio Oxygen 49 */
+	{ USB_DEVICE(0x0763, 0x2027), .driver_info = USB_QUIRK_RESET_RESUME },
+
 	/* M-Systems Flash Disk Pioneers */
 	{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
 
-- 
1.8.0

^ permalink raw reply related

* Re: [PATCH 2/2] platform / ACPI: Attach/detach ACPI PM during probe/remove/shutdown
From: Rafael J. Wysocki @ 2012-11-25 19:57 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, Linux PM list, ACPI Devel Maling List, Zhang Rui,
	Svahn, Kai, Mika Westerberg, Huang Ying, Lan, Tianyu, Zheng, Lv,
	Aaron Lu, Grant Likely
In-Reply-To: <20121125184225.GA1423@kroah.com>

On Sunday, November 25, 2012 10:42:25 AM Greg Kroah-Hartman wrote:
> On Sun, Nov 25, 2012 at 03:58:14PM +0100, Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > 
> > Drivers usually expect that the devices they are supposed to handle
> > will be operational when their .probe() routines are called, but that
> > need not be the case on some ACPI-based systems with ACPI-based
> > device enumeration where the BIOSes don't put devices into D0 by
> > default.  To work around this problem it is sufficient to change
> > bus type .probe() routines to ensure that devices will be powered
> > on before the drivers' .probe() routines run (and their .remove()
> > and .shutdown() routines accordingly).
> > 
> > Modify platform_drv_probe() to run acpi_dev_pm_attach() for devices
> > whose ACPI handles are present, so that ACPI power management is used
> > to change their power states and change their power states to D0
> > before driver probing.  Analogously, modify platform_drv_remove() and
> > platform_drv_shutdown() to call acpi_dev_pm_detach() for those
> > devices, so that they are not subject to ACPI PM any more.
> > 
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Thanks!


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: [PATCH 2/2] platform / ACPI: Attach/detach ACPI PM during probe/remove/shutdown
From: Greg Kroah-Hartman @ 2012-11-25 18:42 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: LKML, Linux PM list, ACPI Devel Maling List, Zhang Rui,
	Svahn, Kai, Mika Westerberg, Huang Ying, Lan, Tianyu, Zheng, Lv,
	Aaron Lu, Grant Likely
In-Reply-To: <6227446.8xPtqi6yHi@vostro.rjw.lan>

On Sun, Nov 25, 2012 at 03:58:14PM +0100, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Drivers usually expect that the devices they are supposed to handle
> will be operational when their .probe() routines are called, but that
> need not be the case on some ACPI-based systems with ACPI-based
> device enumeration where the BIOSes don't put devices into D0 by
> default.  To work around this problem it is sufficient to change
> bus type .probe() routines to ensure that devices will be powered
> on before the drivers' .probe() routines run (and their .remove()
> and .shutdown() routines accordingly).
> 
> Modify platform_drv_probe() to run acpi_dev_pm_attach() for devices
> whose ACPI handles are present, so that ACPI power management is used
> to change their power states and change their power states to D0
> before driver probing.  Analogously, modify platform_drv_remove() and
> platform_drv_shutdown() to call acpi_dev_pm_detach() for those
> devices, so that they are not subject to ACPI PM any more.
> 
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply

* [PATCH 2/2] platform / ACPI: Attach/detach ACPI PM during probe/remove/shutdown
From: Rafael J. Wysocki @ 2012-11-25 14:58 UTC (permalink / raw)
  To: LKML
  Cc: Greg Kroah-Hartman, Linux PM list, ACPI Devel Maling List,
	Zhang Rui, Svahn, Kai, Mika Westerberg, Huang Ying, Lan, Tianyu,
	Zheng, Lv, Aaron Lu, Grant Likely
In-Reply-To: <1672179.qgDUs0YdYu@vostro.rjw.lan>

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Drivers usually expect that the devices they are supposed to handle
will be operational when their .probe() routines are called, but that
need not be the case on some ACPI-based systems with ACPI-based
device enumeration where the BIOSes don't put devices into D0 by
default.  To work around this problem it is sufficient to change
bus type .probe() routines to ensure that devices will be powered
on before the drivers' .probe() routines run (and their .remove()
and .shutdown() routines accordingly).

Modify platform_drv_probe() to run acpi_dev_pm_attach() for devices
whose ACPI handles are present, so that ACPI power management is used
to change their power states and change their power states to D0
before driver probing.  Analogously, modify platform_drv_remove() and
platform_drv_shutdown() to call acpi_dev_pm_detach() for those
devices, so that they are not subject to ACPI PM any more.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/base/platform.c |   19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

Index: linux/drivers/base/platform.c
===================================================================
--- linux.orig/drivers/base/platform.c
+++ linux/drivers/base/platform.c
@@ -484,8 +484,16 @@ static int platform_drv_probe(struct dev
 {
 	struct platform_driver *drv = to_platform_driver(_dev->driver);
 	struct platform_device *dev = to_platform_device(_dev);
+	int ret;
 
-	return drv->probe(dev);
+	if (ACPI_HANDLE(_dev))
+		acpi_dev_pm_attach(_dev, true);
+
+	ret = drv->probe(dev);
+	if (ret && ACPI_HANDLE(_dev))
+		acpi_dev_pm_detach(_dev, true);
+
+	return ret;
 }
 
 static int platform_drv_probe_fail(struct device *_dev)
@@ -497,8 +505,13 @@ static int platform_drv_remove(struct de
 {
 	struct platform_driver *drv = to_platform_driver(_dev->driver);
 	struct platform_device *dev = to_platform_device(_dev);
+	int ret;
+
+	ret = drv->remove(dev);
+	if (ACPI_HANDLE(_dev))
+		acpi_dev_pm_detach(_dev, true);
 
-	return drv->remove(dev);
+	return ret;
 }
 
 static void platform_drv_shutdown(struct device *_dev)
@@ -507,6 +520,8 @@ static void platform_drv_shutdown(struct
 	struct platform_device *dev = to_platform_device(_dev);
 
 	drv->shutdown(dev);
+	if (ACPI_HANDLE(_dev))
+		acpi_dev_pm_detach(_dev, true);
 }
 
 /**


^ permalink raw reply

* [PATCH 1/2] ACPI / PM: Allow attach/detach routines to change device power states
From: Rafael J. Wysocki @ 2012-11-25 14:55 UTC (permalink / raw)
  To: LKML
  Cc: Greg Kroah-Hartman, Linux PM list, ACPI Devel Maling List,
	Zhang Rui, Svahn, Kai, Mika Westerberg, Huang Ying, Lan, Tianyu,
	Zheng, Lv, Aaron Lu, Grant Likely
In-Reply-To: <1672179.qgDUs0YdYu@vostro.rjw.lan>

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Make it possible to ask the routines used for adding/removing devices
to/from the general ACPI PM domain, acpi_dev_pm_attach() and
acpi_dev_pm_detach(), respectively, to change the power states of
devices so that they are put into the full-power state automatically
by acpi_dev_pm_attach() and into the lowest-power state available
automatically by acpi_dev_pm_detach().

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/device_pm.c |   28 ++++++++++++++++++++++++----
 include/linux/acpi.h     |   11 +++++++----
 2 files changed, 31 insertions(+), 8 deletions(-)

Index: linux/drivers/acpi/device_pm.c
===================================================================
--- linux.orig/drivers/acpi/device_pm.c
+++ linux/drivers/acpi/device_pm.c
@@ -599,10 +599,12 @@ static struct dev_pm_domain acpi_general
 /**
  * acpi_dev_pm_attach - Prepare device for ACPI power management.
  * @dev: Device to prepare.
+ * @power_on: Whether or not to power on the device.
  *
  * If @dev has a valid ACPI handle that has a valid struct acpi_device object
  * attached to it, install a wakeup notification handler for the device and
- * add it to the general ACPI PM domain.
+ * add it to the general ACPI PM domain.  If @power_on is set, the device will
+ * be put into the ACPI D0 state before the function returns.
  *
  * This assumes that the @dev's bus type uses generic power management callbacks
  * (or doesn't use any power management callbacks at all).
@@ -610,7 +612,7 @@ static struct dev_pm_domain acpi_general
  * Callers must ensure proper synchronization of this function with power
  * management callbacks.
  */
-int acpi_dev_pm_attach(struct device *dev)
+int acpi_dev_pm_attach(struct device *dev, bool power_on)
 {
 	struct acpi_device *adev = acpi_dev_pm_get_node(dev);
 
@@ -622,6 +624,10 @@ int acpi_dev_pm_attach(struct device *de
 
 	acpi_add_pm_notifier(adev, acpi_wakeup_device, dev);
 	dev->pm_domain = &acpi_general_pm_domain;
+	if (power_on) {
+		acpi_dev_pm_full_power(adev);
+		__acpi_device_run_wake(adev, false);
+	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
@@ -629,20 +635,34 @@ EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
 /**
  * acpi_dev_pm_detach - Remove ACPI power management from the device.
  * @dev: Device to take care of.
+ * @power_off: Whether or not to try to remove power from the device.
  *
  * Remove the device from the general ACPI PM domain and remove its wakeup
- * notifier.
+ * notifier.  If @power_off is set, additionally remove power from the device if
+ * possible.
  *
  * Callers must ensure proper synchronization of this function with power
  * management callbacks.
  */
-void acpi_dev_pm_detach(struct device *dev)
+void acpi_dev_pm_detach(struct device *dev, bool power_off)
 {
 	struct acpi_device *adev = acpi_dev_pm_get_node(dev);
 
 	if (adev && dev->pm_domain == &acpi_general_pm_domain) {
 		dev->pm_domain = NULL;
 		acpi_remove_pm_notifier(adev, acpi_wakeup_device);
+		if (power_off) {
+			/*
+			 * If the device's PM QoS resume latency limit or flags
+			 * have been exposed to user space, they have to be
+			 * hidden at this point, so that they don't affect the
+			 * choice of the low-power state to put the device into.
+			 */
+			dev_pm_qos_hide_latency_limit(dev);
+			dev_pm_qos_hide_flags(dev);
+			__acpi_device_run_wake(adev, false);
+			acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
+		}
 	}
 }
 EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
Index: linux/include/linux/acpi.h
===================================================================
--- linux.orig/include/linux/acpi.h
+++ linux/include/linux/acpi.h
@@ -510,11 +510,14 @@ static inline int acpi_subsys_resume_ear
 #endif
 
 #if defined(CONFIG_ACPI) && defined(CONFIG_PM)
-int acpi_dev_pm_attach(struct device *dev);
-int acpi_dev_pm_detach(struct device *dev);
+int acpi_dev_pm_attach(struct device *dev, bool power_on);
+int acpi_dev_pm_detach(struct device *dev, bool power_off);
 #else
-static inline int acpi_dev_pm_attach(struct device *dev) { return -ENODEV; }
-static inline void acpi_dev_pm_detach(struct device *dev) {}
+static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
+{
+	return -ENODEV;
+}
+static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
 #endif
 
 #ifdef CONFIG_ACPI


^ permalink raw reply

* [PATCH 0/2] ACPI / platform: Put devices enumerated via ACPI into D0 before probing drivers
From: Rafael J. Wysocki @ 2012-11-25 14:54 UTC (permalink / raw)
  To: LKML
  Cc: Greg Kroah-Hartman, Linux PM list, ACPI Devel Maling List,
	Zhang Rui, Svahn, Kai, Mika Westerberg, Huang Ying, Lan, Tianyu,
	Zheng, Lv, Aaron Lu, Grant Likely

Hi All,

The following two patches are meant to work around a problem where some
devices may be in the ACPI D3cold power state (power off) before their
drivers' .probe() routines are called, but those routines assume devices
to be operational.  They also allow ACPI PM to be used going forward with
the devices in question.

[1/2] - Allow ACPI PM attach/detach routines to change device power states.
[2/2] - Call the ACPI PM attach/detach routines in the platform probe and
        remove/shutdown callbacks (and change power states of devices as
        necessary).

The patches are on top of the current linux-next branch of the linux-pm.git
tree.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: [PATCH 1/2] thermal: rcar: add rcar_zone_to_priv() macro
From: Zhang Rui @ 2012-11-25  9:24 UTC (permalink / raw)
  To: Kuninori Morimoto; +Cc: Simon, Magnus, linux-pm
In-Reply-To: <87r4nmuo66.wl%kuninori.morimoto.gx@renesas.com>

On Wed, 2012-11-21 at 22:50 -0800, Kuninori Morimoto wrote:
> This patch adds rcar_zone_to_priv()
> which is a helper macro for gettign private data.
> 
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Patch rebased on thermal next.

>From 5d251a94e56673b4fd22451c068a7a410cd6c687 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Wed, 21 Nov 2012 22:50:12 -0800
Subject: [PATCH] thermal: rcar: add rcar_zone_to_priv() macro

This patch adds rcar_zone_to_priv()
which is a helper macro for gettign private data.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/thermal/rcar_thermal.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index 81dce23..b8e6ffc 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -43,6 +43,8 @@ struct rcar_thermal_priv {
 	u32 comp;
 };
 
+#define rcar_zone_to_priv(zone)		(zone->devdata)
+
 /*
  *		basic functions
  */
@@ -96,7 +98,7 @@ static void rcar_thermal_bset(struct rcar_thermal_priv *priv, u32 reg,
 static int rcar_thermal_get_temp(struct thermal_zone_device *zone,
 			   unsigned long *temp)
 {
-	struct rcar_thermal_priv *priv = zone->devdata;
+	struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
 	int val, min, max, tmp;
 
 	tmp = -200; /* default */
-- 
1.7.7.6




^ permalink raw reply related

* Re: [PATCH v5] Thermal: exynos: Add sysfs node supporting exynos's emulation mode.
From: Zhang Rui @ 2012-11-25  9:17 UTC (permalink / raw)
  To: Jonghwa Lee
  Cc: linux-pm, linux-kernel, Len Brown, Durgadoss R, Rafael J. Wysocki,
	Amit Dinel Kachhap, MyungJoo Ham, Kyungmin Park
In-Reply-To: <1353472261-17430-1-git-send-email-jonghwa3.lee@samsung.com>

On Wed, 2012-11-21 at 13:31 +0900, Jonghwa Lee wrote:
> This patch supports exynos's emulation mode with newly created sysfs node.
> Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal
> management unit. Thermal emulation mode supports software debug for TMU's
> operation. User can set temperature manually with software code and TMU
> will read current temperature from user value not from sensor's value.
> This patch includes also documentary placed under Documentation/thermal/.
> 
> Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
output of checkpatch.pl:
 
ERROR: trailing whitespace
#162: FILE: Documentation/thermal/exynos_thermal_emulation:27:
+want to update the any value of delay or next temperature, then you
have to enable emulation $

ERROR: space required after that ';' (ctx:VxV)
#319: FILE: drivers/thermal/exynos_thermal.c:927:
+static inline int create_emulation_sysfs(struct device *dev) {return
0;}
                                                                       ^

ERROR: space required before the open brace '{'
#320: FILE: drivers/thermal/exynos_thermal.c:928:
+static inline void remove_emulation_sysfs(struct device *dev){}

total: 3 errors, 0 warnings, 198 lines checked

NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch
or
      scripts/cleanfile

/home/rzhang1/1-sysfs.mbox has style problems, please review.

If any of these errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.



output of git am:

git am 0001-Thermal-exynos-Add-sysfs-node-supporting-exynos-s-em.patch
Applying: Thermal: exynos: Add sysfs node supporting exynos's emulation
mode.
/home/rzhang1/src/thermal/.git/rebase-apply/patch:58: space before tab
in indent.
   	    |		   |	     	 |          |
/home/rzhang1/src/thermal/.git/rebase-apply/patch:61: space before tab
in indent.
  	  0 |______________|_____________|__________|__________|_________
/home/rzhang1/src/thermal/.git/rebase-apply/patch:67: new blank line at
EOF.
+
warning: 3 lines add whitespace errors.

Refreshed patch with these warnings fixed attached.

>From 3d80d1134a9b228cde7a55c5f9fa273dbbae7f50 Mon Sep 17 00:00:00 2001
From: Jonghwa Lee <jonghwa3.lee@samsung.com>
Date: Wed, 21 Nov 2012 13:31:01 +0900
Subject: [PATCH] Thermal: exynos: Add sysfs node supporting exynos's
 emulation mode.

This patch supports exynos's emulation mode with newly created sysfs node.
Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal
management unit. Thermal emulation mode supports software debug for TMU's
operation. User can set temperature manually with software code and TMU
will read current temperature from user value not from sensor's value.
This patch includes also documentary placed under Documentation/thermal/.

Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 Documentation/thermal/exynos_thermal_emulation |   53 ++++++++++++
 drivers/thermal/Kconfig                        |    9 ++
 drivers/thermal/exynos_thermal.c               |  103 ++++++++++++++++++++++++
 3 files changed, 165 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/thermal/exynos_thermal_emulation

diff --git a/Documentation/thermal/exynos_thermal_emulation b/Documentation/thermal/exynos_thermal_emulation
new file mode 100644
index 0000000..b73bbfb
--- /dev/null
+++ b/Documentation/thermal/exynos_thermal_emulation
@@ -0,0 +1,53 @@
+EXYNOS EMULATION MODE
+========================
+
+Copyright (C) 2012 Samsung Electronics
+
+Written by Jonghwa Lee <jonghwa3.lee@samsung.com>
+
+Description
+-----------
+
+Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal management unit.
+Thermal emulation mode supports software debug for TMU's operation. User can set temperature
+manually with software code and TMU will read current temperature from user value not from
+sensor's value.
+
+Enabling CONFIG_EXYNOS_THERMAL_EMUL option will make this support in available.
+When it's enabled, sysfs node will be created under
+/sys/bus/platform/devices/'exynos device name'/ with name of 'emulation'.
+
+The sysfs node, 'emulation', will contain value 0 for the initial state. When you input any
+temperature you want to update to sysfs node, it automatically enable emulation mode and
+current temperature will be changed into it.
+(Exynos also supports user changable delay time which would be used to delay of
+ changing temperature. However, this node only uses same delay of real sensing time, 938us.)
+
+Exynos emulation mode requires synchronous of value changing and enabling. It means when you
+want to update the any value of delay or next temperature, then you have to enable emulation
+mode at the same time. (Or you have to keep the mode enabling.) If you don't, it fails to
+change the value to updated one and just use last succeessful value repeatedly. That's why
+this node gives users the right to change termerpature only. Just one interface makes it more
+simply to use.
+
+Disabling emulation mode only requires writing value 0 to sysfs node.
+
+
+TEMP	120 |
+	    |
+	100 |
+	    |
+	 80 |
+	    |		     	 	 +-----------
+	 60 |      		     	 |	    |
+	    |	           +-------------|          |
+	 40 |              |         	 |          |
+	    |		   |	     	 |          |
+	 20 |		   |	     	 |          +----------
+	    |	 	   |	     	 |          |          |
+	  0 |______________|_____________|__________|__________|_________
+		   A	    	 A	    A	   	       A     TIME
+		   |<----->|	 |<----->|  |<----->|	       |
+		   | 938us |  	 |	 |  |       |          |
+emulation    :  0  50	   |  	 70      |  20      |          0
+current temp :   sensor   50		 70         20	      sensor
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 8636fae..f11ae0d 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -101,6 +101,15 @@ config EXYNOS_THERMAL
 	  If you say yes here you get support for TMU (Thermal Managment
 	  Unit) on SAMSUNG EXYNOS series of SoC.
 
+config EXYNOS_THERMAL_EMUL
+	bool "EXYNOS TMU emulation mode support"
+	depends on EXYNOS_THERMAL
+	help
+	  Exynos 4412 and 4414 and 5 series has emulation mode on TMU.
+	  Enable this option will be make sysfs node in exynos thermal platform
+	  device directory to support emulation mode. With emulation mode sysfs
+	  node, you can manually input temperature to TMU for simulation purpose.
+
 config DB8500_THERMAL
 	bool "DB8500 thermal management"
 	depends on ARCH_U8500
diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
index 7772d16..e2ef8a3 100644
--- a/drivers/thermal/exynos_thermal.c
+++ b/drivers/thermal/exynos_thermal.c
@@ -99,6 +99,14 @@
 #define IDLE_INTERVAL 10000
 #define MCELSIUS	1000
 
+#ifdef CONFIG_EXYNOS_THERMAL_EMUL
+#define EXYNOS_EMUL_TIME	0x57F0
+#define EXYNOS_EMUL_TIME_SHIFT	16
+#define EXYNOS_EMUL_DATA_SHIFT	8
+#define EXYNOS_EMUL_DATA_MASK	0xFF
+#define EXYNOS_EMUL_ENABLE	0x1
+#endif /* CONFIG_EXYNOS_THERMAL_EMUL */
+
 /* CPU Zone information */
 #define PANIC_ZONE      4
 #define WARN_ZONE       3
@@ -832,6 +840,94 @@ static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
 	return (struct exynos_tmu_platform_data *)
 			platform_get_device_id(pdev)->driver_data;
 }
+
+#ifdef CONFIG_EXYNOS_THERMAL_EMUL
+static ssize_t exynos_tmu_emulation_show(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct platform_device *pdev = container_of(dev,
+					struct platform_device, dev);
+	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+	unsigned int reg;
+	u8 temp_code;
+	int temp = 0;
+
+	if (data->soc == SOC_ARCH_EXYNOS4210)
+		goto out;
+
+	mutex_lock(&data->lock);
+	clk_enable(data->clk);
+	reg = readl(data->base + EXYNOS_EMUL_CON);
+	clk_disable(data->clk);
+	mutex_unlock(&data->lock);
+
+	if (reg & EXYNOS_EMUL_ENABLE) {
+		reg >>= EXYNOS_EMUL_DATA_SHIFT;
+		temp_code = reg & EXYNOS_EMUL_DATA_MASK;
+		temp = code_to_temp(data, temp_code);
+	}
+out:
+	return sprintf(buf, "%d\n", temp * MCELSIUS);
+}
+
+static ssize_t exynos_tmu_emulation_store(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	struct platform_device *pdev = container_of(dev,
+					struct platform_device, dev);
+	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+	unsigned int reg;
+	int temp;
+
+	if (data->soc == SOC_ARCH_EXYNOS4210)
+		goto out;
+
+	if (!sscanf(buf, "%d\n", &temp) || temp < 0)
+		return -EINVAL;
+
+	mutex_lock(&data->lock);
+	clk_enable(data->clk);
+
+	reg = readl(data->base + EXYNOS_EMUL_CON);
+
+	if (temp) {
+		/* Both CELSIUS and MCELSIUS type are available for input */
+		if (temp > MCELSIUS)
+			temp /= MCELSIUS;
+
+		reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) |
+			(temp_to_code(data, (temp / MCELSIUS))
+			 << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE;
+	} else {
+		reg &= ~EXYNOS_EMUL_ENABLE;
+	}
+
+	writel(reg, data->base + EXYNOS_EMUL_CON);
+
+	clk_disable(data->clk);
+	mutex_unlock(&data->lock);
+
+out:
+	return count;
+}
+
+static DEVICE_ATTR(emulation, 0644, exynos_tmu_emulation_show,
+					exynos_tmu_emulation_store);
+static int create_emulation_sysfs(struct device *dev)
+{
+	return device_create_file(dev, &dev_attr_emulation);
+}
+static void remove_emulation_sysfs(struct device *dev)
+{
+	device_remove_file(dev, &dev_attr_emulation);
+}
+#else
+static inline int create_emulation_sysfs(struct device *dev) { return 0; }
+static inline void remove_emulation_sysfs(struct device *dev) {}
+#endif
+
 static int __devinit exynos_tmu_probe(struct platform_device *pdev)
 {
 	struct exynos_tmu_data *data;
@@ -930,6 +1026,11 @@ static int __devinit exynos_tmu_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "Failed to register thermal interface\n");
 		goto err_clk;
 	}
+
+	ret = create_emulation_sysfs(&pdev->dev);
+	if (ret)
+		dev_err(&pdev->dev, "Failed to create emulation mode sysfs node\n");
+
 	return 0;
 err_clk:
 	platform_set_drvdata(pdev, NULL);
@@ -941,6 +1042,8 @@ static int __devexit exynos_tmu_remove(struct platform_device *pdev)
 {
 	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 
+	remove_emulation_sysfs(&pdev->dev);
+
 	exynos_tmu_control(pdev, false);
 
 	exynos_unregister_thermal();
-- 
1.7.7.6




^ permalink raw reply related

* [PATCH v6 1/6] mm: teach mm by current context info to not do I/O during memory allocation
From: Ming Lei @ 2012-11-24 12:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: Alan Stern, Oliver Neukum, Minchan Kim, Greg Kroah-Hartman,
	Rafael J. Wysocki, Jens Axboe, David S. Miller, Andrew Morton,
	netdev, linux-usb, linux-pm, linux-mm, Ming Lei, Jiri Kosina,
	Mel Gorman, KAMEZAWA Hiroyuki, Michal Hocko, Ingo Molnar,
	Peter Zijlstra
In-Reply-To: <1353761958-12810-1-git-send-email-ming.lei@canonical.com>

This patch introduces PF_MEMALLOC_NOIO on process flag('flags' field of
'struct task_struct'), so that the flag can be set by one task
to avoid doing I/O inside memory allocation in the task's context.

The patch trys to solve one deadlock problem caused by block device,
and the problem may happen at least in the below situations:

- during block device runtime resume, if memory allocation with
GFP_KERNEL is called inside runtime resume callback of any one
of its ancestors(or the block device itself), the deadlock may be
triggered inside the memory allocation since it might not complete
until the block device becomes active and the involed page I/O finishes.
The situation is pointed out first by Alan Stern. It is not a good
approach to convert all GFP_KERNEL[1] in the path into GFP_NOIO because
several subsystems may be involved(for example, PCI, USB and SCSI may
be involved for usb mass stoarage device, network devices involved too
in the iSCSI case)

- during block device runtime suspend, because runtime resume need
to wait for completion of concurrent runtime suspend.

- during error handling of usb mass storage deivce, USB bus reset
will be put on the device, so there shouldn't have any
memory allocation with GFP_KERNEL during USB bus reset, otherwise
the deadlock similar with above may be triggered. Unfortunately, any
usb device may include one mass storage interface in theory, so it
requires all usb interface drivers to handle the situation. In fact,
most usb drivers don't know how to handle bus reset on the device
and don't provide .pre_set() and .post_reset() callback at all, so
USB core has to unbind and bind driver for these devices. So it
is still not practical to resort to GFP_NOIO for solving the problem.

Also the introduced solution can be used by block subsystem or block
drivers too, for example, set the PF_MEMALLOC_NOIO flag before doing
actual I/O transfer.

It is not a good idea to convert all these GFP_KERNEL in the
affected path into GFP_NOIO because these functions doing that may be
implemented as library and will be called in many other contexts.

In fact, memalloc_noio_flags() can convert some of current static GFP_NOIO
allocation into GFP_KERNEL back in other non-affected contexts, at least
almost all GFP_NOIO in USB subsystem can be converted into GFP_KERNEL
after applying the approach and make allocation with GFP_NOIO
only happen in runtime resume/bus reset/block I/O transfer contexts
generally.

[1], several GFP_KERNEL allocation examples in runtime resume path

- pci subsystem
acpi_os_allocate
	<-acpi_ut_allocate
		<-ACPI_ALLOCATE_ZEROED
			<-acpi_evaluate_object
				<-__acpi_bus_set_power
					<-acpi_bus_set_power
						<-acpi_pci_set_power_state
							<-platform_pci_set_power_state
								<-pci_platform_power_transition
									<-__pci_complete_power_transition
										<-pci_set_power_state
											<-pci_restore_standard_config
												<-pci_pm_runtime_resume
- usb subsystem
usb_get_status
	<-finish_port_resume
		<-usb_port_resume
			<-generic_resume
				<-usb_resume_device
					<-usb_resume_both
						<-usb_runtime_resume

- some individual usb drivers
usblp, uvc, gspca, most of dvb-usb-v2 media drivers, cpia2, az6007, ....

That is just what I have found.  Unfortunately, this allocation can
only be found by human being now, and there should be many not found
since any function in the resume path(call tree) may allocate memory
with GFP_KERNEL.

Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Oliver Neukum <oneukum@suse.de>
Cc: Jiri Kosina <jiri.kosina@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Signed-off-by: Minchan Kim <minchan@kernel.org>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
v6:
	- replace GFP_IO with __GFP_IO to fix compile failure

v5:
	- use inline instead of macro to define memalloc_noio_*
	- replace memalloc_noio() with memalloc_noio_flags() to
	make code neater
	- don't clear GFP_FS because no GFP_IO means
	that allocation won't enter device driver as pointed by
	Andrew Morton

v4:
	- fix comment
v3:
	- no change
v2:
        - remove changes on 'may_writepage' and 'may_swap' because that
          isn't related with the patchset, and can't introduce I/O in
          allocation path if GFP_IOFS is unset, so handing 'may_swap'
          and may_writepage on GFP_NOIO or GFP_NOFS  should be a
          mm internal thing, and let mm guys deal with that, :-).

          Looks clearing the two may_XXX flag only excludes dirty pages
	  	  and anon pages for relaiming, and the behaviour should be decided
          by GFP FLAG, IMO.

        - unset GFP_IOFS in try_to_free_pages() path since
          alloc_page_buffers()
          and dma_alloc_from_contiguous may drop into the path, as
          pointed by KAMEZAWA Hiroyuki
v1:
        - take Minchan's change to avoid the check in alloc_page hot
          path

        - change the helpers' style into save/restore as suggested by
          Alan Stern
---
 include/linux/sched.h |   22 ++++++++++++++++++++++
 mm/page_alloc.c       |    9 ++++++++-
 mm/vmscan.c           |    4 ++--
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 85d14e1..c9bb377 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -51,6 +51,7 @@ struct sched_param {
 #include <linux/cred.h>
 #include <linux/llist.h>
 #include <linux/uidgid.h>
+#include <linux/gfp.h>
 
 #include <asm/processor.h>
 
@@ -1810,6 +1811,7 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *
 #define PF_FROZEN	0x00010000	/* frozen for system suspend */
 #define PF_FSTRANS	0x00020000	/* inside a filesystem transaction */
 #define PF_KSWAPD	0x00040000	/* I am kswapd */
+#define PF_MEMALLOC_NOIO 0x00080000	/* Allocating memory without IO involved */
 #define PF_LESS_THROTTLE 0x00100000	/* Throttle me less: I clean memory */
 #define PF_KTHREAD	0x00200000	/* I am a kernel thread */
 #define PF_RANDOMIZE	0x00400000	/* randomize virtual address space */
@@ -1847,6 +1849,26 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *
 #define tsk_used_math(p) ((p)->flags & PF_USED_MATH)
 #define used_math() tsk_used_math(current)
 
+/* __GFP_IO isn't allowed if PF_MEMALLOC_NOIO is set in current->flags */
+static inline gfp_t memalloc_noio_flags(gfp_t flags)
+{
+	if (unlikely(current->flags & PF_MEMALLOC_NOIO))
+		flags &= ~__GFP_IO;
+	return flags;
+}
+
+static inline gfp_t memalloc_noio_save(void)
+{
+	gfp_t flags = current->flags & PF_MEMALLOC_NOIO;
+	current->flags |= PF_MEMALLOC_NOIO;
+	return flags;
+}
+
+static inline void memalloc_noio_restore(gfp_t flags)
+{
+	current->flags = (current->flags & ~PF_MEMALLOC_NOIO) | flags;
+}
+
 /*
  * task->jobctl flags
  */
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 4d077f0..4e485b1 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2644,10 +2644,17 @@ retry_cpuset:
 	page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, order,
 			zonelist, high_zoneidx, alloc_flags,
 			preferred_zone, migratetype);
-	if (unlikely(!page))
+	if (unlikely(!page)) {
+		/*
+		 * Runtime PM, block IO and its error handling path
+		 * can deadlock because I/O on the device might not
+		 * complete.
+		 */
+		gfp_mask = memalloc_noio_flags(gfp_mask);
 		page = __alloc_pages_slowpath(gfp_mask, order,
 				zonelist, high_zoneidx, nodemask,
 				preferred_zone, migratetype);
+	}
 
 	trace_mm_page_alloc(page, order, gfp_mask, migratetype);
 
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 9ca84e2..b1296c4 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2270,7 +2270,7 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
 {
 	unsigned long nr_reclaimed;
 	struct scan_control sc = {
-		.gfp_mask = gfp_mask,
+		.gfp_mask = (gfp_mask = memalloc_noio_flags(gfp_mask)),
 		.may_writepage = !laptop_mode,
 		.nr_to_reclaim = SWAP_CLUSTER_MAX,
 		.may_unmap = 1,
@@ -3277,7 +3277,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
 		.may_swap = 1,
 		.nr_to_reclaim = max_t(unsigned long, nr_pages,
 				       SWAP_CLUSTER_MAX),
-		.gfp_mask = gfp_mask,
+		.gfp_mask = (gfp_mask = memalloc_noio_flags(gfp_mask)),
 		.order = order,
 		.priority = ZONE_RECLAIM_PRIORITY,
 	};
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v6 6/6] USB: forbid memory allocation with I/O during bus reset
From: Ming Lei @ 2012-11-24 12:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: Alan Stern, Oliver Neukum, Minchan Kim, Greg Kroah-Hartman,
	Rafael J. Wysocki, Jens Axboe, David S. Miller, Andrew Morton,
	netdev, linux-usb, linux-pm, linux-mm, Ming Lei
In-Reply-To: <1353761958-12810-1-git-send-email-ming.lei@canonical.com>

If one storage interface or usb network interface(iSCSI case)
exists in current configuration, memory allocation with
GFP_KERNEL during usb_device_reset() might trigger I/O transfer
on the storage interface itself and cause deadlock because
the 'us->dev_mutex' is held in .pre_reset() and the storage
interface can't do I/O transfer when the reset is triggered
by other interface, or the error handling can't be completed
if the reset is triggered by the storage itself(error handling path).
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
v5:
        - use inline memalloc_noio_save()
v4:
	- mark current memalloc_noio for every usb device reset
---
 drivers/usb/core/hub.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 90accde..2d5cc1c 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -5040,6 +5040,7 @@ int usb_reset_device(struct usb_device *udev)
 {
 	int ret;
 	int i;
+	unsigned int noio_flag;
 	struct usb_host_config *config = udev->actconfig;
 
 	if (udev->state == USB_STATE_NOTATTACHED ||
@@ -5049,6 +5050,17 @@ int usb_reset_device(struct usb_device *udev)
 		return -EINVAL;
 	}
 
+	/*
+	 * Don't allocate memory with GFP_KERNEL in current
+	 * context to avoid possible deadlock if usb mass
+	 * storage interface or usbnet interface(iSCSI case)
+	 * is included in current configuration. The easist
+	 * approach is to do it for every device reset,
+	 * because the device 'memalloc_noio' flag may have
+	 * not been set before reseting the usb device.
+	 */
+	noio_flag = memalloc_noio_save();
+
 	/* Prevent autosuspend during the reset */
 	usb_autoresume_device(udev);
 
@@ -5093,6 +5105,7 @@ int usb_reset_device(struct usb_device *udev)
 	}
 
 	usb_autosuspend_device(udev);
+	memalloc_noio_restore(noio_flag);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(usb_reset_device);
-- 
1.7.9.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related

* [PATCH v6 5/6] PM / Runtime: force memory allocation with no I/O during Runtime PM callbcack
From: Ming Lei @ 2012-11-24 12:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: Alan Stern, Oliver Neukum, Minchan Kim, Greg Kroah-Hartman,
	Rafael J. Wysocki, Jens Axboe, David S. Miller, Andrew Morton,
	netdev, linux-usb, linux-pm, linux-mm, Ming Lei
In-Reply-To: <1353761958-12810-1-git-send-email-ming.lei@canonical.com>

This patch applies the introduced memalloc_noio_save() and
memalloc_noio_restore() to force memory allocation with no I/O
during runtime_resume/runtime_suspend callback on device with
the flag of 'memalloc_noio' set.

Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Oliver Neukum <oneukum@suse.de>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
v5:
	- use inline memalloc_noio_save()
v4:
	- runtime_suspend need this too because rpm_resume may wait for
	completion of concurrent runtime_suspend, so deadlock still may
	be triggered in runtime_suspend path.
---
 drivers/base/power/runtime.c |   32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 3e198a0..96d99ea 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -371,6 +371,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
 	int (*callback)(struct device *);
 	struct device *parent = NULL;
 	int retval;
+	unsigned int noio_flag;
 
 	trace_rpm_suspend(dev, rpmflags);
 
@@ -480,7 +481,20 @@ static int rpm_suspend(struct device *dev, int rpmflags)
 	if (!callback && dev->driver && dev->driver->pm)
 		callback = dev->driver->pm->runtime_suspend;
 
-	retval = rpm_callback(callback, dev);
+	/*
+	 * Deadlock might be caused if memory allocation with GFP_KERNEL
+	 * happens inside runtime_suspend callback of one block device's
+	 * ancestor or the block device itself. Network device might be
+	 * thought as part of iSCSI block device, so network device and
+	 * its ancestor should be marked as memalloc_noio.
+	 */
+	if (dev->power.memalloc_noio) {
+		noio_flag = memalloc_noio_save();
+		retval = rpm_callback(callback, dev);
+		memalloc_noio_restore(noio_flag);
+	} else {
+		retval = rpm_callback(callback, dev);
+	}
 	if (retval)
 		goto fail;
 
@@ -563,6 +577,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
 	int (*callback)(struct device *);
 	struct device *parent = NULL;
 	int retval = 0;
+	unsigned int noio_flag;
 
 	trace_rpm_resume(dev, rpmflags);
 
@@ -712,7 +727,20 @@ static int rpm_resume(struct device *dev, int rpmflags)
 	if (!callback && dev->driver && dev->driver->pm)
 		callback = dev->driver->pm->runtime_resume;
 
-	retval = rpm_callback(callback, dev);
+	/*
+	 * Deadlock might be caused if memory allocation with GFP_KERNEL
+	 * happens inside runtime_resume callback of one block device's
+	 * ancestor or the block device itself. Network device might be
+	 * thought as part of iSCSI block device, so network device and
+	 * its ancestor should be marked as memalloc_noio.
+	 */
+	if (dev->power.memalloc_noio) {
+		noio_flag = memalloc_noio_save();
+		retval = rpm_callback(callback, dev);
+		memalloc_noio_restore(noio_flag);
+	} else {
+		retval = rpm_callback(callback, dev);
+	}
 	if (retval) {
 		__update_runtime_status(dev, RPM_SUSPENDED);
 		pm_runtime_cancel_pending(dev);
-- 
1.7.9.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related

* [PATCH v6 4/6] net/core: apply pm_runtime_set_memalloc_noio on network devices
From: Ming Lei @ 2012-11-24 12:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: Alan Stern, Oliver Neukum, Minchan Kim, Greg Kroah-Hartman,
	Rafael J. Wysocki, Jens Axboe, David S. Miller, Andrew Morton,
	netdev, linux-usb, linux-pm, linux-mm, Ming Lei, Eric Dumazet,
	David Decotigny, Tom Herbert, Ingo Molnar
In-Reply-To: <1353761958-12810-1-git-send-email-ming.lei@canonical.com>

Deadlock might be caused by allocating memory with GFP_KERNEL in
runtime_resume and runtime_suspend callback of network devices in
iSCSI situation, so mark network devices and its ancestor as
'memalloc_noio' with the introduced pm_runtime_set_memalloc_noio().

Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: David Decotigny <david.decotigny@google.com>
Cc: Tom Herbert <therbert@google.com>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
v4:
	 - call pm_runtime_set_memalloc_noio(ddev, true) after
	   device_add
---
 net/core/net-sysfs.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index bcf02f6..a55d255 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -22,6 +22,7 @@
 #include <linux/vmalloc.h>
 #include <linux/export.h>
 #include <linux/jiffies.h>
+#include <linux/pm_runtime.h>
 #include <net/wext.h>
 
 #include "net-sysfs.h"
@@ -1386,6 +1387,8 @@ void netdev_unregister_kobject(struct net_device * net)
 
 	remove_queue_kobjects(net);
 
+	pm_runtime_set_memalloc_noio(dev, false);
+
 	device_del(dev);
 }
 
@@ -1421,6 +1424,8 @@ int netdev_register_kobject(struct net_device *net)
 		return error;
 	}
 
+	pm_runtime_set_memalloc_noio(dev, true);
+
 	return error;
 }
 
-- 
1.7.9.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related

* [PATCH v6 3/6] block/genhd.c: apply pm_runtime_set_memalloc_noio on block devices
From: Ming Lei @ 2012-11-24 12:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: Alan Stern, Oliver Neukum, Minchan Kim, Greg Kroah-Hartman,
	Rafael J. Wysocki, Jens Axboe, David S. Miller, Andrew Morton,
	netdev, linux-usb, linux-pm, linux-mm, Ming Lei
In-Reply-To: <1353761958-12810-1-git-send-email-ming.lei@canonical.com>

This patch applyes the introduced pm_runtime_set_memalloc_noio on
block device so that PM core will teach mm to not allocate memory with
GFP_IOFS when calling the runtime_resume and runtime_suspend callback
for block devices and its ancestors.

Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
v5:
	- fix code style and one typo
v4:
	- call pm_runtime_set_memalloc_noio(ddev, true) after device_add
---
 block/genhd.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/block/genhd.c b/block/genhd.c
index 9a289d7..1905966 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -18,6 +18,7 @@
 #include <linux/mutex.h>
 #include <linux/idr.h>
 #include <linux/log2.h>
+#include <linux/pm_runtime.h>
 
 #include "blk.h"
 
@@ -532,6 +533,14 @@ static void register_disk(struct gendisk *disk)
 			return;
 		}
 	}
+
+	/*
+	 * avoid probable deadlock caused by allocating memory with
+	 * GFP_KERNEL in runtime_resume callback of its all ancestor
+	 * devices
+	 */
+	pm_runtime_set_memalloc_noio(ddev, true);
+
 	disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
 	disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
 
@@ -661,6 +670,7 @@ void del_gendisk(struct gendisk *disk)
 	disk->driverfs_dev = NULL;
 	if (!sysfs_deprecated)
 		sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
+	pm_runtime_set_memalloc_noio(disk_to_dev(disk), false);
 	device_del(disk_to_dev(disk));
 }
 EXPORT_SYMBOL(del_gendisk);
-- 
1.7.9.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related

* [PATCH v6 2/6] PM / Runtime: introduce pm_runtime_set_memalloc_noio()
From: Ming Lei @ 2012-11-24 12:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: Alan Stern, Oliver Neukum, Minchan Kim, Greg Kroah-Hartman,
	Rafael J. Wysocki, Jens Axboe, David S. Miller, Andrew Morton,
	netdev, linux-usb, linux-pm, linux-mm, Ming Lei
In-Reply-To: <1353761958-12810-1-git-send-email-ming.lei@canonical.com>

The patch introduces the flag of memalloc_noio in 'struct dev_pm_info'
to help PM core to teach mm not allocating memory with GFP_KERNEL
flag for avoiding probable deadlock.

As explained in the comment, any GFP_KERNEL allocation inside
runtime_resume() or runtime_suspend() on any one of device in
the path from one block or network device to the root device
in the device tree may cause deadlock, the introduced
pm_runtime_set_memalloc_noio() sets or clears the flag on
device in the path recursively.

Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
v5:
	- fix code style error
	- add comment on clear the device memalloc_noio flag
v4:
	- rename memalloc_noio_resume as memalloc_noio
	- remove pm_runtime_get_memalloc_noio()
	- add comments on pm_runtime_set_memalloc_noio
v3:
	- introduce pm_runtime_get_memalloc_noio()
	- hold one global lock on pm_runtime_set_memalloc_noio
	- hold device power lock when accessing memalloc_noio_resume
	  flag suggested by Alan Stern
	- implement pm_runtime_set_memalloc_noio without recursion
	  suggested by Alan Stern
v2:
	- introduce pm_runtime_set_memalloc_noio()
---
 drivers/base/power/runtime.c |   60 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/pm.h           |    1 +
 include/linux/pm_runtime.h   |    3 +++
 3 files changed, 64 insertions(+)

diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 3148b10..3e198a0 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -124,6 +124,66 @@ unsigned long pm_runtime_autosuspend_expiration(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(pm_runtime_autosuspend_expiration);
 
+static int dev_memalloc_noio(struct device *dev, void *data)
+{
+	return dev->power.memalloc_noio;
+}
+
+/*
+ * pm_runtime_set_memalloc_noio - Set a device's memalloc_noio flag.
+ * @dev: Device to handle.
+ * @enable: True for setting the flag and False for clearing the flag.
+ *
+ * Set the flag for all devices in the path from the device to the
+ * root device in the device tree if @enable is true, otherwise clear
+ * the flag for devices in the path whose siblings don't set the flag.
+ *
+ * The function should only be called by block device, or network
+ * device driver for solving the deadlock problem during runtime
+ * resume/suspend:
+ *
+ *     If memory allocation with GFP_KERNEL is called inside runtime
+ *     resume/suspend callback of any one of its ancestors(or the
+ *     block device itself), the deadlock may be triggered inside the
+ *     memory allocation since it might not complete until the block
+ *     device becomes active and the involed page I/O finishes. The
+ *     situation is pointed out first by Alan Stern. Network device
+ *     are involved in iSCSI kind of situation.
+ *
+ * The lock of dev_hotplug_mutex is held in the function for handling
+ * hotplug race because pm_runtime_set_memalloc_noio() may be called
+ * in async probe().
+ *
+ * The function should be called between device_add() and device_del()
+ * on the affected device(block/network device).
+ */
+void pm_runtime_set_memalloc_noio(struct device *dev, bool enable)
+{
+	static DEFINE_MUTEX(dev_hotplug_mutex);
+
+	mutex_lock(&dev_hotplug_mutex);
+	for (;;) {
+		/* hold power lock since bitfield is not SMP-safe. */
+		spin_lock_irq(&dev->power.lock);
+		dev->power.memalloc_noio = enable;
+		spin_unlock_irq(&dev->power.lock);
+
+		dev = dev->parent;
+
+		/*
+		 * clear flag of the parent device only if all the
+		 * children don't set the flag because ancestor's
+		 * flag was set by any one of the descendants.
+		 */
+		if (!dev || (!enable &&
+			     device_for_each_child(dev, NULL,
+						   dev_memalloc_noio)))
+			break;
+	}
+	mutex_unlock(&dev_hotplug_mutex);
+}
+EXPORT_SYMBOL_GPL(pm_runtime_set_memalloc_noio);
+
 /**
  * rpm_check_suspend_allowed - Test whether a device may be suspended.
  * @dev: Device to test.
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 03d7bb1..1a8a69d 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -538,6 +538,7 @@ struct dev_pm_info {
 	unsigned int		irq_safe:1;
 	unsigned int		use_autosuspend:1;
 	unsigned int		timer_autosuspends:1;
+	unsigned int		memalloc_noio:1;
 	enum rpm_request	request;
 	enum rpm_status		runtime_status;
 	int			runtime_error;
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index f271860..775e063 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -47,6 +47,7 @@ extern void pm_runtime_set_autosuspend_delay(struct device *dev, int delay);
 extern unsigned long pm_runtime_autosuspend_expiration(struct device *dev);
 extern void pm_runtime_update_max_time_suspended(struct device *dev,
 						 s64 delta_ns);
+extern void pm_runtime_set_memalloc_noio(struct device *dev, bool enable);
 
 static inline bool pm_children_suspended(struct device *dev)
 {
@@ -149,6 +150,8 @@ static inline void pm_runtime_set_autosuspend_delay(struct device *dev,
 						int delay) {}
 static inline unsigned long pm_runtime_autosuspend_expiration(
 				struct device *dev) { return 0; }
+static inline void pm_runtime_set_memalloc_noio(struct device *dev,
+						bool enable){}
 
 #endif /* !CONFIG_PM_RUNTIME */
 
-- 
1.7.9.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related

* [PATCH v6 0/6] solve deadlock caused by memory allocation with I/O
From: Ming Lei @ 2012-11-24 12:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: Alan Stern, Oliver Neukum, Minchan Kim, Greg Kroah-Hartman,
	Rafael J. Wysocki, Jens Axboe, David S. Miller, Andrew Morton,
	netdev, linux-usb, linux-pm, linux-mm

Hi,

This patchset try to solve one deadlock problem which might be caused
by memory allocation with block I/O during runtime PM and block device
error handling path. Traditionly, the problem is addressed by passing
GFP_NOIO statically to mm, but that is not a effective solution, see
detailed description in patch 1's commit log.

This patch set introduces one process flag and trys to fix the deadlock
problem on block device/network device during runtime PM or usb bus reset.

The 1st one is the change on include/sched.h and mm.

The 2nd patch introduces the flag of memalloc_noio on 'dev_pm_info',
and pm_runtime_set_memalloc_noio(), so that PM Core can teach mm to not
allocate mm with GFP_IO during the runtime_resume callback only on
device with the flag set.

The following 2 patches apply the introduced pm_runtime_set_memalloc_noio()
to mark all devices as memalloc_noio_resume in the path from the block or
network device to the root device in device tree.

The last 2 patches are applied again PM and USB subsystem to demonstrate
how to use the introduced mechanism to fix the deadlock problem.

Andrew, could you queue these patches into your tree since V6 fixes all
your concerns and looks no one objects these patches?

Change logs:
V6:
	- fix one compile failure(1/6), and only one line change

V5:
        - don't clear GFP_FS
        - coding style fix
        - add comments
        - see details in individual change logs

V4:
        - patches from the 2nd to the 6th changed
        - call pm_runtime_set_memalloc_noio() after device_add() as pointed
        by Alan
        - set PF_MEMALLOC_NOIO during runtime_suspend()

V3:
        - patch 2/6 and 5/6 changed, see their commit log
        - remove RFC from title since several guys have expressed that
        it is a reasonable solution
V2:
        - remove changes on 'may_writepage' and 'may_swap'(1/6)
        - unset GFP_IOFS in try_to_free_pages() path(1/6)
        - introduce pm_runtime_set_memalloc_noio()
        - only apply the meachnism on block/network device and its ancestors
        for runtime resume context
V1:
        - take Minchan's change to avoid the check in alloc_page hot path
        - change the helpers' style into save/restore as suggested by Alan
        - memory allocation with no io in usb bus reset path for all devices
        as suggested by Greg and Oliver

 block/genhd.c                |   10 +++++
 drivers/base/power/runtime.c |   92 +++++++++++++++++++++++++++++++++++++++++-
 drivers/usb/core/hub.c       |   13 ++++++
 include/linux/pm.h           |    1 +
 include/linux/pm_runtime.h   |    3 ++
 include/linux/sched.h        |   22 ++++++++++
 mm/page_alloc.c              |    9 ++++-
 mm/vmscan.c                  |    4 +-
 net/core/net-sysfs.c         |    5 +++
 9 files changed, 154 insertions(+), 5 deletions(-)

Thanks,
--
Ming Lei

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH 3/6 v4] cpufreq: tolerate inexact values when collecting stats
From: Rafael J. Wysocki @ 2012-11-24 10:05 UTC (permalink / raw)
  To: Mark Langsdorf
  Cc: Borislav Petkov, linux-kernel@vger.kernel.org,
	cpufreq@vger.kernel.org, linux-pm@vger.kernel.org, MyungJoo Ham
In-Reply-To: <20121117145048.GI16441@x1.osrc.amd.com>

On Saturday, November 17, 2012 03:50:48 PM Borislav Petkov wrote:
> On Tue, Nov 13, 2012 at 02:13:38PM -0500, Mark Langsdorf wrote:
> > Although cpufreq_driver has a flag field, no part of cpufreq_driver
> > is directly passed to the cpufreq_stat code. Only cpufreq_policy
> > is. It's cleaner to do passes of the while loop than to copy the
> > cpufreq_driver.flag field into cpufreq_policy and then store it again
> > in cpufreq_stats.
> 
> That maybe so but this newly added loop which is only Calxeda-relevant
> is called in cpufreq_stat_notifier_trans, which is the frequency change
> notifier call, AFAICT.
> 
> So each cpufreq driver will be paying that small and needless penalty
> now for nothing and on each frequency change. Which adds to the
> kernel-wide bloat and we absolutely don't want that.
> 
> So you probably need to find a slick way of detecting calxeda hw
> somewhere along the init path of cpufreq_stats_init and set a
> hw-specific flag instead of adding that cost to each driver.

Mark, I suppose you'd like me to take this series for v3.8, but the above
comment from Boris has to be addressed for that.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: [PATCH 0/6 v4] cpufreq: add support for Calxeda ECX-1000 (highbank)
From: Rafael J. Wysocki @ 2012-11-24 10:07 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: linux-kernel, cpufreq, linux-pm
In-Reply-To: <1352313166-28980-1-git-send-email-mark.langsdorf@calxeda.com>

Hi Mark,

On Wednesday, November 07, 2012 12:32:40 PM Mark Langsdorf wrote:
> This patch series adds cpufreq support for the Calxeda
> ECX-1000 (highbank) SoCs. The driver is based on the 
> cpufreq-cpu0 driver. Because of the unique way that 
> highbank uses the EnergyCore Management Engine to manage
> voltages, it was not possible to use the cpufreq-cpu0 driver.

Please address the reviewers' comments for patches [3-4/6] and [6/6].

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* [PATCH] PM / QoS: Rename local variable in dev_pm_qos_add_ancestor_request()
From: Rafael J. Wysocki @ 2012-11-24  9:30 UTC (permalink / raw)
  To: Linux PM list; +Cc: LKML, ACPI Devel Maling List

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Local variable 'error' in dev_pm_qos_add_ancestor_request() need
not contain error codes only, so rename it to 'ret'.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/base/power/qos.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Index: linux/drivers/base/power/qos.c
===================================================================
--- linux.orig/drivers/base/power/qos.c
+++ linux/drivers/base/power/qos.c
@@ -542,19 +542,19 @@ int dev_pm_qos_add_ancestor_request(stru
 				    struct dev_pm_qos_request *req, s32 value)
 {
 	struct device *ancestor = dev->parent;
-	int error = -ENODEV;
+	int ret = -ENODEV;
 
 	while (ancestor && !ancestor->power.ignore_children)
 		ancestor = ancestor->parent;
 
 	if (ancestor)
-		error = dev_pm_qos_add_request(ancestor, req,
-					       DEV_PM_QOS_LATENCY, value);
+		ret = dev_pm_qos_add_request(ancestor, req,
+					     DEV_PM_QOS_LATENCY, value);
 
-	if (error < 0)
+	if (ret < 0)
 		req->dev = NULL;
 
-	return error;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request);
 


^ permalink raw reply

* Re: [PATCH] cpufreq: fix jiffies/cputime mixup in conservative/ondemand governors
From: Viresh Kumar @ 2012-11-24  4:28 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Andreas Schwab, cpufreq, linux-pm, Fabio Baltieri
In-Reply-To: <4686564.n70P6BrGFi@vostro.rjw.lan>

On 24 November 2012 03:18, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> Subject: cpufreq: governors: Fix jiffies/cputime mixup (revisited)
>
> This change was made by commit 8636fd2 (cpufreq: fix jiffies/cputime
> mixup in conservative/ondemand governors) before, but then it has
> been reverted inadvertently by commit 4471a34 (cpufreq: governors:
> remove redundant code).
>
> The changelog of commit 8636fd2 says:
>
>   The function get_cpu_idle_time_jiffy in both the conservative and
>   ondemand governors use jiffies_to_usecs to convert a cputime value
>   to usecs which gives the wrong value on architectures where cputime
>   and jiffies use different units.  Only matters if NO_HZ is
>   disabled, since otherwise get_cpu_idle_time_us should already
>   return a valid value, and get_cpu_idle_time_jiffy isn't actually
>   called.
>
> Since now we have only one common get_cpu_idle_time_jiffy() used by
> both governors in question, modify it along the lines of commit
> 8636fd2 to restore the correct behavior.
>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>

^ permalink raw reply

* [PATCH 16/24] MAINTAINERS: remove arch/x86/platform/mrst/pmu.*
From: Cesar Eduardo Barros @ 2012-11-24  0:26 UTC (permalink / raw)
  To: linux-kernel; +Cc: Cesar Eduardo Barros, Alan Cox, Len Brown, linux-pm
In-Reply-To: <1353716808-16375-1-git-send-email-cesarb@cesarb.net>

These files were removed by commit 1a8359e (x86/mid: Remove Intel
Moorestown).

Cc: Alan Cox <alan@linux.intel.com>
Cc: Len Brown <len.brown@intel.com>
Cc: linux-pm@vger.kernel.org
Signed-off-by: Cesar Eduardo Barros <cesarb@cesarb.net>
---
 MAINTAINERS | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3a09993..e7a2349 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3968,12 +3968,6 @@ F:	Documentation/networking/ixgbe.txt
 F:	Documentation/networking/ixgbevf.txt
 F:	drivers/net/ethernet/intel/
 
-INTEL MRST PMU DRIVER
-M:	Len Brown <len.brown@intel.com>
-L:	linux-pm@vger.kernel.org
-S:	Supported
-F:	arch/x86/platform/mrst/pmu.*
-
 INTEL PRO/WIRELESS 2100, 2200BG, 2915ABG NETWORK CONNECTION SUPPORT
 M:	Stanislav Yakovlev <stas.yakovlev@gmail.com>
 L:	linux-wireless@vger.kernel.org
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH] PM / QoS: Handle device PM QoS flags while removing constraints
From: Rafael J. Wysocki @ 2012-11-23 23:41 UTC (permalink / raw)
  To: Linux PM list; +Cc: LKML, ACPI Devel Maling List

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

PM QoS flags have to be handled by dev_pm_qos_constraints_destroy()
in the same way as PM QoS resume latency constraits.  That is, if
they have been exposed to user space, they have to be hidden from it
and the list of flags requests has to be flushed before destroying
the device's PM QoS object.  Make that happen.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/base/power/qos.c |   13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

Index: linux/drivers/base/power/qos.c
===================================================================
--- linux.orig/drivers/base/power/qos.c
+++ linux/drivers/base/power/qos.c
@@ -223,12 +223,14 @@ void dev_pm_qos_constraints_destroy(stru
 	struct dev_pm_qos *qos;
 	struct dev_pm_qos_request *req, *tmp;
 	struct pm_qos_constraints *c;
+	struct pm_qos_flags *f;
 
 	/*
-	 * If the device's PM QoS resume latency limit has been exposed to user
-	 * space, it has to be hidden at this point.
+	 * If the device's PM QoS resume latency limit or PM QoS flags have been
+	 * exposed to user space, they have to be hidden at this point.
 	 */
 	dev_pm_qos_hide_latency_limit(dev);
+	dev_pm_qos_hide_flags(dev);
 
 	mutex_lock(&dev_pm_qos_mtx);
 
@@ -237,8 +239,8 @@ void dev_pm_qos_constraints_destroy(stru
 	if (!qos)
 		goto out;
 
+	/* Flush the constraints lists for the device. */
 	c = &qos->latency;
-	/* Flush the constraints list for the device */
 	plist_for_each_entry_safe(req, tmp, &c->list, data.pnode) {
 		/*
 		 * Update constraints list and call the notification
@@ -247,6 +249,11 @@ void dev_pm_qos_constraints_destroy(stru
 		apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
 		memset(req, 0, sizeof(*req));
 	}
+	f = &qos->flags;
+	list_for_each_entry_safe(req, tmp, &f->list, data.flr.node) {
+		apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
+		memset(req, 0, sizeof(*req));
+	}
 
 	spin_lock_irq(&dev->power.lock);
 	dev->power.qos = NULL;


^ permalink raw reply

* Re: [PATCH] cpufreq: fix jiffies/cputime mixup in conservative/ondemand governors
From: Rafael J. Wysocki @ 2012-11-23 21:48 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: cpufreq, linux-pm, Fabio Baltieri, Viresh Kumar
In-Reply-To: <6739224.35DjQmzyyR@vostro.rjw.lan>

On Friday, October 26, 2012 11:10:10 PM Rafael J. Wysocki wrote:
> On Friday, October 26, 2012 02:26:34 PM Andreas Schwab wrote:
> > "Rafael J. Wysocki" <rjw@sisk.pl> writes:
> > 
> > > http://git.kernel.org/?p=linux/kernel/git/rafael/linux-pm.git;a=shortlog;h=refs/heads/linux-next
> > 
> > 91f347c looks good, unfortunately d7d6f64 undoes the change.
> 
> I didn't notice that, sorry.  Thanks for the heads up.

So, I'm going to apply the following patch to fix this again.

Thanks,
Rafael


---
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Subject: cpufreq: governors: Fix jiffies/cputime mixup (revisited)

This change was made by commit 8636fd2 (cpufreq: fix jiffies/cputime
mixup in conservative/ondemand governors) before, but then it has
been reverted inadvertently by commit 4471a34 (cpufreq: governors:
remove redundant code).

The changelog of commit 8636fd2 says:

  The function get_cpu_idle_time_jiffy in both the conservative and
  ondemand governors use jiffies_to_usecs to convert a cputime value
  to usecs which gives the wrong value on architectures where cputime
  and jiffies use different units.  Only matters if NO_HZ is
  disabled, since otherwise get_cpu_idle_time_us should already
  return a valid value, and get_cpu_idle_time_jiffy isn't actually
  called.

Since now we have only one common get_cpu_idle_time_jiffy() used by
both governors in question, modify it along the lines of commit
8636fd2 to restore the correct behavior.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/cpufreq_governor.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: linux/drivers/cpufreq/cpufreq_governor.c
===================================================================
--- linux.orig/drivers/cpufreq/cpufreq_governor.c
+++ linux/drivers/cpufreq/cpufreq_governor.c
@@ -45,9 +45,9 @@ static inline u64 get_cpu_idle_time_jiff
 
 	idle_time = cur_wall_time - busy_time;
 	if (wall)
-		*wall = jiffies_to_usecs(cur_wall_time);
+		*wall = cputime_to_usecs(cur_wall_time);
 
-	return jiffies_to_usecs(idle_time);
+	return cputime_to_usecs(idle_time);
 }
 
 u64 get_cpu_idle_time(unsigned int cpu, u64 *wall)


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* [GIT PULL] Power management fix for v3.7-rc7
From: Rafael J. Wysocki @ 2012-11-23 21:30 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: LKML, Linux PM list

Hi Linus,

Please pull from the git repository at

  git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git pm-for-3.7-rc7

to receive one power management fix for v3.7-rc7 as commit
a7227a0faa117d0bc532aea546ae5ac5f89e8ed7

  PM / QoS: fix wrong error-checking condition

on top of commit f4a75d2eb7b1e2206094b901be09adb31ba63681

  Linux 3.7-rc6

It fixes a bug that has been there for quite a while, but it's a potential
Oops and the fix is -stable material.

Thanks!


 drivers/base/power/qos.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

---------------

Guennadi Liakhovetski (1):
      PM / QoS: fix wrong error-checking condition


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: [PATCH 3.7+stable] pm: fix wrong error-checking condition
From: Rafael J. Wysocki @ 2012-11-23 20:36 UTC (permalink / raw)
  To: Guennadi Liakhovetski; +Cc: linux-pm
In-Reply-To: <Pine.LNX.4.64.1211231601040.14984@axis700.grange>

On Friday, November 23, 2012 04:02:56 PM Guennadi Liakhovetski wrote:
> dev_pm_qos_add_request() can return 0, 1, or a negative error code,
> therefore the correct error test is "if (error < 0)." Checking just for
> non-zero return code leads to erroneous setting of the req->dev pointer
> to NULL, which then leads to a repeated call to
> dev_pm_qos_add_ancestor_request() in st1232_ts_irq_handler(). This in turn
> leads to an Oops, when the I2C host adapter is unloaded and reloaded again
> because of the inconsistent state of its QoS request list.
> 
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> ---
> 
> Hi Rafael, please push to 3.7 and to stable.

I will, thanks for the fix!

Rafael


>  drivers/base/power/qos.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
> index 74a67e0..fbbd4ed 100644
> --- a/drivers/base/power/qos.c
> +++ b/drivers/base/power/qos.c
> @@ -451,7 +451,7 @@ int dev_pm_qos_add_ancestor_request(struct device *dev,
>  	if (ancestor)
>  		error = dev_pm_qos_add_request(ancestor, req, value);
>  
> -	if (error)
> +	if (error < 0)
>  		req->dev = NULL;
>  
>  	return error;
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox