* [PATCH RFC] kmemleak vs. memory hotplug
@ 2010-03-22 19:51 Jason Baron
2010-03-23 9:25 ` Catalin Marinas
0 siblings, 1 reply; 2+ messages in thread
From: Jason Baron @ 2010-03-22 19:51 UTC (permalink / raw)
To: catalin.marinas, jbarnes, prarit; +Cc: linux-kernel
Hi,
I noticed in the Kconfig that kmemleak can not be set without
MEMORY_HOTPLUG being unset. I'd like to be able to enable both. Below,
is an rfc patch, completely untested, as a starting point. Hopefully,
ppl more knowledgeable in this area can comment.
thanks,
-Jason
diff --git a/include/linux/kmemleak.h b/include/linux/kmemleak.h
index 99d9a67..ad89f2d 100644
--- a/include/linux/kmemleak.h
+++ b/include/linux/kmemleak.h
@@ -54,6 +54,18 @@ static inline void kmemleak_erase(void **ptr)
*ptr = NULL;
}
+extern struct mutex kmemleak_hotplug;
+
+static inline void lock_system_kmemleak(void)
+{
+ mutex_lock(&kmemleak_hotplug);
+}
+
+static inline void unlock_system_kmemleak(void)
+{
+ mutex_unlock(&kmemleak_hotplug);
+}
+
#else
static inline void kmemleak_init(void)
@@ -93,6 +105,14 @@ static inline void kmemleak_no_scan(const void *ptr)
{
}
+static inline void lock_system_kmemleak(void)
+{
+}
+
+static inline void unlock_system_kmemleak(void)
+{
+}
+
#endif /* CONFIG_DEBUG_KMEMLEAK */
#endif /* __KMEMLEAK_H */
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 4a50fc1..2e89153 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -365,14 +365,13 @@ config SLUB_STATS
config DEBUG_KMEMLEAK
bool "Kernel memory leak detector"
- depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \
+ depends on DEBUG_KERNEL && EXPERIMENTAL && \
(X86 || ARM || PPC || S390 || SUPERH)
select DEBUG_FS if SYSFS
select STACKTRACE if STACKTRACE_SUPPORT
select KALLSYMS
select CRC32
- depends on 0
help
Say Y here if you want to enable the memory leak
detector. The memory allocation/freeing is traced in a way
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 5b069e4..509a728 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -102,6 +102,9 @@
#include <linux/kmemcheck.h>
#include <linux/kmemleak.h>
+/* exlcludes memory hotplug */
+DEFINE_MUTEX(kmemleak_hotplug);
+
/*
* Kmemleak configuration and common defines.
*/
@@ -1178,6 +1181,7 @@ static void kmemleak_scan(void)
* Struct page scanning for each node. The code below is not yet safe
* with MEMORY_HOTPLUG.
*/
+ mutex_lock(&kmemleak_hotplug);
for_each_online_node(i) {
pg_data_t *pgdat = NODE_DATA(i);
unsigned long start_pfn = pgdat->node_start_pfn;
@@ -1196,6 +1200,7 @@ static void kmemleak_scan(void)
scan_block(page, page + 1, NULL, 1);
}
}
+ mutex_unlock(&kmemleak_hotplug);
/*
* Scanning the task stacks (may introduce false negatives).
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 78e34e6..01fc57d 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -34,6 +34,23 @@
#include "internal.h"
+/* exclude subsystems that hotplug might conflict with */
+static void lock_hotplug_exlucde(void)
+{
+ /* exclude hotplug */
+ lock_system_sleep();
+ /* exlucde kmemleak */
+ lock_system_kmemleak();
+}
+
+static void unlock_hotplug_exlucde(void)
+{
+ /* exclude hotplug */
+ unlock_system_sleep();
+ /* exlucde kmemleak */
+ unlock_system_kmemleak();
+}
+
/* add this memory to iomem resource */
static struct resource *register_memory_resource(u64 start, u64 size)
{
@@ -490,7 +507,7 @@ int __ref add_memory(int nid, u64 start, u64 size)
struct resource *res;
int ret;
- lock_system_sleep();
+ lock_hotplug_exclude();
res = register_memory_resource(start, size);
ret = -EEXIST;
@@ -537,7 +554,7 @@ error:
release_memory_resource(res);
out:
- unlock_system_sleep();
+ unlock_hotplug_exclude();
return ret;
}
EXPORT_SYMBOL_GPL(add_memory);
@@ -777,7 +794,7 @@ static int offline_pages(unsigned long start_pfn,
if (!test_pages_in_a_zone(start_pfn, end_pfn))
return -EINVAL;
- lock_system_sleep();
+ lock_hotplug_exclude();
zone = page_zone(pfn_to_page(start_pfn));
node = zone_to_nid(zone);
@@ -868,7 +885,7 @@ repeat:
writeback_set_ratelimit();
memory_notify(MEM_OFFLINE, &arg);
- unlock_system_sleep();
+ unlock_hotplug_exclude();
return 0;
failed_removal:
@@ -879,7 +896,7 @@ failed_removal:
undo_isolate_page_range(start_pfn, end_pfn);
out:
- unlock_system_sleep();
+ unlock_hotplug_exclude();
return ret;
}
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH RFC] kmemleak vs. memory hotplug
2010-03-22 19:51 [PATCH RFC] kmemleak vs. memory hotplug Jason Baron
@ 2010-03-23 9:25 ` Catalin Marinas
0 siblings, 0 replies; 2+ messages in thread
From: Catalin Marinas @ 2010-03-23 9:25 UTC (permalink / raw)
To: Jason Baron; +Cc: jbarnes, prarit, linux-kernel
On Mon, 2010-03-22 at 19:51 +0000, Jason Baron wrote:
> I noticed in the Kconfig that kmemleak can not be set without
> MEMORY_HOTPLUG being unset. I'd like to be able to enable both. Below,
> is an rfc patch, completely untested, as a starting point. Hopefully,
> ppl more knowledgeable in this area can comment.
[...]
> diff --git a/mm/kmemleak.c b/mm/kmemleak.c
> index 5b069e4..509a728 100644
> --- a/mm/kmemleak.c
> +++ b/mm/kmemleak.c
> @@ -102,6 +102,9 @@
> #include <linux/kmemcheck.h>
> #include <linux/kmemleak.h>
>
> +/* exlcludes memory hotplug */
> +DEFINE_MUTEX(kmemleak_hotplug);
> +
> /*
> * Kmemleak configuration and common defines.
> */
> @@ -1178,6 +1181,7 @@ static void kmemleak_scan(void)
> * Struct page scanning for each node. The code below is not yet safe
> * with MEMORY_HOTPLUG.
> */
> + mutex_lock(&kmemleak_hotplug);
> for_each_online_node(i) {
> pg_data_t *pgdat = NODE_DATA(i);
> unsigned long start_pfn = pgdat->node_start_pfn;
> @@ -1196,6 +1200,7 @@ static void kmemleak_scan(void)
> scan_block(page, page + 1, NULL, 1);
> }
> }
> + mutex_unlock(&kmemleak_hotplug);
An alternative (not sure whether it's feasible) may be to inform
kmemleak about the pg_data_t objects (via kmemleak_alloc) sometime
during initialisation and add hooks to memory hotplug to remove or add
such objects from kmemleak during hotplug events.
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 78e34e6..01fc57d 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -34,6 +34,23 @@
>
> #include "internal.h"
>
> +/* exclude subsystems that hotplug might conflict with */
> +static void lock_hotplug_exlucde(void)
> +{
> + /* exclude hotplug */
> + lock_system_sleep();
> + /* exlucde kmemleak */
> + lock_system_kmemleak();
> +}
> +
> +static void unlock_hotplug_exlucde(void)
> +{
> + /* exclude hotplug */
> + unlock_system_sleep();
> + /* exlucde kmemleak */
> + unlock_system_kmemleak();
> +}
I think the unlocking should be done in the reversed order.
Thanks.
--
Catalin
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-03-23 9:25 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-22 19:51 [PATCH RFC] kmemleak vs. memory hotplug Jason Baron
2010-03-23 9:25 ` Catalin Marinas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).