Commit 5cc8d536 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau: wake up the card if necessary during gem callbacks

The failure paths if we fail to wake the card are less than desirable,
but there's not really a graceful way to handle this case currently.

I'll keep this situation in mind when I get to fixing other vm-related
issues.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 8d5e3af1
...@@ -36,7 +36,14 @@ void ...@@ -36,7 +36,14 @@ void
nouveau_gem_object_del(struct drm_gem_object *gem) nouveau_gem_object_del(struct drm_gem_object *gem)
{ {
struct nouveau_bo *nvbo = nouveau_gem_object(gem); struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct ttm_buffer_object *bo = &nvbo->bo; struct ttm_buffer_object *bo = &nvbo->bo;
struct device *dev = drm->dev->dev;
int ret;
ret = pm_runtime_get_sync(dev);
if (WARN_ON(ret < 0 && ret != -EACCES))
return;
if (gem->import_attach) if (gem->import_attach)
drm_prime_gem_destroy(gem, nvbo->bo.sg); drm_prime_gem_destroy(gem, nvbo->bo.sg);
...@@ -46,6 +53,9 @@ nouveau_gem_object_del(struct drm_gem_object *gem) ...@@ -46,6 +53,9 @@ nouveau_gem_object_del(struct drm_gem_object *gem)
/* reset filp so nouveau_bo_del_ttm() can test for it */ /* reset filp so nouveau_bo_del_ttm() can test for it */
gem->filp = NULL; gem->filp = NULL;
ttm_bo_unref(&bo); ttm_bo_unref(&bo);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
} }
int int
...@@ -53,7 +63,9 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) ...@@ -53,7 +63,9 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
{ {
struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_bo *nvbo = nouveau_gem_object(gem); struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct nouveau_vma *vma; struct nouveau_vma *vma;
struct device *dev = drm->dev->dev;
int ret; int ret;
if (!cli->vm) if (!cli->vm)
...@@ -71,11 +83,16 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) ...@@ -71,11 +83,16 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
goto out; goto out;
} }
ret = pm_runtime_get_sync(dev);
if (ret < 0 && ret != -EACCES)
goto out;
ret = nouveau_bo_vma_add(nvbo, cli->vm, vma); ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
if (ret) { if (ret)
kfree(vma); kfree(vma);
goto out;
} pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
} else { } else {
vma->refcount++; vma->refcount++;
} }
...@@ -129,6 +146,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) ...@@ -129,6 +146,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
{ {
struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_bo *nvbo = nouveau_gem_object(gem); struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct device *dev = drm->dev->dev;
struct nouveau_vma *vma; struct nouveau_vma *vma;
int ret; int ret;
...@@ -141,8 +160,14 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) ...@@ -141,8 +160,14 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
vma = nouveau_bo_vma_find(nvbo, cli->vm); vma = nouveau_bo_vma_find(nvbo, cli->vm);
if (vma) { if (vma) {
if (--vma->refcount == 0) if (--vma->refcount == 0) {
ret = pm_runtime_get_sync(dev);
if (!WARN_ON(ret < 0 && ret != -EACCES)) {
nouveau_gem_object_unmap(nvbo, vma); nouveau_gem_object_unmap(nvbo, vma);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
}
}
} }
ttm_bo_unreserve(&nvbo->bo); ttm_bo_unreserve(&nvbo->bo);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment