diff options
author | Kirill Korotaev <dev@openvz.org> | 2006-06-23 05:03:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-23 10:42:52 -0400 |
commit | 8f9de51a4a98ba32f839903b7d009788bc2c295d (patch) | |
tree | 65cde3cd75bfc1df172f53ca956cba4fa4954a4e /mm/page_alloc.c | |
parent | d501e62bc7796e90b0312648e23ac39490dfbf87 (diff) |
[PATCH] printk() should not be called under zone->lock
This patch fixes printk() under zone->lock in show_free_areas(). It can be
unsafe to call printk() under this lock, since caller can try to
allocate/free some memory and selfdeadlock on this lock. I found
allocations/freeing mem both in netconsole and serial console.
This issue was faced in reallity when meminfo was periodically printed for
debug purposes and netconsole was used.
Signed-off-by: Kirill Korotaev <dev@openvz.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 71a0b2a23f5b..423db0db7c02 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -1491,7 +1491,7 @@ void show_free_areas(void) | |||
1491 | } | 1491 | } |
1492 | 1492 | ||
1493 | for_each_zone(zone) { | 1493 | for_each_zone(zone) { |
1494 | unsigned long nr, flags, order, total = 0; | 1494 | unsigned long nr[MAX_ORDER], flags, order, total = 0; |
1495 | 1495 | ||
1496 | show_node(zone); | 1496 | show_node(zone); |
1497 | printk("%s: ", zone->name); | 1497 | printk("%s: ", zone->name); |
@@ -1502,11 +1502,12 @@ void show_free_areas(void) | |||
1502 | 1502 | ||
1503 | spin_lock_irqsave(&zone->lock, flags); | 1503 | spin_lock_irqsave(&zone->lock, flags); |
1504 | for (order = 0; order < MAX_ORDER; order++) { | 1504 | for (order = 0; order < MAX_ORDER; order++) { |
1505 | nr = zone->free_area[order].nr_free; | 1505 | nr[order] = zone->free_area[order].nr_free; |
1506 | total += nr << order; | 1506 | total += nr[order] << order; |
1507 | printk("%lu*%lukB ", nr, K(1UL) << order); | ||
1508 | } | 1507 | } |
1509 | spin_unlock_irqrestore(&zone->lock, flags); | 1508 | spin_unlock_irqrestore(&zone->lock, flags); |
1509 | for (order = 0; order < MAX_ORDER; order++) | ||
1510 | printk("%lu*%lukB ", nr[order], K(1UL) << order); | ||
1510 | printk("= %lukB\n", K(total)); | 1511 | printk("= %lukB\n", K(total)); |
1511 | } | 1512 | } |
1512 | 1513 | ||