History

Merge tag 'drm-misc-next-fixes-2023-08-24' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

Short summary of fixes pull: * gpuva: Cleanups * kunit: Documentation fixes * nouveau: * UAPI: Avoid implicit NO_PREFETCH flag * Scheduler fixes * Fix remap * ttm: Fix type conversion in tests Signed-off-by: Dave Airlie <airlied@redhat.com>

Dave Airlie committed 3 years ago

Commit bc609f42 parents 38f8873 cdf410010 files · +68 −19Browse files

Unified · Split

10 files
  1. drivers/gpu/drm/drm_gpuva_mgr.c +4 −6
  2. drivers/gpu/drm/nouveau/nouveau_dma.c +5 −2
  3. drivers/gpu/drm/nouveau/nouveau_dma.h +6 −2
  4. drivers/gpu/drm/nouveau/nouveau_exec.c +16 −3
  5. drivers/gpu/drm/nouveau/nouveau_gem.c +4 −2
  6. drivers/gpu/drm/nouveau/nouveau_sched.c +22 −0
  7. drivers/gpu/drm/nouveau/nouveau_uvmm.c +1 −0
  8. drivers/gpu/drm/tests/drm_kunit_helpers.c +1 −1
  9. drivers/gpu/drm/ttm/tests/ttm_pool_test.c +2 −2
  10. include/uapi/drm/nouveau_drm.h +7 −1
