Skip to content

Commit c61e23e

Browse files
committed
Merge tag 'drm-misc-fixes-2026-10-09' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes
A pointer assignment fix for gud, a reference fix and a preallocation size fix for imagination, a suspend fix and an allocation fix when idle for vc4, and a hardware variant fix for nouveau. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <self@mripard.dev> Link: https://patch.msgid.link/asjkbknTHg2t8JGy@houat
2 parents 492c4de + 6ccf996 commit c61e23e

9 files changed

Lines changed: 62 additions & 67 deletions

File tree

‎drivers/gpu/drm/gud/gud_pipe.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,7 @@ int gud_plane_atomic_check(struct drm_plane *plane,
507507
for_each_new_connector_in_state(state, connector, connector_state, i) {
508508
if (connector_state->crtc)
509509
break;
510+
connector_state = NULL;
510511
}
511512

512513
/*

‎drivers/gpu/drm/imagination/pvr_mmu.c‎

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2337,7 +2337,7 @@ void pvr_mmu_op_context_destroy(struct pvr_mmu_op_context *op_ctx)
23372337
* @ctx: MMU context associated with owning VM context.
23382338
* @sgt: Scatter gather table containing pages pinned for use by this context.
23392339
* @device_addr: Virtual device address at the start of the requested mapping.
2340-
* @sgt_offset: Start offset of the requested device-virtual memory mapping.
2340+
* @sgt_offset: Offset into @sgt of the start of the requested mapping.
23412341
* @size: Size in bytes of the requested device-virtual memory mapping. For an
23422342
* unmapping, this should be zero so that no page tables are allocated.
23432343
*
@@ -2350,7 +2350,6 @@ struct pvr_mmu_op_context *
23502350
pvr_mmu_op_context_create(struct pvr_mmu_context *ctx, struct sg_table *sgt,
23512351
u64 device_addr, u64 sgt_offset, u64 size)
23522352
{
2353-
u64 start_addr = device_addr + sgt_offset;
23542353
int err;
23552354

23562355
struct pvr_mmu_op_context *op_ctx = kzalloc_obj(*op_ctx);
@@ -2365,18 +2364,18 @@ pvr_mmu_op_context_create(struct pvr_mmu_context *ctx, struct sg_table *sgt,
23652364

23662365
if (size) {
23672366
/*
2368-
* The number of page table objects we need to prealloc is
2369-
* indicated by the mapping size, start address and the sizes
2370-
* of the areas mapped per PT or PD. The range calculation is
2371-
* identical to that for the index into a table for a device
2372-
* address, so we reuse those functions here.
2367+
* The page tables needed are set by the device-virtual range
2368+
* being mapped: one level 1 table per 1GiB region and one
2369+
* level 0 table per 2MiB region the range touches. Tables that
2370+
* already exist are not consumed, so this is an upper bound.
23732371
*/
2374-
const u32 l1_start_idx = pvr_page_table_l2_idx(start_addr);
2375-
const u32 l1_end_idx = pvr_page_table_l2_idx(start_addr + size);
2376-
const u32 l1_count = l1_end_idx - l1_start_idx + 1;
2377-
const u32 l0_start_idx = pvr_page_table_l1_idx(start_addr);
2378-
const u32 l0_end_idx = pvr_page_table_l1_idx(start_addr + size);
2379-
const u32 l0_count = l0_end_idx - l0_start_idx + 1;
2372+
const u64 last_addr = device_addr + size - 1;
2373+
const u64 l1_count =
2374+
(last_addr >> ROGUE_MMUCTRL_VADDR_PC_INDEX_SHIFT) -
2375+
(device_addr >> ROGUE_MMUCTRL_VADDR_PC_INDEX_SHIFT) + 1;
2376+
const u64 l0_count =
2377+
(last_addr >> ROGUE_MMUCTRL_VADDR_PD_INDEX_SHIFT) -
2378+
(device_addr >> ROGUE_MMUCTRL_VADDR_PD_INDEX_SHIFT) + 1;
23802379

23812380
/*
23822381
* Alloc and push page table entries until we have enough of

‎drivers/gpu/drm/imagination/pvr_vm.c‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,8 @@ pvr_vm_gpuva_unmap(struct drm_gpuva_op *op, void *op_ctx)
418418
static int
419419
pvr_vm_gpuva_remap(struct drm_gpuva_op *op, void *op_ctx)
420420
{
421+
/* The split parts belong to the object of the mapping being split. */
422+
struct drm_gpuvm_bo *vm_bo = op->remap.unmap->va->vm_bo;
421423
struct pvr_vm_bind_op *ctx = op_ctx;
422424
u64 va_start = 0, va_range = 0;
423425
int err;
@@ -433,14 +435,12 @@ pvr_vm_gpuva_remap(struct drm_gpuva_op *op, void *op_ctx)
433435
drm_gpuva_remap(&ctx->prev_va->base, &ctx->next_va->base, &op->remap);
434436

435437
if (op->remap.prev) {
436-
pvr_gem_object_get(gem_to_pvr_gem(ctx->prev_va->base.gem.obj));
437-
drm_gpuva_link(&ctx->prev_va->base, ctx->gpuvm_bo);
438+
drm_gpuva_link(&ctx->prev_va->base, vm_bo);
438439
ctx->prev_va = NULL;
439440
}
440441

441442
if (op->remap.next) {
442-
pvr_gem_object_get(gem_to_pvr_gem(ctx->next_va->base.gem.obj));
443-
drm_gpuva_link(&ctx->next_va->base, ctx->gpuvm_bo);
443+
drm_gpuva_link(&ctx->next_va->base, vm_bo);
444444
ctx->next_va = NULL;
445445
}
446446

‎drivers/gpu/drm/nouveau/nouveau_abi16.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
488488
goto done;
489489
break;
490490
case NV_DEVICE_INFO_V0_TURING:
491-
if (engine != NV_DEVICE_HOST_RUNLIST_ENGINES_NVDEC) {
491+
if (engine == NV_DEVICE_HOST_RUNLIST_ENGINES_GR) {
492492
ret = nvif_object_ctor(&chan->chan->user, "abi16CeWar",
493493
0, TURING_DMA_COPY_A, NULL, 0,
494494
&chan->ce);

‎drivers/gpu/drm/vc4/vc4_drv.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@ void vc4_plane_async_set_fb(struct drm_plane *plane,
10511051
/* vc4_v3d.c */
10521052
extern struct platform_driver vc4_v3d_driver;
10531053
extern const struct of_device_id vc4_v3d_dt_match[];
1054-
int vc4_v3d_get_bin_slot(struct vc4_dev *vc4);
1054+
int vc4_v3d_get_bin_slot(struct vc4_dev *vc4, long timeout);
10551055
int vc4_v3d_bin_bo_get(struct vc4_dev *vc4, bool *used);
10561056
void vc4_v3d_bin_bo_put(struct vc4_dev *vc4);
10571057
int vc4_v3d_pm_get(struct vc4_dev *vc4);

‎drivers/gpu/drm/vc4/vc4_gem.c‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -877,11 +877,17 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
877877
drm_gem_object_put(&bo->base.base);
878878
}
879879

880-
/* Free up the allocation of any bin slots we used. */
880+
/* Free up the allocation of any bin slots we used. Jobs that ran to
881+
* completion had their slots released in vc4_irq_finish_render_job().
882+
* Only jobs that never completed still have slots to be released here.
883+
*/
881884
spin_lock_irqsave(&vc4->job_lock, irqflags);
882885
vc4->bin_alloc_used &= ~exec->bin_slots;
883886
spin_unlock_irqrestore(&vc4->job_lock, irqflags);
884887

888+
/* Let anyone waiting on the binner pool retry. */
889+
wake_up_all(&vc4->job_wait_queue);
890+
885891
/* Release the reference on the binner BO if needed. */
886892
if (exec->bin_bo_used)
887893
vc4_v3d_bin_bo_put(vc4);

‎drivers/gpu/drm/vc4/vc4_irq.c‎

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ vc4_overflow_mem_work(struct work_struct *work)
7474

7575
bo = vc4->bin_bo;
7676

77-
bin_bo_slot = vc4_v3d_get_bin_slot(vc4);
77+
bin_bo_slot = vc4_v3d_get_bin_slot(vc4, msecs_to_jiffies(500));
7878
if (bin_bo_slot < 0) {
7979
drm_err(&vc4->base, "Couldn't allocate binner overflow mem\n");
8080
goto complete;
@@ -165,6 +165,10 @@ vc4_irq_finish_render_job(struct drm_device *dev)
165165
trace_vc4_rcl_end_irq(dev, exec->seqno);
166166

167167
vc4->finished_seqno++;
168+
169+
vc4->bin_alloc_used &= ~exec->bin_slots;
170+
exec->bin_slots = 0;
171+
168172
list_move_tail(&exec->head, &vc4->job_done_list);
169173

170174
nextbin = vc4_first_bin_job(vc4);
@@ -276,15 +280,14 @@ vc4_irq_disable(struct drm_device *dev)
276280
V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
277281

278282
/* Finish any interrupt handler still in flight. */
279-
synchronize_irq(vc4->irq);
283+
disable_irq(vc4->irq);
280284

281285
cancel_work_sync(&vc4->overflow_mem_work);
282286
}
283287

284288
int vc4_irq_install(struct drm_device *dev, int irq)
285289
{
286290
struct vc4_dev *vc4 = to_vc4_dev(dev);
287-
int ret;
288291

289292
if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
290293
return -ENODEV;
@@ -298,19 +301,8 @@ int vc4_irq_install(struct drm_device *dev, int irq)
298301
init_waitqueue_head(&vc4->job_wait_queue);
299302
INIT_WORK(&vc4->overflow_mem_work, vc4_overflow_mem_work);
300303

301-
/* Clear any pending interrupts someone might have left around
302-
* for us.
303-
*/
304-
V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
305-
306-
ret = devm_request_irq(dev->dev, irq, vc4_irq, 0,
307-
dev_name(dev->dev), dev);
308-
if (ret)
309-
return ret;
310-
311-
vc4_irq_enable(dev);
312-
313-
return 0;
304+
return devm_request_irq(dev->dev, irq, vc4_irq, IRQF_NO_AUTOEN,
305+
dev_name(dev->dev), dev);
314306
}
315307

316308
void vc4_irq_uninstall(struct drm_device *dev)

‎drivers/gpu/drm/vc4/vc4_v3d.c‎

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -173,46 +173,42 @@ static void vc4_v3d_init_hw(struct drm_device *dev)
173173
V3D_WRITE(V3D_VPMBASE, 0);
174174
}
175175

176-
int vc4_v3d_get_bin_slot(struct vc4_dev *vc4)
176+
static int bin_slot_try_alloc(struct vc4_dev *vc4)
177177
{
178-
struct drm_device *dev = &vc4->base;
179-
unsigned long irqflags;
180178
int slot;
181-
uint64_t seqno = 0;
182-
struct vc4_exec_info *exec;
183179

184-
if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
185-
return -ENODEV;
180+
guard(spinlock_irqsave)(&vc4->job_lock);
186181

187-
try_again:
188-
spin_lock_irqsave(&vc4->job_lock, irqflags);
189182
slot = ffs(~vc4->bin_alloc_used);
190183
if (slot != 0) {
191184
/* Switch from ffs() bit index to a 0-based index. */
192185
slot--;
193186
vc4->bin_alloc_used |= BIT(slot);
194-
spin_unlock_irqrestore(&vc4->job_lock, irqflags);
195-
return slot;
187+
} else {
188+
slot = -ENOMEM;
196189
}
197190

198-
/* Couldn't find an open slot. Wait for render to complete
199-
* and try again.
200-
*/
201-
exec = vc4_last_render_job(vc4);
202-
if (exec)
203-
seqno = exec->seqno;
204-
spin_unlock_irqrestore(&vc4->job_lock, irqflags);
191+
return slot;
192+
}
205193

206-
if (seqno) {
207-
int ret = vc4_wait_for_seqno(dev, seqno, ~0ull, true);
194+
int vc4_v3d_get_bin_slot(struct vc4_dev *vc4, long timeout)
195+
{
196+
int slot;
197+
long ret;
208198

209-
if (ret == 0)
210-
goto try_again;
199+
if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
200+
return -ENODEV;
211201

202+
/* If the pool is full, wait for a job to release its slots. */
203+
ret = wait_event_interruptible_timeout(vc4->job_wait_queue,
204+
(slot = bin_slot_try_alloc(vc4)) >= 0,
205+
timeout);
206+
if (ret < 0)
212207
return ret;
213-
}
208+
if (ret == 0)
209+
return -ENOMEM;
214210

215-
return -ENOMEM;
211+
return slot;
216212
}
217213

218214
/*
@@ -397,6 +393,7 @@ static int vc4_v3d_runtime_resume(struct device *dev)
397393
vc4_v3d_init_hw(&vc4->base);
398394

399395
vc4_irq_enable(&vc4->base);
396+
enable_irq(vc4->irq);
400397

401398
return 0;
402399
}
@@ -453,6 +450,12 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data)
453450
return ret;
454451
vc4->irq = ret;
455452

453+
ret = vc4_irq_install(drm, vc4->irq);
454+
if (ret) {
455+
drm_err(drm, "Failed to install IRQ handler\n");
456+
return ret;
457+
}
458+
456459
ret = devm_pm_runtime_enable(dev);
457460
if (ret)
458461
return ret;
@@ -474,12 +477,6 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data)
474477
V3D_WRITE(V3D_BPOA, 0);
475478
V3D_WRITE(V3D_BPOS, 0);
476479

477-
ret = vc4_irq_install(drm, vc4->irq);
478-
if (ret) {
479-
drm_err(drm, "Failed to install IRQ handler\n");
480-
goto err_put_runtime_pm;
481-
}
482-
483480
pm_runtime_use_autosuspend(dev);
484481
pm_runtime_set_autosuspend_delay(dev, 40); /* a little over 2 frames. */
485482
pm_runtime_put_autosuspend(dev);

‎drivers/gpu/drm/vc4/vc4_validate.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ validate_tile_binning_config(VALIDATE_ARGS)
402402
return -EINVAL;
403403
}
404404

405-
bin_slot = vc4_v3d_get_bin_slot(vc4);
405+
bin_slot = vc4_v3d_get_bin_slot(vc4, MAX_SCHEDULE_TIMEOUT);
406406
if (bin_slot < 0) {
407407
if (bin_slot != -EINTR && bin_slot != -ERESTARTSYS) {
408408
drm_err(dev, "Failed to allocate binner memory: %d\n",

0 commit comments

Comments
 (0)