Commit 9242829a authored by Maarten Lankhorst's avatar Maarten Lankhorst

drm/nouveau: Keep only a single list for validation.

Maintain the original order to handle VRAM/GART/mixed correctly for <nv50,
it's likely not as important on newer cards.
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@canonical.com>
Acked-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 472db7ab
...@@ -284,21 +284,17 @@ nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains, ...@@ -284,21 +284,17 @@ nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains,
} }
struct validate_op { struct validate_op {
struct list_head vram_list; struct list_head list;
struct list_head gart_list;
struct list_head both_list;
struct ww_acquire_ctx ticket; struct ww_acquire_ctx ticket;
}; };
static void static void
validate_fini_list(struct list_head *list, struct nouveau_fence *fence, validate_fini_no_ticket(struct validate_op *op, struct nouveau_fence *fence)
struct ww_acquire_ctx *ticket)
{ {
struct list_head *entry, *tmp;
struct nouveau_bo *nvbo; struct nouveau_bo *nvbo;
list_for_each_safe(entry, tmp, list) { while (!list_empty(&op->list)) {
nvbo = list_entry(entry, struct nouveau_bo, entry); nvbo = list_entry(op->list.next, struct nouveau_bo, entry);
if (likely(fence)) if (likely(fence))
nouveau_bo_fence(nvbo, fence); nouveau_bo_fence(nvbo, fence);
...@@ -310,19 +306,11 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence, ...@@ -310,19 +306,11 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence,
list_del(&nvbo->entry); list_del(&nvbo->entry);
nvbo->reserved_by = NULL; nvbo->reserved_by = NULL;
ttm_bo_unreserve_ticket(&nvbo->bo, ticket); ttm_bo_unreserve_ticket(&nvbo->bo, &op->ticket);
drm_gem_object_unreference_unlocked(&nvbo->gem); drm_gem_object_unreference_unlocked(&nvbo->gem);
} }
} }
static void
validate_fini_no_ticket(struct validate_op *op, struct nouveau_fence *fence)
{
validate_fini_list(&op->vram_list, fence, &op->ticket);
validate_fini_list(&op->gart_list, fence, &op->ticket);
validate_fini_list(&op->both_list, fence, &op->ticket);
}
static void static void
validate_fini(struct validate_op *op, struct nouveau_fence *fence) validate_fini(struct validate_op *op, struct nouveau_fence *fence)
{ {
...@@ -340,6 +328,9 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, ...@@ -340,6 +328,9 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
int trycnt = 0; int trycnt = 0;
int ret, i; int ret, i;
struct nouveau_bo *res_bo = NULL; struct nouveau_bo *res_bo = NULL;
LIST_HEAD(gart_list);
LIST_HEAD(vram_list);
LIST_HEAD(both_list);
ww_acquire_init(&op->ticket, &reservation_ww_class); ww_acquire_init(&op->ticket, &reservation_ww_class);
retry: retry:
...@@ -356,9 +347,8 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, ...@@ -356,9 +347,8 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
gem = drm_gem_object_lookup(dev, file_priv, b->handle); gem = drm_gem_object_lookup(dev, file_priv, b->handle);
if (!gem) { if (!gem) {
NV_PRINTK(error, cli, "Unknown handle 0x%08x\n", b->handle); NV_PRINTK(error, cli, "Unknown handle 0x%08x\n", b->handle);
ww_acquire_done(&op->ticket); ret = -ENOENT;
validate_fini(op, NULL); break;
return -ENOENT;
} }
nvbo = nouveau_gem_object(gem); nvbo = nouveau_gem_object(gem);
if (nvbo == res_bo) { if (nvbo == res_bo) {
...@@ -371,13 +361,15 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, ...@@ -371,13 +361,15 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
NV_PRINTK(error, cli, "multiple instances of buffer %d on " NV_PRINTK(error, cli, "multiple instances of buffer %d on "
"validation list\n", b->handle); "validation list\n", b->handle);
drm_gem_object_unreference_unlocked(gem); drm_gem_object_unreference_unlocked(gem);
ww_acquire_done(&op->ticket); ret = -EINVAL;
validate_fini(op, NULL); break;
return -EINVAL;
} }
ret = ttm_bo_reserve(&nvbo->bo, true, false, true, &op->ticket); ret = ttm_bo_reserve(&nvbo->bo, true, false, true, &op->ticket);
if (ret) { if (ret) {
list_splice_tail_init(&vram_list, &op->list);
list_splice_tail_init(&gart_list, &op->list);
list_splice_tail_init(&both_list, &op->list);
validate_fini_no_ticket(op, NULL); validate_fini_no_ticket(op, NULL);
if (unlikely(ret == -EDEADLK)) { if (unlikely(ret == -EDEADLK)) {
ret = ttm_bo_reserve_slowpath(&nvbo->bo, true, ret = ttm_bo_reserve_slowpath(&nvbo->bo, true,
...@@ -386,12 +378,9 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, ...@@ -386,12 +378,9 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
res_bo = nvbo; res_bo = nvbo;
} }
if (unlikely(ret)) { if (unlikely(ret)) {
ww_acquire_done(&op->ticket);
ww_acquire_fini(&op->ticket);
drm_gem_object_unreference_unlocked(gem);
if (ret != -ERESTARTSYS) if (ret != -ERESTARTSYS)
NV_PRINTK(error, cli, "fail reserve\n"); NV_PRINTK(error, cli, "fail reserve\n");
return ret; break;
} }
} }
...@@ -400,27 +389,32 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, ...@@ -400,27 +389,32 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
nvbo->pbbo_index = i; nvbo->pbbo_index = i;
if ((b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && if ((b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
(b->valid_domains & NOUVEAU_GEM_DOMAIN_GART)) (b->valid_domains & NOUVEAU_GEM_DOMAIN_GART))
list_add_tail(&nvbo->entry, &op->both_list); list_add_tail(&nvbo->entry, &both_list);
else else
if (b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) if (b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM)
list_add_tail(&nvbo->entry, &op->vram_list); list_add_tail(&nvbo->entry, &vram_list);
else else
if (b->valid_domains & NOUVEAU_GEM_DOMAIN_GART) if (b->valid_domains & NOUVEAU_GEM_DOMAIN_GART)
list_add_tail(&nvbo->entry, &op->gart_list); list_add_tail(&nvbo->entry, &gart_list);
else { else {
NV_PRINTK(error, cli, "invalid valid domains: 0x%08x\n", NV_PRINTK(error, cli, "invalid valid domains: 0x%08x\n",
b->valid_domains); b->valid_domains);
list_add_tail(&nvbo->entry, &op->both_list); list_add_tail(&nvbo->entry, &both_list);
ww_acquire_done(&op->ticket); ret = -EINVAL;
validate_fini(op, NULL); break;
return -EINVAL;
} }
if (nvbo == res_bo) if (nvbo == res_bo)
goto retry; goto retry;
} }
ww_acquire_done(&op->ticket); ww_acquire_done(&op->ticket);
return 0; list_splice_tail(&vram_list, &op->list);
list_splice_tail(&gart_list, &op->list);
list_splice_tail(&both_list, &op->list);
if (ret)
validate_fini(op, NULL);
return ret;
} }
static int static int
...@@ -492,11 +486,9 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, ...@@ -492,11 +486,9 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan,
struct validate_op *op, int *apply_relocs) struct validate_op *op, int *apply_relocs)
{ {
struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_cli *cli = nouveau_cli(file_priv);
int ret, relocs = 0; int ret;
INIT_LIST_HEAD(&op->vram_list); INIT_LIST_HEAD(&op->list);
INIT_LIST_HEAD(&op->gart_list);
INIT_LIST_HEAD(&op->both_list);
if (nr_buffers == 0) if (nr_buffers == 0)
return 0; return 0;
...@@ -508,34 +500,14 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, ...@@ -508,34 +500,14 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan,
return ret; return ret;
} }
ret = validate_list(chan, cli, &op->vram_list, pbbo, user_buffers); ret = validate_list(chan, cli, &op->list, pbbo, user_buffers);
if (unlikely(ret < 0)) { if (unlikely(ret < 0)) {
if (ret != -ERESTARTSYS) if (ret != -ERESTARTSYS)
NV_PRINTK(error, cli, "validate vram_list\n"); NV_PRINTK(error, cli, "validating bo list\n");
validate_fini(op, NULL); validate_fini(op, NULL);
return ret; return ret;
} }
relocs += ret; *apply_relocs = ret;
ret = validate_list(chan, cli, &op->gart_list, pbbo, user_buffers);
if (unlikely(ret < 0)) {
if (ret != -ERESTARTSYS)
NV_PRINTK(error, cli, "validate gart_list\n");
validate_fini(op, NULL);
return ret;
}
relocs += ret;
ret = validate_list(chan, cli, &op->both_list, pbbo, user_buffers);
if (unlikely(ret < 0)) {
if (ret != -ERESTARTSYS)
NV_PRINTK(error, cli, "validate both_list\n");
validate_fini(op, NULL);
return ret;
}
relocs += ret;
*apply_relocs = relocs;
return 0; return 0;
} }
......
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