* [PATCH 1/7 v2] fix memory leak when memory device is unbound from the module acpi_memhotplug
2012-07-11 7:45 [PATCH 0/7 v2] some fixes about acpi_memhotplug Wen Congyang
@ 2012-07-11 7:47 ` Wen Congyang
2012-07-11 21:55 ` Andrew Morton
2012-07-11 7:47 ` [PATCH 2/7 v2] free memory device if acpi_memory_enable_device() failed Wen Congyang
` (5 subsequent siblings)
6 siblings, 1 reply; 9+ messages in thread
From: Wen Congyang @ 2012-07-11 7:47 UTC (permalink / raw)
To: lenb, linux-acpi, linux-kernel@vger.kernel.org
Cc: Yasuaki ISIMATU, David Rientjes, Andrew Morton,
Konrad Rzeszutek Wilk
We allocate memory to store acpi_memory_info, so we should free it before
freeing mem_device.
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
drivers/acpi/acpi_memhotplug.c | 31 +++++++++++++++++++++----------
1 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index d985713..fe699ec 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -125,12 +125,20 @@ acpi_memory_get_resource(struct acpi_resource *resource, void *context)
return AE_OK;
}
+static void
+acpi_memory_free_device_resources(struct acpi_memory_device *mem_device)
+{
+ struct acpi_memory_info *info, *n;
+
+ list_for_each_entry_safe(info, n, &mem_device->res_list, list)
+ kfree(info);
+ INIT_LIST_HEAD(&mem_device->res_list);
+}
+
static int
acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
{
acpi_status status;
- struct acpi_memory_info *info, *n;
-
if (!list_empty(&mem_device->res_list))
return 0;
@@ -138,9 +146,7 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS,
acpi_memory_get_resource, mem_device);
if (ACPI_FAILURE(status)) {
- list_for_each_entry_safe(info, n, &mem_device->res_list, list)
- kfree(info);
- INIT_LIST_HEAD(&mem_device->res_list);
+ acpi_memory_free_device_resources(mem_device);
return -EINVAL;
}
@@ -399,6 +405,15 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
return;
}
+static void acpi_memory_device_free(struct acpi_memory_device *mem_device)
+{
+ if (!mem_device)
+ return;
+
+ acpi_memory_free_device_resources(mem_device);
+ kfree(mem_device);
+}
+
static int acpi_memory_device_add(struct acpi_device *device)
{
int result;
@@ -451,14 +466,10 @@ static int acpi_memory_device_add(struct acpi_device *device)
static int acpi_memory_device_remove(struct acpi_device *device, int type)
{
- struct acpi_memory_device *mem_device = NULL;
-
-
if (!device || !acpi_driver_data(device))
return -EINVAL;
- mem_device = acpi_driver_data(device);
- kfree(mem_device);
+ acpi_memory_device_free(acpi_driver_data(device));
return 0;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/7 v2] fix memory leak when memory device is unbound from the module acpi_memhotplug
2012-07-11 7:47 ` [PATCH 1/7 v2] fix memory leak when memory device is unbound from the module acpi_memhotplug Wen Congyang
@ 2012-07-11 21:55 ` Andrew Morton
0 siblings, 0 replies; 9+ messages in thread
From: Andrew Morton @ 2012-07-11 21:55 UTC (permalink / raw)
To: Wen Congyang
Cc: lenb, linux-acpi, linux-kernel@vger.kernel.org, Yasuaki ISIMATU,
David Rientjes, Konrad Rzeszutek Wilk, Brown, Len
On Wed, 11 Jul 2012 15:47:02 +0800
Wen Congyang <wency@cn.fujitsu.com> wrote:
> To: lenb@kernel.org
I'm still not sure if that email address works? I've been cc'ing
len.brown@intel.com lately as well.
There are some pretty serious-looking bugfixes in this series.
I merged your patches into my tree to get them a bit of testing.
Please note that I renamed them all so their titles reflect the
subsystem which they are patching. Documentation/SubmittingPatches
section 15 goes into details on this convention.
Having done that rename, it becomes obvious that patches 1-6 are acpi
memhotplug changes, but the seventh patch is a fix against core MM
code. I've sent that patch to Linus earlier today.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/7 v2] free memory device if acpi_memory_enable_device() failed
2012-07-11 7:45 [PATCH 0/7 v2] some fixes about acpi_memhotplug Wen Congyang
2012-07-11 7:47 ` [PATCH 1/7 v2] fix memory leak when memory device is unbound from the module acpi_memhotplug Wen Congyang
@ 2012-07-11 7:47 ` Wen Congyang
2012-07-11 7:48 ` [PATCH 3/7 v2] remove memory info from list before freeing it Wen Congyang
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Wen Congyang @ 2012-07-11 7:47 UTC (permalink / raw)
To: lenb, linux-acpi, linux-kernel@vger.kernel.org
Cc: Yasuaki ISIMATU, David Rientjes, Andrew Morton,
Konrad Rzeszutek Wilk
If acpi_memory_enable_device() fails, acpi_memory_enable_device() will
return a non-zero value, which means we fail to bind the memory device
to this driver. So we should free memory device before acpi_memory_device_add()
returns.
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
drivers/acpi/acpi_memhotplug.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index fe699ec..260a9c4 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -457,9 +457,11 @@ static int acpi_memory_device_add(struct acpi_device *device)
if (!acpi_memory_check_device(mem_device)) {
/* call add_memory func */
result = acpi_memory_enable_device(mem_device);
- if (result)
+ if (result) {
printk(KERN_ERR PREFIX
"Error in acpi_memory_enable_device\n");
+ acpi_memory_device_free(mem_device);
+ }
}
return result;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/7 v2] remove memory info from list before freeing it
2012-07-11 7:45 [PATCH 0/7 v2] some fixes about acpi_memhotplug Wen Congyang
2012-07-11 7:47 ` [PATCH 1/7 v2] fix memory leak when memory device is unbound from the module acpi_memhotplug Wen Congyang
2012-07-11 7:47 ` [PATCH 2/7 v2] free memory device if acpi_memory_enable_device() failed Wen Congyang
@ 2012-07-11 7:48 ` Wen Congyang
2012-07-11 7:49 ` [PATCH 4/7 v2] don't allow to eject the memory device if it is being used Wen Congyang
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Wen Congyang @ 2012-07-11 7:48 UTC (permalink / raw)
To: lenb, linux-acpi, linux-kernel@vger.kernel.org
Cc: Yasuaki ISIMATU, David Rientjes, Andrew Morton,
Konrad Rzeszutek Wilk
We free info, but we forget to remove it from the list. It will cause
unexpected problem when we access the list next time.
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
drivers/acpi/acpi_memhotplug.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 260a9c4..1f6196a 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -328,6 +328,7 @@ static int acpi_memory_disable_device(struct acpi_memory_device *mem_device)
if (result)
return result;
}
+ list_del(&info->list);
kfree(info);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/7 v2] don't allow to eject the memory device if it is being used
2012-07-11 7:45 [PATCH 0/7 v2] some fixes about acpi_memhotplug Wen Congyang
` (2 preceding siblings ...)
2012-07-11 7:48 ` [PATCH 3/7 v2] remove memory info from list before freeing it Wen Congyang
@ 2012-07-11 7:49 ` Wen Congyang
2012-07-11 7:49 ` [PATCH 5/7 v2] bind the memory device when the driver is being loaded Wen Congyang
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Wen Congyang @ 2012-07-11 7:49 UTC (permalink / raw)
To: lenb, linux-acpi, linux-kernel@vger.kernel.org
Cc: Yasuaki ISIMATU, David Rientjes, Andrew Morton,
Konrad Rzeszutek Wilk
We eject the memory device even if it is in use. It is very dangerous,
and it will cause the kernel panicked.
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
drivers/acpi/acpi_memhotplug.c | 38 +++++++++++++++++++++++++++++++-------
1 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 1f6196a..1597348 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -78,6 +78,7 @@ struct acpi_memory_info {
unsigned short caching; /* memory cache attribute */
unsigned short write_protect; /* memory read/write attribute */
unsigned int enabled:1;
+ unsigned int failed:1;
};
struct acpi_memory_device {
@@ -257,9 +258,23 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
node = memory_add_physaddr_to_nid(info->start_addr);
result = add_memory(node, info->start_addr, info->length);
- if (result)
+
+ /*
+ * If the memory block has been used by the kernel, add_memory()
+ * returns -EEXIST. If add_memory() returns the other error, it
+ * means that this memory block is not used by the kernel.
+ */
+ if (result && result != -EEXIST) {
+ info->failed = 1;
continue;
- info->enabled = 1;
+ }
+
+ if (!result)
+ info->enabled = 1;
+ /*
+ * Add num_enable even if add_memory() returns -EEXIST, so the
+ * device is bound to this driver.
+ */
num_enabled++;
}
if (!num_enabled) {
@@ -323,11 +338,20 @@ static int acpi_memory_disable_device(struct acpi_memory_device *mem_device)
* Note: Assume that this function returns zero on success
*/
list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
- if (info->enabled) {
- result = remove_memory(info->start_addr, info->length);
- if (result)
- return result;
- }
+ if (info->failed)
+ /* The kernel does not use this memory block */
+ continue;
+
+ if (!info->enabled)
+ /*
+ * The kernel uses this memory block, but it may be not
+ * managed by us.
+ */
+ return -EBUSY;
+
+ result = remove_memory(info->start_addr, info->length);
+ if (result)
+ return result;
list_del(&info->list);
kfree(info);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/7 v2] bind the memory device when the driver is being loaded
2012-07-11 7:45 [PATCH 0/7 v2] some fixes about acpi_memhotplug Wen Congyang
` (3 preceding siblings ...)
2012-07-11 7:49 ` [PATCH 4/7 v2] don't allow to eject the memory device if it is being used Wen Congyang
@ 2012-07-11 7:49 ` Wen Congyang
2012-07-11 7:50 ` [PATCH 6/7 v2] auto bind the memory device which is hotpluged before the driver is loaded Wen Congyang
2012-07-11 7:50 ` [PATCH 7/7 v2] release memory resources if hotadd_new_pgdat() failed Wen Congyang
6 siblings, 0 replies; 9+ messages in thread
From: Wen Congyang @ 2012-07-11 7:49 UTC (permalink / raw)
To: lenb, linux-acpi, linux-kernel@vger.kernel.org
Cc: Yasuaki ISIMATU, David Rientjes, Andrew Morton,
Konrad Rzeszutek Wilk
We had introduced acpi_hotmem_initialized to avoid strange add_memory fail
message. But the memory device may not be used by the kernel, and the
device should be bound when the driver is being loaded. Remove
acpi_hotmem_initialized to allow that the device can be bound when the
driver is being loaded.
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
drivers/acpi/acpi_memhotplug.c | 12 ------------
1 files changed, 0 insertions(+), 12 deletions(-)
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 1597348..3765375 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -87,8 +87,6 @@ struct acpi_memory_device {
struct list_head res_list;
};
-static int acpi_hotmem_initialized;
-
static acpi_status
acpi_memory_get_resource(struct acpi_resource *resource, void *context)
{
@@ -470,15 +468,6 @@ static int acpi_memory_device_add(struct acpi_device *device)
printk(KERN_DEBUG "%s \n", acpi_device_name(device));
- /*
- * Early boot code has recognized memory area by EFI/E820.
- * If DSDT shows these memory devices on boot, hotplug is not necessary
- * for them. So, it just returns until completion of this driver's
- * start up.
- */
- if (!acpi_hotmem_initialized)
- return 0;
-
if (!acpi_memory_check_device(mem_device)) {
/* call add_memory func */
result = acpi_memory_enable_device(mem_device);
@@ -585,7 +574,6 @@ static int __init acpi_memory_device_init(void)
return -ENODEV;
}
- acpi_hotmem_initialized = 1;
return 0;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 6/7 v2] auto bind the memory device which is hotpluged before the driver is loaded
2012-07-11 7:45 [PATCH 0/7 v2] some fixes about acpi_memhotplug Wen Congyang
` (4 preceding siblings ...)
2012-07-11 7:49 ` [PATCH 5/7 v2] bind the memory device when the driver is being loaded Wen Congyang
@ 2012-07-11 7:50 ` Wen Congyang
2012-07-11 7:50 ` [PATCH 7/7 v2] release memory resources if hotadd_new_pgdat() failed Wen Congyang
6 siblings, 0 replies; 9+ messages in thread
From: Wen Congyang @ 2012-07-11 7:50 UTC (permalink / raw)
To: lenb, linux-acpi, linux-kernel@vger.kernel.org
Cc: Yasuaki ISIMATU, David Rientjes, Andrew Morton,
Konrad Rzeszutek Wilk
If the memory device is hotpluged before the driver is loaded, the
user cannot see this device under the directory /sys/bus/acpi/devices/,
and the user cannot bind it by hand after the driver is loaded.
This patch introduces a new feature to bind such device when the driver
is being loaded.
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
drivers/acpi/acpi_memhotplug.c | 37 ++++++++++++++++++++++++++++++++++++-
1 files changed, 36 insertions(+), 1 deletions(-)
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 3765375..0010720 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -52,6 +52,9 @@ MODULE_LICENSE("GPL");
#define MEMORY_POWER_ON_STATE 1
#define MEMORY_POWER_OFF_STATE 2
+static bool auto_probe;
+module_param(auto_probe, bool, S_IRUGO | S_IWUSR);
+
static int acpi_memory_device_add(struct acpi_device *device);
static int acpi_memory_device_remove(struct acpi_device *device, int type);
@@ -522,12 +525,44 @@ acpi_memory_register_notify_handler(acpi_handle handle,
u32 level, void *ctxt, void **retv)
{
acpi_status status;
-
+ struct acpi_memory_device *mem_device = NULL;
+ unsigned long long current_status;
status = is_memory_device(handle);
if (ACPI_FAILURE(status))
return AE_OK; /* continue */
+ if (auto_probe) {
+ /* Get device present/absent information from the _STA */
+ status = acpi_evaluate_integer(handle, "_STA", NULL,
+ ¤t_status);
+ if (ACPI_FAILURE(status))
+ goto install;
+
+ /*
+ * Check for device status. Device should be
+ * present/enabled/functioning.
+ */
+ if (!(current_status &
+ (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
+ ACPI_STA_DEVICE_FUNCTIONING)))
+ goto install;
+
+ if (acpi_memory_get_device(handle, &mem_device))
+ goto install;
+
+ /* We have bound this device while we register the driver */
+ if (mem_device->state == MEMORY_POWER_ON_STATE)
+ goto install;
+
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "\nauto probe memory device\n"));
+
+ if (acpi_memory_enable_device(mem_device))
+ pr_err(PREFIX "Cannot enable memory device\n");
+ }
+
+install:
status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
acpi_memory_device_notify, NULL);
/* continue */
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 7/7 v2] release memory resources if hotadd_new_pgdat() failed
2012-07-11 7:45 [PATCH 0/7 v2] some fixes about acpi_memhotplug Wen Congyang
` (5 preceding siblings ...)
2012-07-11 7:50 ` [PATCH 6/7 v2] auto bind the memory device which is hotpluged before the driver is loaded Wen Congyang
@ 2012-07-11 7:50 ` Wen Congyang
6 siblings, 0 replies; 9+ messages in thread
From: Wen Congyang @ 2012-07-11 7:50 UTC (permalink / raw)
To: lenb, linux-acpi, linux-kernel@vger.kernel.org
Cc: Yasuaki ISIMATU, David Rientjes, Andrew Morton,
Konrad Rzeszutek Wilk
We should goto error to release memory resource if hotadd_new_pgdat() failed.
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
mm/memory_hotplug.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 0d7e3ec..427bb29 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -618,7 +618,7 @@ int __ref add_memory(int nid, u64 start, u64 size)
pgdat = hotadd_new_pgdat(nid, start);
ret = -ENOMEM;
if (!pgdat)
- goto out;
+ goto error;
new_pgdat = 1;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread