Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'drm-misc-next-fixes-2024-05-16' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next

drm-misc-next-fixes for v6.10-rc1:
- VM_BIND fix for nouveau.
- Lots of panthor fixes:
* Fixes for panthor's heap logical block.
* Reset on unrecoverable fault
* Fix VM references.
* Reset fix.
- xlnx compile and doc fixes.

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/54d2c8b9-8b04-45fc-b483-200ffac9d344@linux.intel.com

+123 -73
+3
drivers/gpu/drm/nouveau/nouveau_abi16.c
··· 272 272 getparam->value = (u64)ttm_resource_manager_usage(vram_mgr); 273 273 break; 274 274 } 275 + case NOUVEAU_GETPARAM_HAS_VMA_TILEMODE: 276 + getparam->value = 1; 277 + break; 275 278 default: 276 279 NV_PRINTK(dbg, cli, "unknown parameter %lld\n", getparam->param); 277 280 return -EINVAL;
+19 -25
drivers/gpu/drm/nouveau/nouveau_bo.c
··· 241 241 } 242 242 243 243 nvbo->contig = !(tile_flags & NOUVEAU_GEM_TILE_NONCONTIG); 244 - if (!nouveau_cli_uvmm(cli) || internal) { 245 - /* for BO noVM allocs, don't assign kinds */ 246 - if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI) { 247 - nvbo->kind = (tile_flags & 0x0000ff00) >> 8; 248 - if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) { 249 - kfree(nvbo); 250 - return ERR_PTR(-EINVAL); 251 - } 252 244 253 - nvbo->comp = mmu->kind[nvbo->kind] != nvbo->kind; 254 - } else if (cli->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { 255 - nvbo->kind = (tile_flags & 0x00007f00) >> 8; 256 - nvbo->comp = (tile_flags & 0x00030000) >> 16; 257 - if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) { 258 - kfree(nvbo); 259 - return ERR_PTR(-EINVAL); 260 - } 261 - } else { 262 - nvbo->zeta = (tile_flags & 0x00000007); 245 + if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI) { 246 + nvbo->kind = (tile_flags & 0x0000ff00) >> 8; 247 + if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) { 248 + kfree(nvbo); 249 + return ERR_PTR(-EINVAL); 263 250 } 264 - nvbo->mode = tile_mode; 265 251 252 + nvbo->comp = mmu->kind[nvbo->kind] != nvbo->kind; 253 + } else if (cli->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { 254 + nvbo->kind = (tile_flags & 0x00007f00) >> 8; 255 + nvbo->comp = (tile_flags & 0x00030000) >> 16; 256 + if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) { 257 + kfree(nvbo); 258 + return ERR_PTR(-EINVAL); 259 + } 260 + } else { 261 + nvbo->zeta = (tile_flags & 0x00000007); 262 + } 263 + nvbo->mode = tile_mode; 264 + 265 + if (!nouveau_cli_uvmm(cli) || internal) { 266 266 /* Determine the desirable target GPU page size for the buffer. */ 267 267 for (i = 0; i < vmm->page_nr; i++) { 268 268 /* Because we cannot currently allow VMM maps to fail ··· 304 304 } 305 305 nvbo->page = vmm->page[pi].shift; 306 306 } else { 307 - /* reject other tile flags when in VM mode. */ 308 - if (tile_mode) 309 - return ERR_PTR(-EINVAL); 310 - if (tile_flags & ~NOUVEAU_GEM_TILE_NONCONTIG) 311 - return ERR_PTR(-EINVAL); 312 - 313 307 /* Determine the desirable target GPU page size for the buffer. */ 314 308 for (i = 0; i < vmm->page_nr; i++) { 315 309 /* Because we cannot currently allow VMM maps to fail
+2 -6
drivers/gpu/drm/panthor/panthor_device.c
··· 129 129 panthor_gpu_l2_power_on(ptdev); 130 130 panthor_mmu_post_reset(ptdev); 131 131 ret = panthor_fw_post_reset(ptdev); 132 - if (ret) 133 - goto out_dev_exit; 134 - 135 132 atomic_set(&ptdev->reset.pending, 0); 136 - panthor_sched_post_reset(ptdev); 137 - 138 - out_dev_exit: 133 + panthor_sched_post_reset(ptdev, ret != 0); 139 134 drm_dev_exit(cookie); 140 135 141 136 if (ret) { ··· 288 293 PANTHOR_EXCEPTION(ACTIVE), 289 294 PANTHOR_EXCEPTION(CS_RES_TERM), 290 295 PANTHOR_EXCEPTION(CS_CONFIG_FAULT), 296 + PANTHOR_EXCEPTION(CS_UNRECOVERABLE), 291 297 PANTHOR_EXCEPTION(CS_ENDPOINT_FAULT), 292 298 PANTHOR_EXCEPTION(CS_BUS_FAULT), 293 299 PANTHOR_EXCEPTION(CS_INSTR_INVALID),
+1
drivers/gpu/drm/panthor/panthor_device.h
··· 216 216 DRM_PANTHOR_EXCEPTION_CS_RES_TERM = 0x0f, 217 217 DRM_PANTHOR_EXCEPTION_MAX_NON_FAULT = 0x3f, 218 218 DRM_PANTHOR_EXCEPTION_CS_CONFIG_FAULT = 0x40, 219 + DRM_PANTHOR_EXCEPTION_CS_UNRECOVERABLE = 0x41, 219 220 DRM_PANTHOR_EXCEPTION_CS_ENDPOINT_FAULT = 0x44, 220 221 DRM_PANTHOR_EXCEPTION_CS_BUS_FAULT = 0x48, 221 222 DRM_PANTHOR_EXCEPTION_CS_INSTR_INVALID = 0x49,
+3 -2
drivers/gpu/drm/panthor/panthor_fw.c
··· 453 453 454 454 ret = panthor_kernel_bo_vmap(mem); 455 455 if (ret) { 456 - panthor_kernel_bo_destroy(panthor_fw_vm(ptdev), mem); 456 + panthor_kernel_bo_destroy(mem); 457 457 return ERR_PTR(ret); 458 458 } 459 459 ··· 1134 1134 panthor_fw_stop(ptdev); 1135 1135 1136 1136 list_for_each_entry(section, &ptdev->fw->sections, node) 1137 - panthor_kernel_bo_destroy(panthor_fw_vm(ptdev), section->mem); 1137 + panthor_kernel_bo_destroy(section->mem); 1138 1138 1139 1139 /* We intentionally don't call panthor_vm_idle() and let 1140 1140 * panthor_mmu_unplug() release the AS we acquired with ··· 1142 1142 * state to keep the active_refcnt balanced. 1143 1143 */ 1144 1144 panthor_vm_put(ptdev->fw->vm); 1145 + ptdev->fw->vm = NULL; 1145 1146 1146 1147 panthor_gpu_power_off(ptdev, L2, ptdev->gpu_info.l2_present, 20000); 1147 1148 }
+5 -3
drivers/gpu/drm/panthor/panthor_gem.c
··· 26 26 27 27 /** 28 28 * panthor_kernel_bo_destroy() - Destroy a kernel buffer object 29 - * @vm: The VM this BO was mapped to. 30 29 * @bo: Kernel buffer object to destroy. If NULL or an ERR_PTR(), the destruction 31 30 * is skipped. 32 31 */ 33 - void panthor_kernel_bo_destroy(struct panthor_vm *vm, 34 - struct panthor_kernel_bo *bo) 32 + void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo) 35 33 { 34 + struct panthor_vm *vm; 36 35 int ret; 37 36 38 37 if (IS_ERR_OR_NULL(bo)) 39 38 return; 40 39 40 + vm = bo->vm; 41 41 panthor_kernel_bo_vunmap(bo); 42 42 43 43 if (drm_WARN_ON(bo->obj->dev, ··· 53 53 drm_gem_object_put(bo->obj); 54 54 55 55 out_free_bo: 56 + panthor_vm_put(vm); 56 57 kfree(bo); 57 58 } 58 59 ··· 107 106 if (ret) 108 107 goto err_free_va; 109 108 109 + kbo->vm = panthor_vm_get(vm); 110 110 bo->exclusive_vm_root_gem = panthor_vm_root_gem(vm); 111 111 drm_gem_object_get(bo->exclusive_vm_root_gem); 112 112 bo->base.base.resv = bo->exclusive_vm_root_gem->resv;
+6 -2
drivers/gpu/drm/panthor/panthor_gem.h
··· 62 62 struct drm_gem_object *obj; 63 63 64 64 /** 65 + * @vm: VM this private buffer is attached to. 66 + */ 67 + struct panthor_vm *vm; 68 + 69 + /** 65 70 * @va_node: VA space allocated to this GEM. 66 71 */ 67 72 struct drm_mm_node va_node; ··· 141 136 size_t size, u32 bo_flags, u32 vm_map_flags, 142 137 u64 gpu_va); 143 138 144 - void panthor_kernel_bo_destroy(struct panthor_vm *vm, 145 - struct panthor_kernel_bo *bo); 139 + void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo); 146 140 147 141 #endif /* __PANTHOR_GEM_H__ */
+22 -14
drivers/gpu/drm/panthor/panthor_heap.c
··· 127 127 heap->chunk_count--; 128 128 mutex_unlock(&heap->lock); 129 129 130 - panthor_kernel_bo_destroy(vm, chunk->bo); 130 + panthor_kernel_bo_destroy(chunk->bo); 131 131 kfree(chunk); 132 132 } 133 133 ··· 183 183 return 0; 184 184 185 185 err_destroy_bo: 186 - panthor_kernel_bo_destroy(vm, chunk->bo); 186 + panthor_kernel_bo_destroy(chunk->bo); 187 187 188 188 err_free_chunk: 189 189 kfree(chunk); ··· 253 253 * @pool: Pool to instantiate the heap context from. 254 254 * @initial_chunk_count: Number of chunk allocated at initialization time. 255 255 * Must be at least 1. 256 - * @chunk_size: The size of each chunk. Must be a power of two between 256k 257 - * and 2M. 256 + * @chunk_size: The size of each chunk. Must be page-aligned and lie in the 257 + * [128k:8M] range. 258 258 * @max_chunks: Maximum number of chunks that can be allocated. 259 259 * @target_in_flight: Maximum number of in-flight render passes. 260 260 * @heap_ctx_gpu_va: Pointer holding the GPU address of the allocated heap ··· 281 281 if (initial_chunk_count == 0) 282 282 return -EINVAL; 283 283 284 - if (hweight32(chunk_size) != 1 || 285 - chunk_size < SZ_256K || chunk_size > SZ_2M) 284 + if (initial_chunk_count > max_chunks) 285 + return -EINVAL; 286 + 287 + if (!IS_ALIGNED(chunk_size, PAGE_SIZE) || 288 + chunk_size < SZ_128K || chunk_size > SZ_8M) 286 289 return -EINVAL; 287 290 288 291 down_read(&pool->lock); ··· 323 320 if (!pool->vm) { 324 321 ret = -EINVAL; 325 322 } else { 326 - ret = xa_alloc(&pool->xa, &id, heap, XA_LIMIT(1, MAX_HEAPS_PER_POOL), GFP_KERNEL); 323 + ret = xa_alloc(&pool->xa, &id, heap, 324 + XA_LIMIT(0, MAX_HEAPS_PER_POOL - 1), GFP_KERNEL); 327 325 if (!ret) { 328 326 void *gpu_ctx = panthor_get_heap_ctx(pool, id); 329 327 ··· 395 391 mutex_unlock(&heap->lock); 396 392 397 393 if (removed) { 398 - panthor_kernel_bo_destroy(pool->vm, chunk->bo); 394 + panthor_kernel_bo_destroy(chunk->bo); 399 395 kfree(chunk); 400 396 ret = 0; 401 397 } else { ··· 414 410 * @renderpasses_in_flight: Number of render passes currently in-flight. 415 411 * @pending_frag_count: Number of fragment jobs waiting for execution/completion. 416 412 * @new_chunk_gpu_va: Pointer used to return the chunk VA. 413 + * 414 + * Return: 415 + * - 0 if a new heap was allocated 416 + * - -ENOMEM if the tiler context reached the maximum number of chunks 417 + * or if too many render passes are in-flight 418 + * or if the allocation failed 419 + * - -EINVAL if any of the arguments passed to panthor_heap_grow() is invalid 417 420 */ 418 421 int panthor_heap_grow(struct panthor_heap_pool *pool, 419 422 u64 heap_gpu_va, ··· 450 439 * handler provided by the userspace driver, if any). 451 440 */ 452 441 if (renderpasses_in_flight > heap->target_in_flight || 453 - (pending_frag_count > 0 && heap->chunk_count >= heap->max_chunks)) { 454 - ret = -EBUSY; 455 - goto out_unlock; 456 - } else if (heap->chunk_count >= heap->max_chunks) { 442 + heap->chunk_count >= heap->max_chunks) { 457 443 ret = -ENOMEM; 458 444 goto out_unlock; 459 445 } ··· 544 536 pool->vm = vm; 545 537 pool->ptdev = ptdev; 546 538 init_rwsem(&pool->lock); 547 - xa_init_flags(&pool->xa, XA_FLAGS_ALLOC1); 539 + xa_init_flags(&pool->xa, XA_FLAGS_ALLOC); 548 540 kref_init(&pool->refcount); 549 541 550 542 pool->gpu_contexts = panthor_kernel_bo_create(ptdev, vm, bosize, ··· 595 587 drm_WARN_ON(&pool->ptdev->base, panthor_heap_destroy_locked(pool, i)); 596 588 597 589 if (!IS_ERR_OR_NULL(pool->gpu_contexts)) 598 - panthor_kernel_bo_destroy(pool->vm, pool->gpu_contexts); 590 + panthor_kernel_bo_destroy(pool->gpu_contexts); 599 591 600 592 /* Reflects the fact the pool has been destroyed. */ 601 593 pool->vm = NULL;
+35 -13
drivers/gpu/drm/panthor/panthor_sched.c
··· 826 826 827 827 panthor_queue_put_syncwait_obj(queue); 828 828 829 - panthor_kernel_bo_destroy(group->vm, queue->ringbuf); 830 - panthor_kernel_bo_destroy(panthor_fw_vm(group->ptdev), queue->iface.mem); 829 + panthor_kernel_bo_destroy(queue->ringbuf); 830 + panthor_kernel_bo_destroy(queue->iface.mem); 831 831 832 832 kfree(queue); 833 833 } ··· 837 837 struct panthor_group *group = container_of(work, 838 838 struct panthor_group, 839 839 release_work); 840 - struct panthor_device *ptdev = group->ptdev; 841 840 u32 i; 842 841 843 842 for (i = 0; i < group->queue_count; i++) 844 843 group_free_queue(group, group->queues[i]); 845 844 846 - panthor_kernel_bo_destroy(panthor_fw_vm(ptdev), group->suspend_buf); 847 - panthor_kernel_bo_destroy(panthor_fw_vm(ptdev), group->protm_suspend_buf); 848 - panthor_kernel_bo_destroy(group->vm, group->syncobjs); 845 + panthor_kernel_bo_destroy(group->suspend_buf); 846 + panthor_kernel_bo_destroy(group->protm_suspend_buf); 847 + panthor_kernel_bo_destroy(group->syncobjs); 849 848 850 849 panthor_vm_put(group->vm); 851 850 kfree(group); ··· 1280 1281 if (group) 1281 1282 group->fatal_queues |= BIT(cs_id); 1282 1283 1283 - sched_queue_delayed_work(sched, tick, 0); 1284 + if (CS_EXCEPTION_TYPE(fatal) == DRM_PANTHOR_EXCEPTION_CS_UNRECOVERABLE) { 1285 + /* If this exception is unrecoverable, queue a reset, and make 1286 + * sure we stop scheduling groups until the reset has happened. 1287 + */ 1288 + panthor_device_schedule_reset(ptdev); 1289 + cancel_delayed_work(&sched->tick_work); 1290 + } else { 1291 + sched_queue_delayed_work(sched, tick, 0); 1292 + } 1293 + 1284 1294 drm_warn(&ptdev->base, 1285 1295 "CSG slot %d CS slot: %d\n" 1286 1296 "CS_FATAL.EXCEPTION_TYPE: 0x%x (%s)\n" ··· 1393 1385 pending_frag_count, &new_chunk_va); 1394 1386 } 1395 1387 1396 - if (ret && ret != -EBUSY) { 1388 + /* If the heap context doesn't have memory for us, we want to let the 1389 + * FW try to reclaim memory by waiting for fragment jobs to land or by 1390 + * executing the tiler OOM exception handler, which is supposed to 1391 + * implement incremental rendering. 1392 + */ 1393 + if (ret && ret != -ENOMEM) { 1397 1394 drm_warn(&ptdev->base, "Failed to extend the tiler heap\n"); 1398 1395 group->fatal_queues |= BIT(cs_id); 1399 1396 sched_queue_delayed_work(sched, tick, 0); ··· 2733 2720 mutex_unlock(&sched->reset.lock); 2734 2721 } 2735 2722 2736 - void panthor_sched_post_reset(struct panthor_device *ptdev) 2723 + void panthor_sched_post_reset(struct panthor_device *ptdev, bool reset_failed) 2737 2724 { 2738 2725 struct panthor_scheduler *sched = ptdev->scheduler; 2739 2726 struct panthor_group *group, *group_tmp; 2740 2727 2741 2728 mutex_lock(&sched->reset.lock); 2742 2729 2743 - list_for_each_entry_safe(group, group_tmp, &sched->reset.stopped_groups, run_node) 2730 + list_for_each_entry_safe(group, group_tmp, &sched->reset.stopped_groups, run_node) { 2731 + /* Consider all previously running group as terminated if the 2732 + * reset failed. 2733 + */ 2734 + if (reset_failed) 2735 + group->state = PANTHOR_CS_GROUP_TERMINATED; 2736 + 2744 2737 panthor_group_start(group); 2738 + } 2745 2739 2746 2740 /* We're done resetting the GPU, clear the reset.in_progress bit so we can 2747 2741 * kick the scheduler. ··· 2756 2736 atomic_set(&sched->reset.in_progress, false); 2757 2737 mutex_unlock(&sched->reset.lock); 2758 2738 2759 - sched_queue_delayed_work(sched, tick, 0); 2760 - 2761 - sched_queue_work(sched, sync_upd); 2739 + /* No need to queue a tick and update syncs if the reset failed. */ 2740 + if (!reset_failed) { 2741 + sched_queue_delayed_work(sched, tick, 0); 2742 + sched_queue_work(sched, sync_upd); 2743 + } 2762 2744 } 2763 2745 2764 2746 static void group_sync_upd_work(struct work_struct *work)
+1 -1
drivers/gpu/drm/panthor/panthor_sched.h
··· 40 40 int panthor_sched_init(struct panthor_device *ptdev); 41 41 void panthor_sched_unplug(struct panthor_device *ptdev); 42 42 void panthor_sched_pre_reset(struct panthor_device *ptdev); 43 - void panthor_sched_post_reset(struct panthor_device *ptdev); 43 + void panthor_sched_post_reset(struct panthor_device *ptdev, bool reset_failed); 44 44 void panthor_sched_suspend(struct panthor_device *ptdev); 45 45 void panthor_sched_resume(struct panthor_device *ptdev); 46 46
+3 -3
drivers/gpu/drm/xlnx/zynqmp_disp.c
··· 940 940 * zynqmp_disp_layer_find_live_format - Find format information for given 941 941 * media bus format 942 942 * @layer: The layer 943 - * @drm_fmt: Media bus format to search 943 + * @media_bus_format: Media bus format to search 944 944 * 945 945 * Search display subsystem format information corresponding to the given media 946 946 * bus format @media_bus_format for the @layer, and return a pointer to the ··· 981 981 unsigned int i; 982 982 u32 *formats; 983 983 984 - if (WARN_ON(!layer->mode == ZYNQMP_DPSUB_LAYER_NONLIVE)) { 984 + if (WARN_ON(layer->mode != ZYNQMP_DPSUB_LAYER_NONLIVE)) { 985 985 *num_formats = 0; 986 986 return NULL; 987 987 } ··· 1117 1117 /** 1118 1118 * zynqmp_disp_layer_set_live_format - Set the live video layer format 1119 1119 * @layer: The layer 1120 - * @info: The format info 1120 + * @media_bus_format: Media bus format to set 1121 1121 * 1122 1122 * NOTE: This function should not be used to set format for non-live video 1123 1123 * layer. Use zynqmp_disp_layer_set_format() instead.
+7
include/uapi/drm/nouveau_drm.h
··· 68 68 */ 69 69 #define NOUVEAU_GETPARAM_VRAM_USED 19 70 70 71 + /* 72 + * NOUVEAU_GETPARAM_HAS_VMA_TILEMODE 73 + * 74 + * Query whether tile mode and PTE kind are accepted with VM allocs or not. 75 + */ 76 + #define NOUVEAU_GETPARAM_HAS_VMA_TILEMODE 20 77 + 71 78 struct drm_nouveau_getparam { 72 79 __u64 param; 73 80 __u64 value;
+16 -4
include/uapi/drm/panthor_drm.h
··· 895 895 /** @vm_id: VM ID the tiler heap should be mapped to */ 896 896 __u32 vm_id; 897 897 898 - /** @initial_chunk_count: Initial number of chunks to allocate. */ 898 + /** @initial_chunk_count: Initial number of chunks to allocate. Must be at least one. */ 899 899 __u32 initial_chunk_count; 900 900 901 - /** @chunk_size: Chunk size. Must be a power of two at least 256KB large. */ 901 + /** 902 + * @chunk_size: Chunk size. 903 + * 904 + * Must be page-aligned and lie in the [128k:8M] range. 905 + */ 902 906 __u32 chunk_size; 903 907 904 - /** @max_chunks: Maximum number of chunks that can be allocated. */ 908 + /** 909 + * @max_chunks: Maximum number of chunks that can be allocated. 910 + * 911 + * Must be at least @initial_chunk_count. 912 + */ 905 913 __u32 max_chunks; 906 914 907 915 /** ··· 939 931 * struct drm_panthor_tiler_heap_destroy - Arguments passed to DRM_IOCTL_PANTHOR_TILER_HEAP_DESTROY 940 932 */ 941 933 struct drm_panthor_tiler_heap_destroy { 942 - /** @handle: Handle of the tiler heap to destroy */ 934 + /** 935 + * @handle: Handle of the tiler heap to destroy. 936 + * 937 + * Must be a valid heap handle returned by DRM_IOCTL_PANTHOR_TILER_HEAP_CREATE. 938 + */ 943 939 __u32 handle; 944 940 945 941 /** @pad: Padding field, MBZ. */