Skip to content

Commit

Permalink
drm/nouveau: wake up the card if necessary during gem callbacks
Browse files Browse the repository at this point in the history
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: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information
Ben Skeggs committed Dec 21, 2014
1 parent 8d5e3af commit 5cc8d53
Showing 1 changed file with 30 additions and 5 deletions.
35 changes: 30 additions & 5 deletions drivers/gpu/drm/nouveau/nouveau_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,14 @@ void
nouveau_gem_object_del(struct drm_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 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)
drm_prime_gem_destroy(gem, nvbo->bo.sg);
Expand All @@ -46,14 +53,19 @@ nouveau_gem_object_del(struct drm_gem_object *gem)
/* reset filp so nouveau_bo_del_ttm() can test for it */
gem->filp = NULL;
ttm_bo_unref(&bo);

pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
}

int
nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
{
struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct nouveau_vma *vma;
struct device *dev = drm->dev->dev;
int ret;

if (!cli->vm)
Expand All @@ -71,11 +83,16 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
goto out;
}

ret = pm_runtime_get_sync(dev);
if (ret < 0 && ret != -EACCES)
goto out;

ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
if (ret) {
if (ret)
kfree(vma);
goto out;
}

pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
} else {
vma->refcount++;
}
Expand Down Expand Up @@ -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_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;
int ret;

Expand All @@ -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);
if (vma) {
if (--vma->refcount == 0)
nouveau_gem_object_unmap(nvbo, vma);
if (--vma->refcount == 0) {
ret = pm_runtime_get_sync(dev);
if (!WARN_ON(ret < 0 && ret != -EACCES)) {
nouveau_gem_object_unmap(nvbo, vma);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
}
}
}
ttm_bo_unreserve(&nvbo->bo);
}
Expand Down

0 comments on commit 5cc8d53

Please sign in to comment.