Message ID | 20210120111240.2509679-3-kraxel@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/qxl: fix some driver shutdown issues. | expand |
Hi Am 20.01.21 um 12:12 schrieb Gerd Hoffmann: > Balances the qxl_create_bo(..., pinned=true, ...); > call in qxl_release_bo_alloc(). > > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> > --- > drivers/gpu/drm/qxl/qxl_release.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c > index 0fcfc952d5e9..add979cba11b 100644 > --- a/drivers/gpu/drm/qxl/qxl_release.c > +++ b/drivers/gpu/drm/qxl/qxl_release.c > @@ -166,6 +166,7 @@ qxl_release_free_list(struct qxl_release *release) > entry = container_of(release->bos.next, > struct qxl_bo_list, tv.head); > bo = to_qxl_bo(entry->tv.bo); > + bo->tbo.pin_count = 0; /* ttm_bo_unpin(&bo->tbo); */ This code looks like a workaround or a bug. AFAICT the only place with pre-pinned BO is qdev->dumb_shadow_bo. Can you remove the pinned flag entirely and handle pinning as part of dumb_shadow_bo's code. Otherwise maybe use if (pin_count) ttm_bo_unpin(); WARN_ON(pin_count); /* should always be 0 now */ with a comment similar to the commit's description. Best regards Thomas > qxl_bo_unref(&bo); > list_del(&entry->tv.head); > kfree(entry); >
On Fri, Jan 22, 2021 at 09:13:42AM +0100, Thomas Zimmermann wrote: > Hi > > Am 20.01.21 um 12:12 schrieb Gerd Hoffmann: > > Balances the qxl_create_bo(..., pinned=true, ...); > > call in qxl_release_bo_alloc(). > > > > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> > > --- > > drivers/gpu/drm/qxl/qxl_release.c | 1 + > > 1 file changed, 1 insertion(+) > > > > diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c > > index 0fcfc952d5e9..add979cba11b 100644 > > --- a/drivers/gpu/drm/qxl/qxl_release.c > > +++ b/drivers/gpu/drm/qxl/qxl_release.c > > @@ -166,6 +166,7 @@ qxl_release_free_list(struct qxl_release *release) > > entry = container_of(release->bos.next, > > struct qxl_bo_list, tv.head); > > bo = to_qxl_bo(entry->tv.bo); > > + bo->tbo.pin_count = 0; /* ttm_bo_unpin(&bo->tbo); */ > > This code looks like a workaround or a bug. > > AFAICT the only place with pre-pinned BO is qdev->dumb_shadow_bo. Can you > remove the pinned flag entirely and handle pinning as part of > dumb_shadow_bo's code. No, the release objects are pinned too, and they must be pinned (qxl commands are in there, and references are placed in the qxl rings, so allowing them to roam is a non-starter). > if (pin_count) > ttm_bo_unpin(); > WARN_ON(pin_count); /* should always be 0 now */ Well, the pin_count is 1 at this point. No need for the if(). Just calling ttm_bo_unpin() here makes lockdep unhappy. Not calling ttm_bo_unpin() makes ttm_bo_release() throw a WARN() because of the pin. Clearing pin_count (which is how ttm fixes things up in the error path) works. I'm open to better ideas. take care, Gerd
On Fri, Jan 22, 2021 at 2:35 PM Gerd Hoffmann <kraxel@redhat.com> wrote: > > On Fri, Jan 22, 2021 at 09:13:42AM +0100, Thomas Zimmermann wrote: > > Hi > > > > Am 20.01.21 um 12:12 schrieb Gerd Hoffmann: > > > Balances the qxl_create_bo(..., pinned=true, ...); > > > call in qxl_release_bo_alloc(). > > > > > > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> > > > --- > > > drivers/gpu/drm/qxl/qxl_release.c | 1 + > > > 1 file changed, 1 insertion(+) > > > > > > diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c > > > index 0fcfc952d5e9..add979cba11b 100644 > > > --- a/drivers/gpu/drm/qxl/qxl_release.c > > > +++ b/drivers/gpu/drm/qxl/qxl_release.c > > > @@ -166,6 +166,7 @@ qxl_release_free_list(struct qxl_release *release) > > > entry = container_of(release->bos.next, > > > struct qxl_bo_list, tv.head); > > > bo = to_qxl_bo(entry->tv.bo); > > > + bo->tbo.pin_count = 0; /* ttm_bo_unpin(&bo->tbo); */ > > > > This code looks like a workaround or a bug. > > > > AFAICT the only place with pre-pinned BO is qdev->dumb_shadow_bo. Can you > > remove the pinned flag entirely and handle pinning as part of > > dumb_shadow_bo's code. > > No, the release objects are pinned too, and they must be > pinned (qxl commands are in there, and references are > placed in the qxl rings, so allowing them to roam is > a non-starter). > > > if (pin_count) > > ttm_bo_unpin(); > > WARN_ON(pin_count); /* should always be 0 now */ > > Well, the pin_count is 1 at this point. > No need for the if(). > > Just calling ttm_bo_unpin() here makes lockdep unhappy. How does that one splat? But yeah if that's a problem should be explained in the comment. I'd then also only do a pin_count--; to make sure you can still catch other pin leaks if you have them. Setting it to 0 kinda defeats the warning. -Daniel > > Not calling ttm_bo_unpin() makes ttm_bo_release() throw > a WARN() because of the pin. > > Clearing pin_count (which is how ttm fixes things up > in the error path) works. > > I'm open to better ideas. > > take care, > Gerd > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> > Just calling ttm_bo_unpin() here makes lockdep unhappy. > > How does that one splat? But yeah if that's a problem should be > explained in the comment. I'd then also only do a pin_count--; to make > sure you can still catch other pin leaks if you have them. Setting it > to 0 kinda defeats the warning. Figured the unpin is at the completely wrong place while trying to reproduce the lockdep splat ... take care, Gerd From 43befab4a935114e8620af62781666fa81288255 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann <kraxel@redhat.com> Date: Mon, 25 Jan 2021 13:10:50 +0100 Subject: [PATCH] drm/qxl: unpin release objects Balances the qxl_create_bo(..., pinned=true, ...); call in qxl_release_bo_alloc(). Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- drivers/gpu/drm/qxl/qxl_release.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index c52412724c26..28013fd1f8ea 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -347,6 +347,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, mutex_lock(&qdev->release_mutex); if (qdev->current_release_bo_offset[cur_idx] + 1 >= releases_per_bo[cur_idx]) { + qxl_bo_unpin(qdev->current_release_bo[cur_idx]); qxl_bo_unref(&qdev->current_release_bo[cur_idx]); qdev->current_release_bo_offset[cur_idx] = 0; qdev->current_release_bo[cur_idx] = NULL;
diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index 0fcfc952d5e9..add979cba11b 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -166,6 +166,7 @@ qxl_release_free_list(struct qxl_release *release) entry = container_of(release->bos.next, struct qxl_bo_list, tv.head); bo = to_qxl_bo(entry->tv.bo); + bo->tbo.pin_count = 0; /* ttm_bo_unpin(&bo->tbo); */ qxl_bo_unref(&bo); list_del(&entry->tv.head); kfree(entry);
Balances the qxl_create_bo(..., pinned=true, ...); call in qxl_release_bo_alloc(). Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- drivers/gpu/drm/qxl/qxl_release.c | 1 + 1 file changed, 1 insertion(+)