Skip to content

Commit 311e03c

Browse files
committed
drm/msm/gem: Separate object and vma unpin
Previously the BO_PINNED state in the submit was tracking two related but different things: (1) that the buffer object was pinned, and (2) that the vma (mapping within a set of pagetables) was pinned. But with fenced vma unpin (needed so that userspace couldn't race with retire path for releasing a vma) these two were decoupled. The fact that the BO_PINNED flag was already cleared meant that we leaked the bo pin count which should have been dropped when the submit was retired. So split this state into BO_OBJ_PINNED and BO_VMA_PINNED, so they can be dropped independently. Fixes: 95d1deb ("drm/msm/gem: Add fenced vma unpin") Signed-off-by: Rob Clark <robdclark@chromium.org> Patchwork: https://patchwork.freedesktop.org/patch/487559/ Link: https://lore.kernel.org/r/20220527172341.2151005-1-robdclark@gmail.com
1 parent 62b5e32 commit 311e03c

4 files changed

Lines changed: 22 additions & 16 deletions

File tree

drivers/gpu/drm/msm/msm_gem.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -439,14 +439,12 @@ int msm_gem_pin_vma_locked(struct drm_gem_object *obj, struct msm_gem_vma *vma)
439439
return ret;
440440
}
441441

442-
void msm_gem_unpin_vma_locked(struct drm_gem_object *obj, struct msm_gem_vma *vma)
442+
void msm_gem_unpin_locked(struct drm_gem_object *obj)
443443
{
444444
struct msm_gem_object *msm_obj = to_msm_bo(obj);
445445

446446
GEM_WARN_ON(!msm_gem_is_locked(obj));
447447

448-
msm_gem_unpin_vma(vma);
449-
450448
msm_obj->pin_count--;
451449
GEM_WARN_ON(msm_obj->pin_count < 0);
452450

@@ -586,7 +584,8 @@ void msm_gem_unpin_iova(struct drm_gem_object *obj,
586584
msm_gem_lock(obj);
587585
vma = lookup_vma(obj, aspace);
588586
if (!GEM_WARN_ON(!vma)) {
589-
msm_gem_unpin_vma_locked(obj, vma);
587+
msm_gem_unpin_vma(vma);
588+
msm_gem_unpin_locked(obj);
590589
}
591590
msm_gem_unlock(obj);
592591
}

drivers/gpu/drm/msm/msm_gem.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ struct msm_gem_object {
145145

146146
uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj);
147147
int msm_gem_pin_vma_locked(struct drm_gem_object *obj, struct msm_gem_vma *vma);
148-
void msm_gem_unpin_vma_locked(struct drm_gem_object *obj, struct msm_gem_vma *vma);
148+
void msm_gem_unpin_locked(struct drm_gem_object *obj);
149149
struct msm_gem_vma *msm_gem_get_vma_locked(struct drm_gem_object *obj,
150150
struct msm_gem_address_space *aspace);
151151
int msm_gem_get_iova(struct drm_gem_object *obj,
@@ -377,10 +377,11 @@ struct msm_gem_submit {
377377
} *cmd; /* array of size nr_cmds */
378378
struct {
379379
/* make sure these don't conflict w/ MSM_SUBMIT_BO_x */
380-
#define BO_VALID 0x8000 /* is current addr in cmdstream correct/valid? */
381-
#define BO_LOCKED 0x4000 /* obj lock is held */
382-
#define BO_ACTIVE 0x2000 /* active refcnt is held */
383-
#define BO_PINNED 0x1000 /* obj is pinned and on active list */
380+
#define BO_VALID 0x8000 /* is current addr in cmdstream correct/valid? */
381+
#define BO_LOCKED 0x4000 /* obj lock is held */
382+
#define BO_ACTIVE 0x2000 /* active refcnt is held */
383+
#define BO_OBJ_PINNED 0x1000 /* obj (pages) is pinned and on active list */
384+
#define BO_VMA_PINNED 0x0800 /* vma (virtual address) is pinned */
384385
uint32_t flags;
385386
union {
386387
struct msm_gem_object *obj;

drivers/gpu/drm/msm/msm_gem_submit.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,11 @@ static void submit_cleanup_bo(struct msm_gem_submit *submit, int i,
232232
*/
233233
submit->bos[i].flags &= ~cleanup_flags;
234234

235-
if (flags & BO_PINNED)
236-
msm_gem_unpin_vma_locked(obj, submit->bos[i].vma);
235+
if (flags & BO_VMA_PINNED)
236+
msm_gem_unpin_vma(submit->bos[i].vma);
237+
238+
if (flags & BO_OBJ_PINNED)
239+
msm_gem_unpin_locked(obj);
237240

238241
if (flags & BO_ACTIVE)
239242
msm_gem_active_put(obj);
@@ -244,7 +247,9 @@ static void submit_cleanup_bo(struct msm_gem_submit *submit, int i,
244247

245248
static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i)
246249
{
247-
submit_cleanup_bo(submit, i, BO_PINNED | BO_ACTIVE | BO_LOCKED);
250+
unsigned cleanup_flags = BO_VMA_PINNED | BO_OBJ_PINNED |
251+
BO_ACTIVE | BO_LOCKED;
252+
submit_cleanup_bo(submit, i, cleanup_flags);
248253

249254
if (!(submit->bos[i].flags & BO_VALID))
250255
submit->bos[i].iova = 0;
@@ -377,7 +382,7 @@ static int submit_pin_objects(struct msm_gem_submit *submit)
377382
if (ret)
378383
break;
379384

380-
submit->bos[i].flags |= BO_PINNED;
385+
submit->bos[i].flags |= BO_OBJ_PINNED | BO_VMA_PINNED;
381386
submit->bos[i].vma = vma;
382387

383388
if (vma->iova == submit->bos[i].iova) {
@@ -511,7 +516,7 @@ static void submit_cleanup(struct msm_gem_submit *submit, bool error)
511516
unsigned i;
512517

513518
if (error)
514-
cleanup_flags |= BO_PINNED | BO_ACTIVE;
519+
cleanup_flags |= BO_VMA_PINNED | BO_OBJ_PINNED | BO_ACTIVE;
515520

516521
for (i = 0; i < submit->nr_bos; i++) {
517522
struct msm_gem_object *msm_obj = submit->bos[i].obj;
@@ -529,7 +534,8 @@ void msm_submit_retire(struct msm_gem_submit *submit)
529534
struct drm_gem_object *obj = &submit->bos[i].obj->base;
530535

531536
msm_gem_lock(obj);
532-
submit_cleanup_bo(submit, i, BO_PINNED | BO_ACTIVE);
537+
/* Note, VMA already fence-unpinned before submit: */
538+
submit_cleanup_bo(submit, i, BO_OBJ_PINNED | BO_ACTIVE);
533539
msm_gem_unlock(obj);
534540
drm_gem_object_put(obj);
535541
}

drivers/gpu/drm/msm/msm_ringbuffer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ static struct dma_fence *msm_job_run(struct drm_sched_job *job)
2525

2626
msm_gem_lock(obj);
2727
msm_gem_unpin_vma_fenced(submit->bos[i].vma, fctx);
28-
submit->bos[i].flags &= ~BO_PINNED;
28+
submit->bos[i].flags &= ~BO_VMA_PINNED;
2929
msm_gem_unlock(obj);
3030
}
3131

0 commit comments

Comments
 (0)