diff --git a/drivers/video/tegra/nvmap/nvmap_carveout.c b/drivers/video/tegra/nvmap/nvmap_carveout.c index f407bd47..52acffc9 100644 --- a/drivers/video/tegra/nvmap/nvmap_carveout.c +++ b/drivers/video/tegra/nvmap/nvmap_carveout.c @@ -56,7 +56,8 @@ int nvmap_create_carveout(const struct nvmap_platform_carveout *co) } for (i = 0; i < nvmap_dev->nr_heaps; i++) - if ((co->usage_mask != NVMAP_HEAP_CARVEOUT_IVM) && + if ((co->usage_mask != NVMAP_HEAP_CARVEOUT_IVM && + co->usage_mask != NVMAP_HEAP_CARVEOUT_GPU) && (nvmap_dev->heaps[i].heap_bit & co->usage_mask)) { pr_err("carveout %s already exists\n", co->name); err = -EEXIST; @@ -87,33 +88,38 @@ int nvmap_create_carveout(const struct nvmap_platform_carveout *co) if (!IS_ERR_OR_NULL(nvmap_dev->debug_root)) { struct dentry *heap_root = debugfs_create_dir(co->name, nvmap_dev->debug_root); + struct debugfs_info *carevout_debugfs_info = node->carveout->carevout_debugfs_info; + + carevout_debugfs_info->heap_bit = node->heap_bit; + carevout_debugfs_info->numa_id = node->carveout->numa_node_id; + if (!IS_ERR_OR_NULL(heap_root)) { debugfs_create_file("clients", S_IRUGO, heap_root, - (void *)(uintptr_t)node->heap_bit, + (void *)carevout_debugfs_info, &debug_clients_fops); debugfs_create_file("allocations", S_IRUGO, heap_root, - (void *)(uintptr_t)node->heap_bit, + (void *)carevout_debugfs_info, &debug_allocations_fops); debugfs_create_file("all_allocations", S_IRUGO, heap_root, - (void *)(uintptr_t)node->heap_bit, + (void *)carevout_debugfs_info, &debug_all_allocations_fops); debugfs_create_file("orphan_handles", S_IRUGO, heap_root, - (void *)(uintptr_t)node->heap_bit, + (void *)carevout_debugfs_info, &debug_orphan_handles_fops); debugfs_create_file("maps", S_IRUGO, heap_root, - (void *)(uintptr_t)node->heap_bit, + (void *)carevout_debugfs_info, &debug_maps_fops); debugfs_create_bool("no_cpu_access", S_IRUGO, heap_root, (bool *)&co->no_cpu_access); #ifdef NVMAP_CONFIG_DEBUG_MAPS debugfs_create_file("device_list", S_IRUGO, heap_root, - (void *)(uintptr_t)node->heap_bit, + (void *)carevout_debugfs_info, &debug_device_list_fops); #endif /* NVMAP_CONFIG_DEBUG_MAPS */ nvmap_heap_debugfs_init(heap_root, @@ -232,10 +238,10 @@ struct nvmap_heap_block *do_nvmap_carveout_alloc(struct nvmap_client *client, { struct nvmap_carveout_node *co_heap; struct nvmap_device *dev = nvmap_dev; + struct nvmap_heap_block *block = NULL; int i; for (i = 0; i < dev->nr_carveouts; i++) { - struct nvmap_heap_block *block; co_heap = &dev->heaps[i]; if (!(co_heap->heap_bit & type)) @@ -244,11 +250,26 @@ struct nvmap_heap_block *do_nvmap_carveout_alloc(struct nvmap_client *client, if (type & NVMAP_HEAP_CARVEOUT_IVM) handle->size = ALIGN(handle->size, NVMAP_IVM_ALIGNMENT); - block = nvmap_heap_alloc(co_heap->carveout, handle, start); - if (block) - return block; + /* + * When NUMA_NO_NODE is specified, iterate all carveouts with same heap_bit + * and different numa nid. Else, specific numa nid is specified, then allocate + * only from that particular carveout on given numa node. + */ + if (handle->numa_id == NUMA_NO_NODE) { + block = nvmap_heap_alloc(co_heap->carveout, handle, start); + if (!block) + continue; + goto exit; + } else { + if (handle->numa_id != co_heap->carveout->numa_node_id) + continue; + block = nvmap_heap_alloc(co_heap->carveout, handle, start); + goto exit; + } } - return NULL; + +exit: + return block; } struct nvmap_heap_block *nvmap_carveout_alloc(struct nvmap_client *client, diff --git a/drivers/video/tegra/nvmap/nvmap_dev.c b/drivers/video/tegra/nvmap/nvmap_dev.c index 57feeda4..45f57ef9 100644 --- a/drivers/video/tegra/nvmap/nvmap_dev.c +++ b/drivers/video/tegra/nvmap/nvmap_dev.c @@ -70,6 +70,7 @@ static struct device_dma_parameters nvmap_dma_parameters = { .max_segment_size = UINT_MAX, }; +static struct debugfs_info iovmm_debugfs_info; static int nvmap_open(struct inode *inode, struct file *filp); static int nvmap_release(struct inode *inode, struct file *filp); static long nvmap_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); @@ -592,13 +593,13 @@ next_page: nvmap_ref_unlock(client); } -bool is_nvmap_memory_available(size_t size, uint32_t heap) +bool is_nvmap_memory_available(size_t size, uint32_t heap, int numa_nid) { unsigned long total_num_pages; unsigned int carveout_mask = NVMAP_HEAP_CARVEOUT_MASK; unsigned int iovmm_mask = NVMAP_HEAP_IOVMM; struct nvmap_device *dev = nvmap_dev; - bool heap_present = false; + bool memory_available = false; int i; if (!heap) @@ -637,17 +638,33 @@ bool is_nvmap_memory_available(size_t size, uint32_t heap) if (!(co_heap->heap_bit & heap)) continue; - heap_present = true; h = co_heap->carveout; - if (size > h->free_size) { - pr_debug("Requested size is more than available memory"); - pr_debug("Requested size : %lu B, Available memory : %lu B\n", size, - h->free_size); - return false; - } + /* + * When user does not specify numa node i.e. in default NUMA_NO_NODE case, + * do not consider numa node id. So check for heap instances on all numa + * nodes. When numa node is provided by user, then check heap instance only + * on that numa node. + */ + if (numa_nid == NUMA_NO_NODE) { + if (size > h->free_size) + continue; + memory_available = true; + goto exit; + } else { + if (h->numa_node_id != numa_nid) + continue; + else if (size > h->free_size) + memory_available = false; + else + memory_available = true; + + goto exit; + } break; } - return heap_present; + +exit: + return memory_available; } /* compute the total amount of handle physical memory that is mapped @@ -750,7 +767,7 @@ next_page: } static void nvmap_get_client_mss(struct nvmap_client *client, - u64 *total, u32 heap_type) + u64 *total, u32 heap_type, int numa_id) { struct rb_node *n; @@ -761,15 +778,21 @@ static void nvmap_get_client_mss(struct nvmap_client *client, struct nvmap_handle_ref *ref = rb_entry(n, struct nvmap_handle_ref, node); struct nvmap_handle *handle = ref->handle; - if (handle->alloc && handle->heap_type == heap_type) + if (handle->alloc && handle->heap_type == heap_type) { + if (heap_type != NVMAP_HEAP_IOVMM && + (nvmap_block_to_heap(handle->carveout)->numa_node_id != + numa_id)) + continue; + *total += handle->size / atomic_read(&handle->share_count); + } } nvmap_ref_unlock(client); } #define PSS_SHIFT 12 -static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type) +static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type, int numa_id) { int i; struct rb_node *n; @@ -789,6 +812,11 @@ static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type) if (!h || !h->alloc || h->heap_type != heap_type) continue; + if (heap_type != NVMAP_HEAP_IOVMM && + (nvmap_block_to_heap(h->carveout)->numa_node_id != + numa_id)) + continue; + *total += h->size; if (!pss) continue; @@ -807,7 +835,9 @@ static int nvmap_debug_allocations_show(struct seq_file *s, void *unused) { u64 total; struct nvmap_client *client; - u32 heap_type = (u32)(uintptr_t)s->private; + struct debugfs_info *debugfs_information = (struct debugfs_info *)s->private; + u32 heap_type = debugfs_information->heap_bit; + int numa_id = debugfs_information->numa_id; mutex_lock(&nvmap_dev->clients_lock); seq_printf(s, "%-18s %18s %8s %11s\n", @@ -818,13 +848,13 @@ static int nvmap_debug_allocations_show(struct seq_file *s, void *unused) list_for_each_entry(client, &nvmap_dev->clients, list) { u64 client_total; client_stringify(client, s); - nvmap_get_client_mss(client, &client_total, heap_type); + nvmap_get_client_mss(client, &client_total, heap_type, numa_id); seq_printf(s, " %10lluK\n", K(client_total)); allocations_stringify(client, s, heap_type); seq_printf(s, "\n"); } mutex_unlock(&nvmap_dev->clients_lock); - nvmap_get_total_mss(NULL, &total, heap_type); + nvmap_get_total_mss(NULL, &total, heap_type, numa_id); seq_printf(s, "%-18s %-18s %8s %10lluK\n", "total", "", "", K(total)); return 0; } @@ -846,7 +876,9 @@ DEBUGFS_OPEN_FOPS(free_size); #ifdef NVMAP_CONFIG_DEBUG_MAPS static int nvmap_debug_device_list_show(struct seq_file *s, void *unused) { - u32 heap_type = (u32)(uintptr_t)s->private; + struct debugfs_info *debugfs_information = (struct debugfs_info *)s->private; + u32 heap_type = debugfs_information->heap_bit; + int numa_id = debugfs_information->numa_id; struct rb_node *n = NULL; struct nvmap_device_list *dl = NULL; int i; @@ -857,7 +889,9 @@ static int nvmap_debug_device_list_show(struct seq_file *s, void *unused) /* Iterate over all heaps to find the matching heap */ for (i = 0; i < nvmap_dev->nr_carveouts; i++) { if (heap_type & nvmap_dev->heaps[i].heap_bit) { - if (nvmap_dev->heaps[i].carveout) { + if (nvmap_dev->heaps[i].carveout && (nvmap_block_to_heap + (nvmap_dev->heaps[i].carveout)->numa_node_id + != numa_id)) { n = rb_first(&nvmap_dev->heaps[i].carveout->device_names); break; } @@ -878,10 +912,11 @@ DEBUGFS_OPEN_FOPS(device_list); static int nvmap_debug_all_allocations_show(struct seq_file *s, void *unused) { - u32 heap_type = (u32)(uintptr_t)s->private; + struct debugfs_info *debugfs_information = (struct debugfs_info *)s->private; + u32 heap_type = debugfs_information->heap_bit; + int numa_id = debugfs_information->numa_id; struct rb_node *n; - spin_lock(&nvmap_dev->handle_lock); seq_printf(s, "%8s %11s %9s %6s %6s %6s %6s %8s\n", "BASE", "SIZE", "USERFLAGS", "REFS", @@ -894,12 +929,16 @@ static int nvmap_debug_all_allocations_show(struct seq_file *s, void *unused) rb_entry(n, struct nvmap_handle, node); int i = 0; - if (handle->alloc && handle->heap_type == heap_type) { + if (handle->alloc && handle->heap_type == debugfs_information->heap_bit) { phys_addr_t base = heap_type == NVMAP_HEAP_IOVMM ? 0 : handle->heap_pgalloc ? 0 : (handle->carveout->base); size_t size = K(handle->size); + if (heap_type != NVMAP_HEAP_IOVMM && + (nvmap_block_to_heap(handle->carveout)->numa_node_id != numa_id)) + continue; + next_page: if ((heap_type == NVMAP_HEAP_CARVEOUT_VPR) && handle->heap_pgalloc) { base = page_to_phys(handle->pgalloc.pages[i++]); @@ -933,7 +972,9 @@ DEBUGFS_OPEN_FOPS(all_allocations); static int nvmap_debug_orphan_handles_show(struct seq_file *s, void *unused) { - u32 heap_type = (u32)(uintptr_t)s->private; + struct debugfs_info *debugfs_information = (struct debugfs_info *)s->private; + u32 heap_type = debugfs_information->heap_bit; + int numa_id = debugfs_information->numa_id; struct rb_node *n; @@ -956,6 +997,11 @@ static int nvmap_debug_orphan_handles_show(struct seq_file *s, void *unused) (handle->carveout->base); size_t size = K(handle->size); + if (heap_type != NVMAP_HEAP_IOVMM && + (nvmap_block_to_heap(handle->carveout)->numa_node_id != + numa_id)) + continue; + next_page: if ((heap_type == NVMAP_HEAP_CARVEOUT_VPR) && handle->heap_pgalloc) { base = page_to_phys(handle->pgalloc.pages[i++]); @@ -990,7 +1036,9 @@ static int nvmap_debug_maps_show(struct seq_file *s, void *unused) { u64 total; struct nvmap_client *client; - u32 heap_type = (u32)(uintptr_t)s->private; + struct debugfs_info *debugfs_information = (struct debugfs_info *)s->private; + u32 heap_type = debugfs_information->heap_bit; + int numa_id = debugfs_information->numa_id; mutex_lock(&nvmap_dev->clients_lock); seq_printf(s, "%-18s %18s %8s %11s\n", @@ -1002,14 +1050,14 @@ static int nvmap_debug_maps_show(struct seq_file *s, void *unused) list_for_each_entry(client, &nvmap_dev->clients, list) { u64 client_total; client_stringify(client, s); - nvmap_get_client_mss(client, &client_total, heap_type); + nvmap_get_client_mss(client, &client_total, heap_type, numa_id); seq_printf(s, " %10lluK\n", K(client_total)); maps_stringify(client, s, heap_type); seq_printf(s, "\n"); } mutex_unlock(&nvmap_dev->clients_lock); - nvmap_get_total_mss(NULL, &total, heap_type); + nvmap_get_total_mss(NULL, &total, heap_type, numa_id); seq_printf(s, "%-18s %-18s %8s %10lluK\n", "total", "", "", K(total)); return 0; } @@ -1020,7 +1068,9 @@ static int nvmap_debug_clients_show(struct seq_file *s, void *unused) { u64 total; struct nvmap_client *client; - ulong heap_type = (ulong)s->private; + struct debugfs_info *debugfs_information = (struct debugfs_info *)s->private; + u32 heap_type = debugfs_information->heap_bit; + int numa_id = debugfs_information->numa_id; mutex_lock(&nvmap_dev->clients_lock); seq_printf(s, "%-18s %18s %8s %11s\n", @@ -1028,11 +1078,11 @@ static int nvmap_debug_clients_show(struct seq_file *s, void *unused) list_for_each_entry(client, &nvmap_dev->clients, list) { u64 client_total; client_stringify(client, s); - nvmap_get_client_mss(client, &client_total, heap_type); + nvmap_get_client_mss(client, &client_total, heap_type, numa_id); seq_printf(s, " %10lluK\n", K(client_total)); } mutex_unlock(&nvmap_dev->clients_lock); - nvmap_get_total_mss(NULL, &total, heap_type); + nvmap_get_total_mss(NULL, &total, heap_type, numa_id); seq_printf(s, "%-18s %18s %8s %10lluK\n", "total", "", "", K(total)); return 0; } @@ -1291,7 +1341,7 @@ static int nvmap_debug_iovmm_procrank_show(struct seq_file *s, void *unused) } mutex_unlock(&dev->clients_lock); - nvmap_get_total_mss(&total_pss, &total_memory, NVMAP_HEAP_IOVMM); + nvmap_get_total_mss(&total_pss, &total_memory, NVMAP_HEAP_IOVMM, NUMA_NO_NODE); seq_printf(s, "%-18s %18s %8s %10lluK %10lluK\n", "total", "", "", K(total_pss), K(total_memory)); return 0; @@ -1305,7 +1355,7 @@ ulong nvmap_iovmm_get_used_pages(void) { u64 total; - nvmap_get_total_mss(NULL, &total, NVMAP_HEAP_IOVMM); + nvmap_get_total_mss(NULL, &total, NVMAP_HEAP_IOVMM, NUMA_NO_NODE); return total >> PAGE_SHIFT; } #endif @@ -1315,28 +1365,32 @@ static void nvmap_iovmm_debugfs_init(void) if (!IS_ERR_OR_NULL(nvmap_dev->debug_root)) { struct dentry *iovmm_root = debugfs_create_dir("iovmm", nvmap_dev->debug_root); + + iovmm_debugfs_info.heap_bit = NVMAP_HEAP_IOVMM; + iovmm_debugfs_info.numa_id = NUMA_NO_NODE; + if (!IS_ERR_OR_NULL(iovmm_root)) { debugfs_create_file("clients", S_IRUGO, iovmm_root, - (void *)(uintptr_t)NVMAP_HEAP_IOVMM, + (void *)&iovmm_debugfs_info, &debug_clients_fops); debugfs_create_file("allocations", S_IRUGO, iovmm_root, - (void *)(uintptr_t)NVMAP_HEAP_IOVMM, + (void *)&iovmm_debugfs_info, &debug_allocations_fops); debugfs_create_file("all_allocations", S_IRUGO, - iovmm_root, (void *)(uintptr_t)NVMAP_HEAP_IOVMM, + iovmm_root, (void *)&iovmm_debugfs_info, &debug_all_allocations_fops); debugfs_create_file("orphan_handles", S_IRUGO, - iovmm_root, (void *)(uintptr_t)NVMAP_HEAP_IOVMM, + iovmm_root, (void *)&iovmm_debugfs_info, &debug_orphan_handles_fops); debugfs_create_file("maps", S_IRUGO, iovmm_root, - (void *)(uintptr_t)NVMAP_HEAP_IOVMM, + (void *)&iovmm_debugfs_info, &debug_maps_fops); debugfs_create_file("free_size", S_IRUGO, iovmm_root, - (void *)(uintptr_t)NVMAP_HEAP_IOVMM, + (void *)&iovmm_debugfs_info, &debug_free_size_fops); #ifdef NVMAP_CONFIG_DEBUG_MAPS debugfs_create_file("device_list", S_IRUGO, iovmm_root, - (void *)(uintptr_t)NVMAP_HEAP_IOVMM, + (void *)&iovmm_debugfs_info, &debug_device_list_fops); #endif /* NVMAP_CONFIG_DEBUG_MAPS */ diff --git a/drivers/video/tegra/nvmap/nvmap_handle.c b/drivers/video/tegra/nvmap/nvmap_handle.c index 9953b78c..5f7c080b 100644 --- a/drivers/video/tegra/nvmap/nvmap_handle.c +++ b/drivers/video/tegra/nvmap/nvmap_handle.c @@ -185,7 +185,7 @@ struct nvmap_handle_ref *nvmap_create_handle_from_va(struct nvmap_client *client size = vma->vm_end - vaddr; /* Don't allow exuberantly large sizes. */ - if (!is_nvmap_memory_available(size, NVMAP_HEAP_IOVMM)) { + if (!is_nvmap_memory_available(size, NVMAP_HEAP_IOVMM, NUMA_NO_NODE)) { pr_debug("Cannot allocate %zu bytes.\n", size); nvmap_release_mmap_read_lock(mm); return ERR_PTR(-ENOMEM); diff --git a/drivers/video/tegra/nvmap/nvmap_heap.c b/drivers/video/tegra/nvmap/nvmap_heap.c index 485cc708..df357ace 100644 --- a/drivers/video/tegra/nvmap/nvmap_heap.c +++ b/drivers/video/tegra/nvmap/nvmap_heap.c @@ -506,6 +506,7 @@ struct nvmap_heap *nvmap_heap_create(struct device *parent, h->can_alloc = !!co->can_alloc; h->is_ivm = co->is_ivm; h->is_gpu_co = co->is_gpu_co; + h->numa_node_id = co->numa_node_id; h->granule_size = co->granule_size; h->len = len; h->free_size = len; @@ -517,6 +518,7 @@ struct nvmap_heap *nvmap_heap_create(struct device *parent, if (co->pm_ops.idle) h->pm_ops.idle = co->pm_ops.idle; + h->carevout_debugfs_info = kmalloc(sizeof(struct debugfs_info), GFP_KERNEL); INIT_LIST_HEAD(&h->all_list); mutex_init(&h->lock); #ifdef NVMAP_CONFIG_DEBUG_MAPS @@ -546,6 +548,7 @@ struct nvmap_heap *nvmap_heap_create(struct device *parent, co->name, (void *)(uintptr_t)base, len/1024); return h; fail: + kfree(h->carevout_debugfs_info); if (h->dma_dev->kobj.name) kfree_const(h->dma_dev->kobj.name); kfree(h); @@ -562,6 +565,7 @@ void nvmap_heap_destroy(struct nvmap_heap *heap) if (heap->is_ivm) kfree(heap->name); + kfree(heap->carevout_debugfs_info); #ifdef NVMAP_LOADABLE_MODULE nvmap_dma_release_coherent_memory((struct dma_coherent_mem_replica *) heap->dma_dev->dma_mem); diff --git a/drivers/video/tegra/nvmap/nvmap_heap.h b/drivers/video/tegra/nvmap/nvmap_heap.h index e4d2b446..3e60f289 100644 --- a/drivers/video/tegra/nvmap/nvmap_heap.h +++ b/drivers/video/tegra/nvmap/nvmap_heap.h @@ -18,6 +18,15 @@ struct nvmap_heap_block { struct nvmap_handle *handle; }; +/* + * Info to be passed to debugfs nodes, so as to provide heap type and + * numa node id. + */ +struct debugfs_info { + unsigned int heap_bit; + int numa_id; +}; + struct nvmap_heap { struct list_head all_list; struct mutex lock; @@ -33,6 +42,7 @@ struct nvmap_heap { bool is_ivm; bool is_gpu_co; u32 granule_size; + int numa_node_id; bool can_alloc; /* Used only if is_ivm == true */ unsigned int peer; /* Used only if is_ivm == true */ unsigned int vm_id; /* Used only if is_ivm == true */ @@ -40,6 +50,7 @@ struct nvmap_heap { #ifdef NVMAP_CONFIG_DEBUG_MAPS struct rb_root device_names; #endif /* NVMAP_CONFIG_DEBUG_MAPS */ + struct debugfs_info *carevout_debugfs_info; /* Used for storing debugfs info */ }; struct list_block { diff --git a/drivers/video/tegra/nvmap/nvmap_init.c b/drivers/video/tegra/nvmap/nvmap_init.c index dd36eebd..c2a335e6 100644 --- a/drivers/video/tegra/nvmap/nvmap_init.c +++ b/drivers/video/tegra/nvmap/nvmap_init.c @@ -108,6 +108,7 @@ static struct nvmap_platform_carveout nvmap_carveouts[] = { #ifdef NVMAP_CONFIG_VPR_RESIZE .dma_info = &generic_dma_info, #endif + .numa_node_id = 0, }, [1] = { .name = "vpr", @@ -120,6 +121,7 @@ static struct nvmap_platform_carveout nvmap_carveouts[] = { .dma_info = &vpr_dma_info, #endif .enable_static_dma_map = true, + .numa_node_id = 0, }, [2] = { .name = "vidmem", @@ -128,41 +130,55 @@ static struct nvmap_platform_carveout nvmap_carveouts[] = { .size = 0, .disable_dynamic_dma_map = true, .no_cpu_access = true, + .numa_node_id = 0, }, [3] = { .name = "fsi", .usage_mask = NVMAP_HEAP_CARVEOUT_FSI, .base = 0, .size = 0, + .numa_node_id = 0, }, [4] = { - .name = "gpu", + .name = "gpu0", .usage_mask = NVMAP_HEAP_CARVEOUT_GPU, .base = 0, .size = 0, + .numa_node_id = 0, + }, + [5] = { + .name = "gpu1", + .usage_mask = NVMAP_HEAP_CARVEOUT_GPU, + .base = 0, + .size = 0, + .numa_node_id = 1, }, /* Need uninitialized entries for IVM carveouts */ - [5] = { - .name = NULL, - .usage_mask = NVMAP_HEAP_CARVEOUT_IVM, - }, [6] = { .name = NULL, .usage_mask = NVMAP_HEAP_CARVEOUT_IVM, + .numa_node_id = 0, }, [7] = { .name = NULL, .usage_mask = NVMAP_HEAP_CARVEOUT_IVM, + .numa_node_id = 0, }, [8] = { .name = NULL, .usage_mask = NVMAP_HEAP_CARVEOUT_IVM, + .numa_node_id = 0, + }, + [9] = { + .name = NULL, + .usage_mask = NVMAP_HEAP_CARVEOUT_IVM, + .numa_node_id = 0, }, }; static struct nvmap_platform_data nvmap_data = { .carveouts = nvmap_carveouts, - .nr_carveouts = 5, + .nr_carveouts = 6, }; static struct nvmap_platform_carveout *nvmap_get_carveout_pdata(const char *name) @@ -944,8 +960,10 @@ int __init nvmap_init(struct platform_device *pdev) if (of_device_is_available(it.node) && !of_device_is_compatible(it.node, "nvidia,ivm_carveout")) { /* Read granule size in case of gpu carveout */ - if (of_device_is_compatible(it.node, "nvidia,gpu_carveout") - && of_property_read_u32(it.node, "granule-size", &granule_size)) { + if ((of_device_is_compatible(it.node, "nvidia,gpu0_carveout") || + of_device_is_compatible(it.node, "nvidia,gpu1_carveout")) && + of_property_read_u32(it.node, "granule-size", &granule_size + )) { pr_err("granule-size property is missing\n"); return -EINVAL; } diff --git a/drivers/video/tegra/nvmap/nvmap_ioctl.c b/drivers/video/tegra/nvmap/nvmap_ioctl.c index 29135405..6d6d0923 100644 --- a/drivers/video/tegra/nvmap/nvmap_ioctl.c +++ b/drivers/video/tegra/nvmap/nvmap_ioctl.c @@ -227,7 +227,7 @@ int nvmap_ioctl_alloc(struct file *filp, void __user *arg) page_sz = granule_size; } - if (!is_nvmap_memory_available(handle->size, op.heap_mask)) { + if (!is_nvmap_memory_available(handle->size, op.heap_mask, op.numa_nid)) { nvmap_handle_put(handle); return -ENOMEM; } diff --git a/drivers/video/tegra/nvmap/nvmap_priv.h b/drivers/video/tegra/nvmap/nvmap_priv.h index 232326cb..e5830b64 100644 --- a/drivers/video/tegra/nvmap/nvmap_priv.h +++ b/drivers/video/tegra/nvmap/nvmap_priv.h @@ -915,7 +915,7 @@ static inline struct dma_buf *nvmap_id_array_id_release(struct xarray *xarr, u32 #endif void *nvmap_dmabuf_get_drv_data(struct dma_buf *dmabuf, struct device *dev); -bool is_nvmap_memory_available(size_t size, uint32_t heap); +bool is_nvmap_memory_available(size_t size, uint32_t heap, int numa_nid); int system_heap_free_mem(unsigned long *mem_val); #ifdef NVMAP_CONFIG_DEBUG_MAPS diff --git a/include/linux/nvmap.h b/include/linux/nvmap.h index fa02dcf6..fdff8e60 100644 --- a/include/linux/nvmap.h +++ b/include/linux/nvmap.h @@ -96,6 +96,7 @@ struct nvmap_platform_carveout { struct nvmap_pm_ops pm_ops; bool is_gpu_co; /* Gpu carveout is treated differently */ u32 granule_size; /* Granule size for gpu carveout */ + int numa_node_id; /* NUMA node id from which the carveout is allocated from */ }; struct nvmap_platform_data {