diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2015-08-20 14:54:16 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2015-08-28 12:40:32 +1000 |
commit | bf81df9be28657eea4aca8c6ab4ed3e69f8a051c (patch) | |
tree | a4a7e6f3d4e46696584c930bb7d6b4b2fd941337 /drivers/gpu/drm/nouveau/nvkm/core | |
parent | a01ca78c8f118e5a24f1527ecf078ab56ddd4805 (diff) |
drm/nouveau/nvif: replace path-based object identification
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/core')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/core/client.c | 50 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/core/handle.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/core/ioctl.c | 51 |
3 files changed, 76 insertions, 47 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/client.c b/drivers/gpu/drm/nouveau/nvkm/core/client.c index 7615cdd75294..bfe5357d7334 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/client.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/client.c @@ -183,6 +183,55 @@ nvkm_client_oclass = { }, }; +void +nvkm_client_remove(struct nvkm_client *client, struct nvkm_handle *object) +{ + if (!RB_EMPTY_NODE(&object->rb)) + rb_erase(&object->rb, &client->objroot); +} + +bool +nvkm_client_insert(struct nvkm_client *client, struct nvkm_handle *object) +{ + struct rb_node **ptr = &client->objroot.rb_node; + struct rb_node *parent = NULL; + + while (*ptr) { + struct nvkm_handle *this = + container_of(*ptr, typeof(*this), rb); + parent = *ptr; + if (object->handle < this->handle) + ptr = &parent->rb_left; + else + if (object->handle > this->handle) + ptr = &parent->rb_right; + else + return false; + } + + rb_link_node(&object->rb, parent, ptr); + rb_insert_color(&object->rb, &client->objroot); + return true; +} + +struct nvkm_handle * +nvkm_client_search(struct nvkm_client *client, u64 handle) +{ + struct rb_node *node = client->objroot.rb_node; + while (node) { + struct nvkm_handle *object = + container_of(node, typeof(*object), rb); + if (handle < object->handle) + node = node->rb_left; + else + if (handle > object->handle) + node = node->rb_right; + else + return object; + } + return NULL; +} + int nvkm_client_fini(struct nvkm_client *client, bool suspend) { @@ -256,6 +305,7 @@ nvkm_client_new(const char *name, u64 device, const char *cfg, client->device = device; snprintf(client->name, sizeof(client->name), "%s", name); client->debug = nvkm_dbgopt(dbg, "CLIENT"); + client->objroot = RB_ROOT; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/core/handle.c b/drivers/gpu/drm/nouveau/nvkm/core/handle.c index 6230eaece64d..a12ab8001701 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/handle.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/handle.c @@ -113,6 +113,7 @@ nvkm_handle_create(struct nvkm_object *parent, u32 _parent, u32 _handle, INIT_LIST_HEAD(&handle->tree); handle->name = _handle; handle->priv = ~0; + RB_CLEAR_NODE(&handle->rb); ret = nvkm_namedb_insert(nv_namedb(namedb), _handle, object, handle); if (ret) { @@ -149,12 +150,15 @@ nvkm_handle_create(struct nvkm_object *parent, u32 _parent, u32 _handle, void nvkm_handle_destroy(struct nvkm_handle *handle) { + struct nvkm_client *client = nvkm_client(handle->object); struct nvkm_handle *item, *temp; hprintk(handle, TRACE, "destroy running\n"); list_for_each_entry_safe(item, temp, &handle->tree, head) { nvkm_handle_destroy(item); } + + nvkm_client_remove(client, handle); list_del(&handle->head); if (handle->priv != ~0) { @@ -167,24 +171,6 @@ nvkm_handle_destroy(struct nvkm_handle *handle) kfree(handle); } -struct nvkm_object * -nvkm_handle_ref(struct nvkm_object *parent, u32 name) -{ - struct nvkm_object *object = NULL; - struct nvkm_handle *handle; - - while (!nv_iclass(parent, NV_NAMEDB_CLASS)) - parent = parent->parent; - - handle = nvkm_namedb_get(nv_namedb(parent), name); - if (handle) { - nvkm_object_ref(handle->object, &object); - nvkm_namedb_put(handle); - } - - return object; -} - struct nvkm_handle * nvkm_handle_get_class(struct nvkm_object *engctx, u16 oclass) { diff --git a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c index 7434958846f7..7654783e8350 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c @@ -103,9 +103,9 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) return ret; nvif_ioctl(handle->object, "new vers %d handle %08x class %08x " - "route %02x token %llx\n", + "route %02x token %llx object %016llx\n", args->v0.version, _handle, _oclass, - args->v0.route, args->v0.token); + args->v0.route, args->v0.token, args->v0.object); if (!nv_iclass(handle->object, NV_PARENT_CLASS)) { nvif_debug(handle->object, "cannot have children (ctor)\n"); @@ -166,6 +166,8 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) if (ret) nvkm_handle_destroy(handle); + handle->handle = args->v0.object; + nvkm_client_insert(client, handle); fail_handle: nvkm_object_dec(object, false); fail_init: @@ -438,40 +440,31 @@ nvkm_ioctl_v0[] = { }; static int -nvkm_ioctl_path(struct nvkm_handle *parent, u32 type, u32 nr, u32 *path, +nvkm_ioctl_path(struct nvkm_client *client, u64 handle, u32 type, void *data, u32 size, u8 owner, u8 *route, u64 *token) { - struct nvkm_handle *handle = parent; - struct nvkm_namedb *namedb; - struct nvkm_object *object; + struct nvkm_handle *object; int ret; - while ((object = parent->object), nr--) { - nvif_ioctl(object, "path 0x%08x\n", path[nr]); - if (!nv_iclass(object, NV_PARENT_CLASS)) { - nvif_debug(object, "cannot have children (path)\n"); - return -EINVAL; - } - - if (!(namedb = (void *)nv_pclass(object, NV_NAMEDB_CLASS)) || - !(handle = nvkm_namedb_get(namedb, path[nr]))) { - nvif_debug(object, "handle 0x%08x not found\n", path[nr]); - return -ENOENT; - } - nvkm_namedb_put(handle); - parent = handle; + if (handle) + object = nvkm_client_search(client, handle); + else + object = client->root; + if (unlikely(!object)) { + nvif_ioctl(&client->namedb.parent.object, "object not found\n"); + return -ENOENT; } - if (owner != NVIF_IOCTL_V0_OWNER_ANY && owner != handle->route) { - nvif_ioctl(object, "object route != owner\n"); + if (owner != NVIF_IOCTL_V0_OWNER_ANY && owner != object->route) { + nvif_ioctl(&client->namedb.parent.object, "route != owner\n"); return -EACCES; } - *route = handle->route; - *token = handle->token; + *route = object->route; + *token = object->token; if (ret = -EINVAL, type < ARRAY_SIZE(nvkm_ioctl_v0)) { if (nvkm_ioctl_v0[type].version == 0) - ret = nvkm_ioctl_v0[type].func(handle, data, size); + ret = nvkm_ioctl_v0[type].func(object, data, size); } return ret; @@ -491,11 +484,11 @@ nvkm_ioctl(struct nvkm_client *client, bool supervisor, nvif_ioctl(object, "size %d\n", size); if (nvif_unpack(args->v0, 0, 0, true)) { - nvif_ioctl(object, "vers %d type %02x path %d owner %02x\n", - args->v0.version, args->v0.type, args->v0.path_nr, + nvif_ioctl(object, + "vers %d type %02x object %016llx owner %02x\n", + args->v0.version, args->v0.type, args->v0.object, args->v0.owner); - ret = nvkm_ioctl_path(client->root, args->v0.type, - args->v0.path_nr, args->v0.path, + ret = nvkm_ioctl_path(client, args->v0.object, args->v0.type, data, size, args->v0.owner, &args->v0.route, &args->v0.token); } |