--- linux-2.6.14-rc2/include/linux/vmalloc.h 2005-09-20 05:00:41.000000000 +0200 +++ linux-2.6.14-rc2-ed/include/linux/vmalloc.h 2005-09-22 11:34:55.000000000 +0200 @@ -1,6 +1,7 @@ #ifndef _LINUX_VMALLOC_H #define _LINUX_VMALLOC_H +#include /* vmalloc_node() needs CONFIG_ options */ #include #include /* pgprot_t */ @@ -32,6 +33,14 @@ * Highlevel APIs for driver use */ extern void *vmalloc(unsigned long size); +#ifdef CONFIG_NUMA +extern void *vmalloc_node(unsigned long size, int node); +#else +static inline void *vmalloc_node(unsigned long size, int node) +{ + return vmalloc(size); +} +#endif extern void *vmalloc_exec(unsigned long size); extern void *vmalloc_32(unsigned long size); extern void *__vmalloc(unsigned long size, unsigned int __nocast gfp_mask, pgprot_t prot); --- linux-2.6.14-rc2/mm/vmalloc.c 2005-09-20 05:00:41.000000000 +0200 +++ linux-2.6.14-rc2-ed/mm/vmalloc.c 2005-09-22 11:55:19.000000000 +0200 @@ -19,6 +19,9 @@ #include #include +#ifdef CONFIG_NUMA +#include +#endif DEFINE_RWLOCK(vmlist_lock); struct vm_struct *vmlist; @@ -471,7 +474,7 @@ * Allocate enough pages to cover @size from the page level * allocator and map them into contiguous kernel virtual space. * - * For tight cotrol over page level allocator and protection flags + * For tight control over page level allocator and protection flags * use __vmalloc() instead. */ void *vmalloc(unsigned long size) @@ -481,6 +484,40 @@ EXPORT_SYMBOL(vmalloc); +#ifdef CONFIG_NUMA +/** + * vmalloc_node - allocate virtually contiguous memory + * + * @size: allocation size + * @node: preferred node + * + * This vmalloc variant try to allocate memory from a preferred node. + */ +void *vmalloc_node(unsigned long size, int node) +{ + void *result; + struct mempolicy *oldpol = current->mempolicy; + mm_segment_t oldfs = get_fs(); + DECLARE_BITMAP(prefnode, MAX_NUMNODES); + + mpol_get(oldpol); + bitmap_zero(prefnode, MAX_NUMNODES); + set_bit(node, prefnode); + + set_fs(KERNEL_DS); + sys_set_mempolicy(MPOL_PREFERRED, prefnode, MAX_NUMNODES); + set_fs(oldfs); + + result = vmalloc(size); + + mpol_free(current->mempolicy); + current->mempolicy = oldpol; + return result; +} + +EXPORT_SYMBOL(vmalloc_node); +#endif + #ifndef PAGE_KERNEL_EXEC # define PAGE_KERNEL_EXEC PAGE_KERNEL #endif