drivers/gpu/drm/drm_gpuva_mgr.c+4−6
@@ -1076,7 +1076,7 @@ __drm_gpuva_sm_map(struct drm_gpuva_manager *mgr, · 1075 unmodified lines
1076 u64 req_addr, u64 req_range,1076 u64 req_addr, u64 req_range,
1077 struct drm_gem_object *req_obj, u64 req_offset)1077 struct drm_gem_object *req_obj, u64 req_offset)
1078{1078{
1079 struct drm_gpuva *va, *next, *prev = NULL;1079 struct drm_gpuva *va, *next;
1080 u64 req_end = req_addr + req_range;1080 u64 req_end = req_addr + req_range;
1081 int ret;1081 int ret;
1082 1082
@@ -1106,7 +1106,7 @@ __drm_gpuva_sm_map(struct drm_gpuva_manager *mgr, · 23 unmodified lines
1106 ret = op_unmap_cb(ops, priv, va, merge);1106 ret = op_unmap_cb(ops, priv, va, merge);
1107 if (ret)1107 if (ret)
1108 return ret;1108 return ret;
1109 goto next;1109 continue;
1110 }1110 }
1111 1111
1112 if (end > req_end) {1112 if (end > req_end) {
@@ -1151,7 +1151,7 @@ __drm_gpuva_sm_map(struct drm_gpuva_manager *mgr, · 38 unmodified lines
1151 ret = op_remap_cb(ops, priv, &p, NULL, &u);1151 ret = op_remap_cb(ops, priv, &p, NULL, &u);
1152 if (ret)1152 if (ret)
1153 return ret;1153 return ret;
1154 goto next;1154 continue;
1155 }1155 }
1156 1156
1157 if (end > req_end) {1157 if (end > req_end) {
@@ -1184,7 +1184,7 @@ __drm_gpuva_sm_map(struct drm_gpuva_manager *mgr, · 26 unmodified lines
1184 ret = op_unmap_cb(ops, priv, va, merge);1184 ret = op_unmap_cb(ops, priv, va, merge);
1185 if (ret)1185 if (ret)
1186 return ret;1186 return ret;
1187 goto next;1187 continue;
1188 }1188 }
1189 1189
1190 if (end > req_end) {1190 if (end > req_end) {
@@ -1205,8 +1205,6 @@ __drm_gpuva_sm_map(struct drm_gpuva_manager *mgr, · 14 unmodified lines
1205 break;1205 break;
1206 }1206 }
1207 }1207 }
1208next:
1209 prev = va;
1210 }1208 }
1211 1209
1212 return op_map_cb(ops, priv,1210 return op_map_cb(ops, priv,
drivers/gpu/drm/nouveau/nouveau_dma.c+5−2
@@ -69,16 +69,19 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) · 68 unmodified lines
69}69}
70 70
71void71void
72nv50_dma_push(struct nouveau_channel *chan, u64 offset, int length)72nv50_dma_push(struct nouveau_channel *chan, u64 offset, u32 length,
73 bool no_prefetch)
73{74{
74 struct nvif_user *user = &chan->drm->client.device.user;75 struct nvif_user *user = &chan->drm->client.device.user;
75 struct nouveau_bo *pb = chan->push.buffer;76 struct nouveau_bo *pb = chan->push.buffer;
76 int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;77 int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
77 78
78 BUG_ON(chan->dma.ib_free < 1);79 BUG_ON(chan->dma.ib_free < 1);
80 WARN_ON(length > NV50_DMA_PUSH_MAX_LENGTH);
79 81
80 nouveau_bo_wr32(pb, ip++, lower_32_bits(offset));82 nouveau_bo_wr32(pb, ip++, lower_32_bits(offset));
81 nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8);83 nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8 |
84 (no_prefetch ? (1 << 31) : 0));
82 85
83 chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max;86 chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max;
84 87
drivers/gpu/drm/nouveau/nouveau_dma.h+6−2
@@ -31,7 +31,8 @@ · 30 unmodified lines
31#include "nouveau_chan.h"31#include "nouveau_chan.h"
32 32
33int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);33int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
34void nv50_dma_push(struct nouveau_channel *, u64 addr, int length);34void nv50_dma_push(struct nouveau_channel *, u64 addr, u32 length,
35 bool no_prefetch);
35 36
36/*37/*
37 * There's a hw race condition where you can't jump to your PUT offset,38 * There's a hw race condition where you can't jump to your PUT offset,
@@ -45,6 +46,9 @@ void nv50_dma_push(struct nouveau_channel *, u64 addr, int length); · 7 unmodified lines
45 */46 */
46#define NOUVEAU_DMA_SKIPS (128 / 4)47#define NOUVEAU_DMA_SKIPS (128 / 4)
47 48
49/* Maximum push buffer size. */
50#define NV50_DMA_PUSH_MAX_LENGTH 0x7fffff
51
48/* Object handles - for stuff that's doesn't use handle == oclass. */52/* Object handles - for stuff that's doesn't use handle == oclass. */
49enum {53enum {
50 NvDmaFB = 0x80000002,54 NvDmaFB = 0x80000002,
@@ -89,7 +93,7 @@ FIRE_RING(struct nouveau_channel *chan) · 38 unmodified lines
89 93
90 if (chan->dma.ib_max) {94 if (chan->dma.ib_max) {
91 nv50_dma_push(chan, chan->push.addr + (chan->dma.put << 2),95 nv50_dma_push(chan, chan->push.addr + (chan->dma.put << 2),
92 (chan->dma.cur - chan->dma.put) << 2);96 (chan->dma.cur - chan->dma.put) << 2, false);
93 } else {97 } else {
94 WRITE_PUT(chan->dma.cur);98 WRITE_PUT(chan->dma.cur);
95 }99 }
drivers/gpu/drm/nouveau/nouveau_exec.c+16−3
@@ -164,8 +164,10 @@ nouveau_exec_job_run(struct nouveau_job *job) · 163 unmodified lines
164 }164 }
165 165
166 for (i = 0; i < exec_job->push.count; i++) {166 for (i = 0; i < exec_job->push.count; i++) {
167 nv50_dma_push(chan, exec_job->push.s[i].va,167 struct drm_nouveau_exec_push *p = &exec_job->push.s[i];
168 exec_job->push.s[i].va_len);168 bool no_prefetch = p->flags & DRM_NOUVEAU_EXEC_PUSH_NO_PREFETCH;
169
170 nv50_dma_push(chan, p->va, p->va_len, no_prefetch);
169 }171 }
170 172
171 ret = nouveau_fence_emit(fence, chan);173 ret = nouveau_fence_emit(fence, chan);
@@ -223,7 +225,18 @@ nouveau_exec_job_init(struct nouveau_exec_job **pjob, · 51 unmodified lines
223{225{
224 struct nouveau_exec_job *job;226 struct nouveau_exec_job *job;
225 struct nouveau_job_args args = {};227 struct nouveau_job_args args = {};
226 int ret;228 int i, ret;
229
230 for (i = 0; i < __args->push.count; i++) {
231 struct drm_nouveau_exec_push *p = &__args->push.s[i];
232
233 if (unlikely(p->va_len > NV50_DMA_PUSH_MAX_LENGTH)) {
234 NV_PRINTK(err, nouveau_cli(__args->file_priv),
235 "pushbuf size exceeds limit: 0x%x max 0x%x\n",
236 p->va_len, NV50_DMA_PUSH_MAX_LENGTH);
237 return -EINVAL;
238 }
239 }
227 240
228 job = *pjob = kzalloc(sizeof(*job), GFP_KERNEL);241 job = *pjob = kzalloc(sizeof(*job), GFP_KERNEL);
229 if (!job)242 if (!job)
drivers/gpu/drm/nouveau/nouveau_gem.c+4−2
@@ -856,9 +856,11 @@ revalidate: · 855 unmodified lines
856 for (i = 0; i < req->nr_push; i++) {856 for (i = 0; i < req->nr_push; i++) {
857 struct nouveau_vma *vma = (void *)(unsigned long)857 struct nouveau_vma *vma = (void *)(unsigned long)
858 bo[push[i].bo_index].user_priv;858 bo[push[i].bo_index].user_priv;
859 u64 addr = vma->addr + push[i].offset;
860 u32 length = push[i].length & ~NOUVEAU_GEM_PUSHBUF_NO_PREFETCH;
861 bool no_prefetch = push[i].length & NOUVEAU_GEM_PUSHBUF_NO_PREFETCH;
859 862
860 nv50_dma_push(chan, vma->addr + push[i].offset,863 nv50_dma_push(chan, addr, length, no_prefetch);
861 push[i].length);
862 }864 }
863 } else865 } else
864 if (drm->client.device.info.chipset >= 0x25) {866 if (drm->client.device.info.chipset >= 0x25) {
drivers/gpu/drm/nouveau/nouveau_sched.c+22−0
@@ -292,6 +292,28 @@ nouveau_job_submit(struct nouveau_job *job) · 291 unmodified lines
292 if (job->sync)292 if (job->sync)
293 done_fence = dma_fence_get(job->done_fence);293 done_fence = dma_fence_get(job->done_fence);
294 294
295 /* If a sched job depends on a dma-fence from a job from the same GPU
296 * scheduler instance, but a different scheduler entity, the GPU
297 * scheduler does only wait for the particular job to be scheduled,
298 * rather than for the job to fully complete. This is due to the GPU
299 * scheduler assuming that there is a scheduler instance per ring.
300 * However, the current implementation, in order to avoid arbitrary
301 * amounts of kthreads, has a single scheduler instance while scheduler
302 * entities represent rings.
303 *
304 * As a workaround, set the DRM_SCHED_FENCE_DONT_PIPELINE for all
305 * out-fences in order to force the scheduler to wait for full job
306 * completion for dependent jobs from different entities and same
307 * scheduler instance.
308 *
309 * There is some work in progress [1] to address the issues of firmware
310 * schedulers; once it is in-tree the scheduler topology in Nouveau
311 * should be re-worked accordingly.
312 *
313 * [1] https://lore.kernel.org/dri-devel/20230801205103.627779-1-matthew.brost@intel.com/
314 */
315 set_bit(DRM_SCHED_FENCE_DONT_PIPELINE, &job->done_fence->flags);
316
295 if (job->ops->armed_submit)317 if (job->ops->armed_submit)
296 job->ops->armed_submit(job);318 job->ops->armed_submit(job);
297 319
drivers/gpu/drm/nouveau/nouveau_uvmm.c+1−0
@@ -639,6 +639,7 @@ nouveau_uvmm_sm_prepare(struct nouveau_uvmm *uvmm, · 638 unmodified lines
639 struct drm_gpuva *va = r->unmap->va;639 struct drm_gpuva *va = r->unmap->va;
640 struct uvmm_map_args remap_args = {640 struct uvmm_map_args remap_args = {
641 .kind = uvma_from_va(va)->kind,641 .kind = uvma_from_va(va)->kind,
642 .region = uvma_from_va(va)->region,
642 };643 };
643 u64 ustart = va->va.addr;644 u64 ustart = va->va.addr;
644 u64 urange = va->va.range;645 u64 urange = va->va.range;
drivers/gpu/drm/tests/drm_kunit_helpers.c+1−1
@@ -156,7 +156,7 @@ static void action_drm_release_context(void *ptr) · 155 unmodified lines
156}156}
157 157
158/**158/**
159 * drm_kunit_helper_context_alloc - Allocates an acquire context159 * drm_kunit_helper_acquire_ctx_alloc - Allocates an acquire context
160 * @test: The test context object160 * @test: The test context object
161 *161 *
162 * Allocates and initializes a modeset acquire context.162 * Allocates and initializes a modeset acquire context.
drivers/gpu/drm/ttm/tests/ttm_pool_test.c+2−2
@@ -228,8 +228,8 @@ static void ttm_pool_alloc_basic_dma_addr(struct kunit *test) · 227 unmodified lines
228 dma1 = tt->dma_address[0];228 dma1 = tt->dma_address[0];
229 dma2 = tt->dma_address[tt->num_pages - 1];229 dma2 = tt->dma_address[tt->num_pages - 1];
230 230
231 KUNIT_ASSERT_NOT_NULL(test, (void *)dma1);231 KUNIT_ASSERT_NOT_NULL(test, (void *)(uintptr_t)dma1);
232 KUNIT_ASSERT_NOT_NULL(test, (void *)dma2);232 KUNIT_ASSERT_NOT_NULL(test, (void *)(uintptr_t)dma2);
233 233
234 ttm_pool_free(pool, tt);234 ttm_pool_free(pool, tt);
235 ttm_tt_fini(tt);235 ttm_tt_fini(tt);
include/uapi/drm/nouveau_drm.h+7−1
@@ -138,6 +138,7 @@ struct drm_nouveau_gem_pushbuf_push { · 137 unmodified lines
138 __u32 pad;138 __u32 pad;
139 __u64 offset;139 __u64 offset;
140 __u64 length;140 __u64 length;
141#define NOUVEAU_GEM_PUSHBUF_NO_PREFETCH (1 << 23)
141};142};
142 143
143struct drm_nouveau_gem_pushbuf {144struct drm_nouveau_gem_pushbuf {
@@ -338,7 +339,12 @@ struct drm_nouveau_exec_push { · 194 unmodified lines
338 /**339 /**
339 * @va_len: the length of the push buffer mapping340 * @va_len: the length of the push buffer mapping
340 */341 */
341 __u64 va_len;342 __u32 va_len;
343 /**
344 * @flags: the flags for this push buffer mapping
345 */
346 __u32 flags;
347#define DRM_NOUVEAU_EXEC_PUSH_NO_PREFETCH 0x1
342};348};
343 349
344/**350/**

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t