Add the ability to allocate a block of memory via alloc_bootmem() and manage that memory with a remote heap (rheap).
Signed-off-by: Timur Tabi <[EMAIL PROTECTED]> --- This patch will conflict with Sylvain's "powerpc: Changes the config mechanism for rheap" patch, but that patch hasn't been accepted yet, so I'm posting this for review and comment. arch/powerpc/lib/rheap.c | 79 +++++++++++++++++++++++++++++++++++++++++++ include/asm-powerpc/rheap.h | 4 ++ 2 files changed, 83 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c index ada5b42..d2c8913 100644 --- a/arch/powerpc/lib/rheap.c +++ b/arch/powerpc/lib/rheap.c @@ -18,6 +18,8 @@ #include <linux/mm.h> #include <linux/err.h> #include <linux/slab.h> +#include <linux/bootmem.h> +#include <linux/module.h> #include <asm/rheap.h> @@ -729,3 +731,80 @@ void rh_dump_blk(rh_info_t * info, rh_block_t * blk) "blk @0x%p: 0x%lx-0x%lx (%u)\n", blk, blk->start, blk->start + blk->size, blk->size); } + +/* Bootmem-allocated rheap + * + * If the "rhbootmem=X" command-line parameter is specified, then the RHEAP + * code will allocate a chunk of memory using alloc_bootmem() and create an + * rheap for it. +*/ + +static rh_info_t bootmem_rh_info; +static rh_block_t bootmem_rh_block[16]; + +static void *bootmem_ptr; +static unsigned long bootmem_size; + +static int __init early_parse_rhbootmem(char *p) +{ + if (!p) + return 1; + + bootmem_size = _ALIGN_UP(memparse(p, &p), 32); + + return 0; +} +early_param("rhbootmem", early_parse_rhbootmem); + +static int __init rheap_bootmem_init(void) +{ + if (!bootmem_size) + return 0; + + bootmem_ptr = __alloc_bootmem(bootmem_size, 32, 0); + if (!bootmem_ptr) { + printk(KERN_ERR "rheap: cannot allocate %lu bootmem bytes\n", + bootmem_size); + return -ENOMEM; + } + + rh_init(&bootmem_rh_info, 32, ARRAY_SIZE(bootmem_rh_block), + bootmem_rh_block); + + rh_attach_region(&bootmem_rh_info, bootmem_ptr, bootmem_size); + + printk(KERN_INFO "rheap: allocated %lu bootmem bytes\n", bootmem_size); + + return 0; +} +arch_initcall(rheap_bootmem_init); + +/* Allocatate a block from the bootmem + * + * This function allocates a block of memory from the bootmem + */ +void *rheap_bootmem_alloc(size_t size) +{ + return rh_alloc(&bootmem_rh_info, size, "BOOTMEM"); +} +EXPORT_SYMBOL(rheap_bootmem_alloc); + +/* Free a previously allocated block + */ +void rheap_bootmem_free(void *p, size_t size) +{ + if (p) + rh_free(&bootmem_rh_info, p); +} +EXPORT_SYMBOL(rheap_bootmem_free); + +/* Returns 1 if pointer is inside bootmem + * + * This function tells you if the given pointer points to the allocated + * bootmem. + */ +int rheap_is_bootmem(void *p) +{ + return (p >= bootmem_ptr) && (p < (bootmem_ptr + bootmem_size)); +} +EXPORT_SYMBOL(rheap_is_bootmem); diff --git a/include/asm-powerpc/rheap.h b/include/asm-powerpc/rheap.h index 1723817..5a8dee1 100644 --- a/include/asm-powerpc/rheap.h +++ b/include/asm-powerpc/rheap.h @@ -86,4 +86,8 @@ extern void rh_dump(rh_info_t * info); /* Set owner of taken block */ extern int rh_set_owner(rh_info_t * info, unsigned long start, const char *owner); +void *rheap_bootmem_alloc(size_t size); +void rheap_bootmem_free(void *p, size_t size); +int rheap_is_bootmem(void *p); + #endif /* __ASM_PPC_RHEAP_H__ */ -- 1.5.2.4 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev