diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-08-04 00:38:47 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-08-04 00:38:47 -0400 |
commit | 72d4b0b4e0e7fa858767e03972771a9f7c02b689 (patch) | |
tree | 5cdf39edb6edbaa7f75da27ad1d9ce7864bb9448 | |
parent | 411a25a80da328f5ae6b6c037872ffe867fcc130 (diff) |
memblock: Implement memblock_is_memory and memblock_is_region_memory
To make it fast, we steal ARM's binary search for memblock_is_memory()
and we use that to also the replace existing implementation of
memblock_is_reserved().
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | include/linux/memblock.h | 2 | ||||
-rw-r--r-- | mm/memblock.c | 42 |
2 files changed, 36 insertions, 8 deletions
diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 4b6931327b22..47bceb187058 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h | |||
@@ -56,6 +56,8 @@ extern u64 __init __memblock_alloc_base(u64 size, | |||
56 | extern u64 __init memblock_phys_mem_size(void); | 56 | extern u64 __init memblock_phys_mem_size(void); |
57 | extern u64 memblock_end_of_DRAM(void); | 57 | extern u64 memblock_end_of_DRAM(void); |
58 | extern void __init memblock_enforce_memory_limit(u64 memory_limit); | 58 | extern void __init memblock_enforce_memory_limit(u64 memory_limit); |
59 | extern int memblock_is_memory(u64 addr); | ||
60 | extern int memblock_is_region_memory(u64 base, u64 size); | ||
59 | extern int __init memblock_is_reserved(u64 addr); | 61 | extern int __init memblock_is_reserved(u64 addr); |
60 | extern int memblock_is_region_reserved(u64 base, u64 size); | 62 | extern int memblock_is_region_reserved(u64 base, u64 size); |
61 | extern int memblock_find(struct memblock_region *res); | 63 | extern int memblock_find(struct memblock_region *res); |
diff --git a/mm/memblock.c b/mm/memblock.c index 6f407ccf604e..aa88c62bce7f 100644 --- a/mm/memblock.c +++ b/mm/memblock.c | |||
@@ -487,17 +487,43 @@ void __init memblock_enforce_memory_limit(u64 memory_limit) | |||
487 | } | 487 | } |
488 | } | 488 | } |
489 | 489 | ||
490 | static int memblock_search(struct memblock_type *type, u64 addr) | ||
491 | { | ||
492 | unsigned int left = 0, right = type->cnt; | ||
493 | |||
494 | do { | ||
495 | unsigned int mid = (right + left) / 2; | ||
496 | |||
497 | if (addr < type->regions[mid].base) | ||
498 | right = mid; | ||
499 | else if (addr >= (type->regions[mid].base + | ||
500 | type->regions[mid].size)) | ||
501 | left = mid + 1; | ||
502 | else | ||
503 | return mid; | ||
504 | } while (left < right); | ||
505 | return -1; | ||
506 | } | ||
507 | |||
490 | int __init memblock_is_reserved(u64 addr) | 508 | int __init memblock_is_reserved(u64 addr) |
491 | { | 509 | { |
492 | int i; | 510 | return memblock_search(&memblock.reserved, addr) != -1; |
511 | } | ||
493 | 512 | ||
494 | for (i = 0; i < memblock.reserved.cnt; i++) { | 513 | int memblock_is_memory(u64 addr) |
495 | u64 upper = memblock.reserved.regions[i].base + | 514 | { |
496 | memblock.reserved.regions[i].size - 1; | 515 | return memblock_search(&memblock.memory, addr) != -1; |
497 | if ((addr >= memblock.reserved.regions[i].base) && (addr <= upper)) | 516 | } |
498 | return 1; | 517 | |
499 | } | 518 | int memblock_is_region_memory(u64 base, u64 size) |
500 | return 0; | 519 | { |
520 | int idx = memblock_search(&memblock.reserved, base); | ||
521 | |||
522 | if (idx == -1) | ||
523 | return 0; | ||
524 | return memblock.reserved.regions[idx].base <= base && | ||
525 | (memblock.reserved.regions[idx].base + | ||
526 | memblock.reserved.regions[idx].size) >= (base + size); | ||
501 | } | 527 | } |
502 | 528 | ||
503 | int memblock_is_region_reserved(u64 base, u64 size) | 529 | int memblock_is_region_reserved(u64 base, u64 size) |