Provide user a way to control which NUMA node the memory for ram device is allocated from. The default memory allocation can fall into more than one numa node for one raw device, with this patch you can specify one device just allocting from one node, if not exceed the node's total memory, and another device from a different node as the parameter is writable. Signed-off-by: Zhengyuan Liu <liuzhengyuan@xxxxxxxxxx> --- drivers/block/brd.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 17723fd5..a9e5867 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -56,10 +56,28 @@ struct brd_device { struct radix_tree_root brd_pages; }; +static DEFINE_MUTEX(brd_mutex); + +static int rd_numa_node = NUMA_NO_NODE; + +static int set_rd_numa_node(const char *val, struct kernel_param *kp) +{ + int ret = param_set_int(val, kp); + if (ret) + return ret; + mutex_lock(&brd_mutex); + if (rd_numa_node < NUMA_NO_NODE) + rd_numa_node = NUMA_NO_NODE; + else if (rd_numa_node > num_online_nodes() - 1) + rd_numa_node = num_online_nodes() - 1; + pr_info("setting rd_numa_node to (%d)\n", rd_numa_node); + mutex_unlock(&brd_mutex); + return 0; +} + /* * Look up and return a brd's page for a given sector. */ -static DEFINE_MUTEX(brd_mutex); static struct page *brd_lookup_page(struct brd_device *brd, sector_t sector) { pgoff_t idx; @@ -114,7 +132,7 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector) #ifndef CONFIG_BLK_DEV_RAM_DAX gfp_flags |= __GFP_HIGHMEM; #endif - page = alloc_page(gfp_flags); + page = alloc_pages_node(rd_numa_node, gfp_flags, 0); if (!page) return NULL; @@ -413,14 +431,14 @@ static struct brd_device *brd_alloc(int i) struct brd_device *brd; struct gendisk *disk; - brd = kzalloc(sizeof(*brd), GFP_KERNEL); + brd = kzalloc_node(sizeof(*brd), GFP_KERNEL, rd_numa_node); if (!brd) goto out; brd->brd_number = i; spin_lock_init(&brd->brd_lock); INIT_RADIX_TREE(&brd->brd_pages, GFP_ATOMIC); - brd->brd_queue = blk_alloc_queue(GFP_KERNEL); + brd->brd_queue = blk_alloc_queue_node(GFP_KERNEL, rd_numa_node); if (!brd->brd_queue) goto out_free_dev; @@ -434,7 +452,7 @@ static struct brd_device *brd_alloc(int i) * is harmless) */ blk_queue_physical_block_size(brd->brd_queue, PAGE_SIZE); - disk = brd->brd_disk = alloc_disk(max_part); + disk = brd->brd_disk = alloc_disk_node(max_part, rd_numa_node); if (!disk) goto out_free_queue; disk->major = RAMDISK_MAJOR; @@ -593,6 +611,10 @@ static void __exit brd_exit(void) pr_info("brd: module unloaded\n"); } +module_param_call(rd_numa_node, set_rd_numa_node, param_get_int, + &rd_numa_node, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(rd_numa_node, "Numa node to which memeory alloc from"); + module_init(brd_init); module_exit(brd_exit); -- 2.7.4