Re: [PATCH 1/9] drm/ttm: ttm_fault callback to allow driver to handle bo placement V2
Jerome Glisse wrote: On fault the driver is given the opportunity to perform any operation it sees fit in order to place the buffer into a CPU visible area of memory. This patch doesn't break TTM users, nouveau, vmwgfx and radeon should keep working properly. Future patch will take advantage of this infrastructure and remove the old path from TTM once driver are converted. V2 return VM_FAULT_NOPAGE if callback return -EBUSY or -ERESTARTSYS Signed-off-by: Jerome Glisse jgli...@redhat.com Jerome, See inline comments below and 1) Please make sure the patch passes checkpatch.pl without warnings or errors before submitting. This patch has 14 warnings. 2) There are a number of line spacing changes (empty newline changes) and line break changes. Please remove them from the patch. --- drivers/gpu/drm/ttm/ttm_bo.c |3 +- drivers/gpu/drm/ttm/ttm_bo_util.c | 92 + drivers/gpu/drm/ttm/ttm_bo_vm.c | 56 -- include/drm/ttm/ttm_bo_api.h |1 + include/drm/ttm/ttm_bo_driver.h | 30 5 files changed, 105 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index c7320ce..28f3fcf 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1581,7 +1581,8 @@ void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo) if (!bdev-dev_mapping) return; - + if (bdev-driver-io_mem_free) + bdev-driver-io_mem_free(bdev, bo-mem); unmap_mapping_range(bdev-dev_mapping, offset, holelen, 1); } The user-space mappings must be taken down *before* the IO space is released, but please also see at the bottom for a design change for this. EXPORT_SYMBOL(ttm_bo_unmap_virtual); diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 3f72fe1..10c5fc6 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -84,26 +84,36 @@ int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, void **virtual) { struct ttm_mem_type_manager *man = bdev-man[mem-mem_type]; - unsigned long bus_offset; - unsigned long bus_size; - unsigned long bus_base; + struct ttm_bus_placement pl; int ret; void *addr; *virtual = NULL; - ret = ttm_bo_pci_offset(bdev, mem, bus_base, bus_offset, bus_size); - if (ret || bus_size == 0) - return ret; + if (bdev-driver-io_mem_reserve) { + ret = bdev-driver-io_mem_reserve(bdev, mem, pl); + if (unlikely(ret != 0)) { + return ret; + } + } else { + ret = ttm_bo_pci_offset(bdev, mem, pl.base, pl.offset, pl.size); + if (unlikely(ret != 0) || pl.size == 0) { + return ret; + } + pl.is_iomem = (pl.size != 0); I fail to see how pl.size can be == 0 here? + } if (!(man-flags TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) - addr = (void *)(((u8 *) man-io_addr) + bus_offset); + addr = (void *)(pl.base + pl.offset); This is incorrect. man-io_addr is the virtual kernel address of an existing iomap covering the whole aperture, if the driver has choosen to set up one. This is not practical on 32-bit systems, due to the limited vmalloc / ioremap space but may well be on 64-bit system. else { if (mem-placement TTM_PL_FLAG_WC) - addr = ioremap_wc(bus_base + bus_offset, bus_size); + addr = ioremap_wc(pl.base + pl.offset, pl.size); else - addr = ioremap_nocache(bus_base + bus_offset, bus_size); - if (!addr) + addr = ioremap_nocache(pl.base + pl.offset, pl.size); + if (!addr) { + if (bdev-driver-io_mem_free) + bdev-driver-io_mem_free(bdev, mem); return -ENOMEM; + } } *virtual = addr; return 0; @@ -118,6 +128,8 @@ void ttm_mem_reg_iounmap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, if (virtual (man-flags TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) iounmap(virtual); + if (bdev-driver-io_mem_free) + bdev-driver-io_mem_free(bdev, mem); } static int ttm_copy_io_page(void *dst, void *src, unsigned long page) @@ -440,13 +452,12 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, unsigned long num_pages, struct ttm_bo_kmap_obj *map) { + struct ttm_bus_placement pl; int ret; - unsigned long bus_base; - unsigned long bus_offset; - unsigned long bus_size; BUG_ON(!list_empty(bo-swap)); map-virtual = NULL; + map-bo = bo; if
[PATCH 1/9] drm/ttm: ttm_fault callback to allow driver to handle bo placement V2
On fault the driver is given the opportunity to perform any operation it sees fit in order to place the buffer into a CPU visible area of memory. This patch doesn't break TTM users, nouveau, vmwgfx and radeon should keep working properly. Future patch will take advantage of this infrastructure and remove the old path from TTM once driver are converted. V2 return VM_FAULT_NOPAGE if callback return -EBUSY or -ERESTARTSYS Signed-off-by: Jerome Glisse jgli...@redhat.com --- drivers/gpu/drm/ttm/ttm_bo.c |3 +- drivers/gpu/drm/ttm/ttm_bo_util.c | 92 + drivers/gpu/drm/ttm/ttm_bo_vm.c | 56 -- include/drm/ttm/ttm_bo_api.h |1 + include/drm/ttm/ttm_bo_driver.h | 30 5 files changed, 105 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index d2b2482..2a808fc 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1588,7 +1588,8 @@ void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo) if (!bdev-dev_mapping) return; - + if (bdev-driver-io_mem_free) + bdev-driver-io_mem_free(bdev, bo-mem); unmap_mapping_range(bdev-dev_mapping, offset, holelen, 1); } EXPORT_SYMBOL(ttm_bo_unmap_virtual); diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index db43b30..efce42c 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -85,26 +85,36 @@ int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, void **virtual) { struct ttm_mem_type_manager *man = bdev-man[mem-mem_type]; - unsigned long bus_offset; - unsigned long bus_size; - unsigned long bus_base; + struct ttm_bus_placement pl; int ret; void *addr; *virtual = NULL; - ret = ttm_bo_pci_offset(bdev, mem, bus_base, bus_offset, bus_size); - if (ret || bus_size == 0) - return ret; + if (bdev-driver-io_mem_reserve) { + ret = bdev-driver-io_mem_reserve(bdev, mem, pl); + if (unlikely(ret != 0)) { + return ret; + } + } else { + ret = ttm_bo_pci_offset(bdev, mem, pl.base, pl.offset, pl.size); + if (unlikely(ret != 0) || pl.size == 0) { + return ret; + } + pl.is_iomem = (pl.size != 0); + } if (!(man-flags TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) - addr = (void *)(((u8 *) man-io_addr) + bus_offset); + addr = (void *)(pl.base + pl.offset); else { if (mem-placement TTM_PL_FLAG_WC) - addr = ioremap_wc(bus_base + bus_offset, bus_size); + addr = ioremap_wc(pl.base + pl.offset, pl.size); else - addr = ioremap_nocache(bus_base + bus_offset, bus_size); - if (!addr) + addr = ioremap_nocache(pl.base + pl.offset, pl.size); + if (!addr) { + if (bdev-driver-io_mem_free) + bdev-driver-io_mem_free(bdev, mem); return -ENOMEM; + } } *virtual = addr; return 0; @@ -119,6 +129,8 @@ void ttm_mem_reg_iounmap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, if (virtual (man-flags TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) iounmap(virtual); + if (bdev-driver-io_mem_free) + bdev-driver-io_mem_free(bdev, mem); } static int ttm_copy_io_page(void *dst, void *src, unsigned long page) @@ -442,13 +454,12 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, unsigned long num_pages, struct ttm_bo_kmap_obj *map) { + struct ttm_bus_placement pl; int ret; - unsigned long bus_base; - unsigned long bus_offset; - unsigned long bus_size; BUG_ON(!list_empty(bo-swap)); map-virtual = NULL; + map-bo = bo; if (num_pages bo-num_pages) return -EINVAL; if (start_page bo-num_pages) @@ -457,16 +468,24 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, if (num_pages 1 !DRM_SUSER(DRM_CURPROC)) return -EPERM; #endif - ret = ttm_bo_pci_offset(bo-bdev, bo-mem, bus_base, - bus_offset, bus_size); - if (ret) - return ret; - if (bus_size == 0) { + if (bo-bdev-driver-io_mem_reserve) { + ret = bo-bdev-driver-io_mem_reserve(bo-bdev, bo-mem, pl); + if (unlikely(ret != 0)) { + return ret; + } + } else { + ret = ttm_bo_pci_offset(bo-bdev, bo-mem, pl.base, pl.offset, pl.size); + if
[PATCH 1/9] drm/ttm: ttm_fault callback to allow driver to handle bo placement V2
On fault the driver is given the opportunity to perform any operation it sees fit in order to place the buffer into a CPU visible area of memory. This patch doesn't break TTM users, nouveau, vmwgfx and radeon should keep working properly. Future patch will take advantage of this infrastructure and remove the old path from TTM once driver are converted. V2 return VM_FAULT_NOPAGE if callback return -EBUSY or -ERESTARTSYS Signed-off-by: Jerome Glisse jgli...@redhat.com --- drivers/gpu/drm/ttm/ttm_bo.c |3 +- drivers/gpu/drm/ttm/ttm_bo_util.c | 92 + drivers/gpu/drm/ttm/ttm_bo_vm.c | 56 -- include/drm/ttm/ttm_bo_api.h |1 + include/drm/ttm/ttm_bo_driver.h | 30 5 files changed, 105 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index c7320ce..28f3fcf 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1581,7 +1581,8 @@ void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo) if (!bdev-dev_mapping) return; - + if (bdev-driver-io_mem_free) + bdev-driver-io_mem_free(bdev, bo-mem); unmap_mapping_range(bdev-dev_mapping, offset, holelen, 1); } EXPORT_SYMBOL(ttm_bo_unmap_virtual); diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 3f72fe1..10c5fc6 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -84,26 +84,36 @@ int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, void **virtual) { struct ttm_mem_type_manager *man = bdev-man[mem-mem_type]; - unsigned long bus_offset; - unsigned long bus_size; - unsigned long bus_base; + struct ttm_bus_placement pl; int ret; void *addr; *virtual = NULL; - ret = ttm_bo_pci_offset(bdev, mem, bus_base, bus_offset, bus_size); - if (ret || bus_size == 0) - return ret; + if (bdev-driver-io_mem_reserve) { + ret = bdev-driver-io_mem_reserve(bdev, mem, pl); + if (unlikely(ret != 0)) { + return ret; + } + } else { + ret = ttm_bo_pci_offset(bdev, mem, pl.base, pl.offset, pl.size); + if (unlikely(ret != 0) || pl.size == 0) { + return ret; + } + pl.is_iomem = (pl.size != 0); + } if (!(man-flags TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) - addr = (void *)(((u8 *) man-io_addr) + bus_offset); + addr = (void *)(pl.base + pl.offset); else { if (mem-placement TTM_PL_FLAG_WC) - addr = ioremap_wc(bus_base + bus_offset, bus_size); + addr = ioremap_wc(pl.base + pl.offset, pl.size); else - addr = ioremap_nocache(bus_base + bus_offset, bus_size); - if (!addr) + addr = ioremap_nocache(pl.base + pl.offset, pl.size); + if (!addr) { + if (bdev-driver-io_mem_free) + bdev-driver-io_mem_free(bdev, mem); return -ENOMEM; + } } *virtual = addr; return 0; @@ -118,6 +128,8 @@ void ttm_mem_reg_iounmap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, if (virtual (man-flags TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) iounmap(virtual); + if (bdev-driver-io_mem_free) + bdev-driver-io_mem_free(bdev, mem); } static int ttm_copy_io_page(void *dst, void *src, unsigned long page) @@ -440,13 +452,12 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, unsigned long num_pages, struct ttm_bo_kmap_obj *map) { + struct ttm_bus_placement pl; int ret; - unsigned long bus_base; - unsigned long bus_offset; - unsigned long bus_size; BUG_ON(!list_empty(bo-swap)); map-virtual = NULL; + map-bo = bo; if (num_pages bo-num_pages) return -EINVAL; if (start_page bo-num_pages) @@ -455,16 +466,24 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, if (num_pages 1 !DRM_SUSER(DRM_CURPROC)) return -EPERM; #endif - ret = ttm_bo_pci_offset(bo-bdev, bo-mem, bus_base, - bus_offset, bus_size); - if (ret) - return ret; - if (bus_size == 0) { + if (bo-bdev-driver-io_mem_reserve) { + ret = bo-bdev-driver-io_mem_reserve(bo-bdev, bo-mem, pl); + if (unlikely(ret != 0)) { + return ret; + } + } else { + ret = ttm_bo_pci_offset(bo-bdev, bo-mem, pl.base, pl.offset, pl.size); + if
[PATCH 1/9] drm/ttm: ttm_fault callback to allow driver to handle bo placement V2
On fault the driver is given the opportunity to perform any operation it sees fit in order to place the buffer into a CPU visible area of memory. This patch doesn't break TTM users, nouveau, vmwgfx and radeon should keep working properly. Future patch will take advantage of this infrastructure and remove the old path from TTM once driver are converted. V2 return VM_FAULT_NOPAGE if callback return -EBUSY or -ERESTARTSYS Signed-off-by: Jerome Glisse jgli...@redhat.com --- drivers/gpu/drm/ttm/ttm_bo.c |3 +- drivers/gpu/drm/ttm/ttm_bo_util.c | 92 + drivers/gpu/drm/ttm/ttm_bo_vm.c | 56 -- include/drm/ttm/ttm_bo_api.h |1 + include/drm/ttm/ttm_bo_driver.h | 30 5 files changed, 105 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index c7320ce..28f3fcf 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1581,7 +1581,8 @@ void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo) if (!bdev-dev_mapping) return; - + if (bdev-driver-io_mem_free) + bdev-driver-io_mem_free(bdev, bo-mem); unmap_mapping_range(bdev-dev_mapping, offset, holelen, 1); } EXPORT_SYMBOL(ttm_bo_unmap_virtual); diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 3f72fe1..10c5fc6 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -84,26 +84,36 @@ int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, void **virtual) { struct ttm_mem_type_manager *man = bdev-man[mem-mem_type]; - unsigned long bus_offset; - unsigned long bus_size; - unsigned long bus_base; + struct ttm_bus_placement pl; int ret; void *addr; *virtual = NULL; - ret = ttm_bo_pci_offset(bdev, mem, bus_base, bus_offset, bus_size); - if (ret || bus_size == 0) - return ret; + if (bdev-driver-io_mem_reserve) { + ret = bdev-driver-io_mem_reserve(bdev, mem, pl); + if (unlikely(ret != 0)) { + return ret; + } + } else { + ret = ttm_bo_pci_offset(bdev, mem, pl.base, pl.offset, pl.size); + if (unlikely(ret != 0) || pl.size == 0) { + return ret; + } + pl.is_iomem = (pl.size != 0); + } if (!(man-flags TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) - addr = (void *)(((u8 *) man-io_addr) + bus_offset); + addr = (void *)(pl.base + pl.offset); else { if (mem-placement TTM_PL_FLAG_WC) - addr = ioremap_wc(bus_base + bus_offset, bus_size); + addr = ioremap_wc(pl.base + pl.offset, pl.size); else - addr = ioremap_nocache(bus_base + bus_offset, bus_size); - if (!addr) + addr = ioremap_nocache(pl.base + pl.offset, pl.size); + if (!addr) { + if (bdev-driver-io_mem_free) + bdev-driver-io_mem_free(bdev, mem); return -ENOMEM; + } } *virtual = addr; return 0; @@ -118,6 +128,8 @@ void ttm_mem_reg_iounmap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, if (virtual (man-flags TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) iounmap(virtual); + if (bdev-driver-io_mem_free) + bdev-driver-io_mem_free(bdev, mem); } static int ttm_copy_io_page(void *dst, void *src, unsigned long page) @@ -440,13 +452,12 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, unsigned long num_pages, struct ttm_bo_kmap_obj *map) { + struct ttm_bus_placement pl; int ret; - unsigned long bus_base; - unsigned long bus_offset; - unsigned long bus_size; BUG_ON(!list_empty(bo-swap)); map-virtual = NULL; + map-bo = bo; if (num_pages bo-num_pages) return -EINVAL; if (start_page bo-num_pages) @@ -455,16 +466,24 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, if (num_pages 1 !DRM_SUSER(DRM_CURPROC)) return -EPERM; #endif - ret = ttm_bo_pci_offset(bo-bdev, bo-mem, bus_base, - bus_offset, bus_size); - if (ret) - return ret; - if (bus_size == 0) { + if (bo-bdev-driver-io_mem_reserve) { + ret = bo-bdev-driver-io_mem_reserve(bo-bdev, bo-mem, pl); + if (unlikely(ret != 0)) { + return ret; + } + } else { + ret = ttm_bo_pci_offset(bo-bdev, bo-mem, pl.base, pl.offset, pl.size); + if