aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-04-20 11:31:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-04-20 14:18:46 -0400
commitb3dc627cabb33fc95f93da78457770c1b2a364d2 (patch)
treee37cae7a574b808b6da48e4c93e81f170efce078
parent310eb776501af8412c570c4bcddc9ab5cecf3d7a (diff)
memblock: memblock should be able to handle zero length operations
Commit 24aa07882b ("memblock, x86: Replace memblock_x86_reserve/ free_range() with generic ones") replaced x86 specific memblock operations with the generic ones; unfortunately, it lost zero length operation handling in the process making the kernel panic if somebody tries to reserve zero length area. There isn't much to be gained by being cranky to zero length operations and panicking is almost the worst response. Drop the BUG_ON() in memblock_reserve() and update memblock_add_region/isolate_range() so that all zero length operations are handled as noops. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: stable@vger.kernel.org Reported-by: Valere Monseur <valere.monseur@ymail.com> Bisected-by: Joseph Freeman <jfree143dev@gmail.com> Tested-by: Joseph Freeman <jfree143dev@gmail.com> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=43098 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/memblock.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/mm/memblock.c b/mm/memblock.c
index 99f285599501..a44eab3157f8 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -330,6 +330,9 @@ static int __init_memblock memblock_add_region(struct memblock_type *type,
330 phys_addr_t end = base + memblock_cap_size(base, &size); 330 phys_addr_t end = base + memblock_cap_size(base, &size);
331 int i, nr_new; 331 int i, nr_new;
332 332
333 if (!size)
334 return 0;
335
333 /* special case for empty array */ 336 /* special case for empty array */
334 if (type->regions[0].size == 0) { 337 if (type->regions[0].size == 0) {
335 WARN_ON(type->cnt != 1 || type->total_size); 338 WARN_ON(type->cnt != 1 || type->total_size);
@@ -430,6 +433,9 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type,
430 433
431 *start_rgn = *end_rgn = 0; 434 *start_rgn = *end_rgn = 0;
432 435
436 if (!size)
437 return 0;
438
433 /* we'll create at most two more regions */ 439 /* we'll create at most two more regions */
434 while (type->cnt + 2 > type->max) 440 while (type->cnt + 2 > type->max)
435 if (memblock_double_array(type) < 0) 441 if (memblock_double_array(type) < 0)
@@ -514,7 +520,6 @@ int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size)
514 (unsigned long long)base, 520 (unsigned long long)base,
515 (unsigned long long)base + size, 521 (unsigned long long)base + size,
516 (void *)_RET_IP_); 522 (void *)_RET_IP_);
517 BUG_ON(0 == size);
518 523
519 return memblock_add_region(_rgn, base, size, MAX_NUMNODES); 524 return memblock_add_region(_rgn, base, size, MAX_NUMNODES);
520} 525}