drm/nouveau/core/object: support lookup of specific object types

It turns out we have a nice and convenient way of looking up a specific
object type already, by using the func pointer as a key.

This will be used to remove the separate object trees for each type we
need to be able to search for.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Ben Skeggs 2016-12-22 15:22:25 +10:00
parent 05073caeed
commit 110cccff95
2 changed files with 65 additions and 1 deletions

View File

@ -62,6 +62,11 @@ int nvkm_object_wr32(struct nvkm_object *, u64 addr, u32 data);
int nvkm_object_bind(struct nvkm_object *, struct nvkm_gpuobj *, int align,
struct nvkm_gpuobj **);
bool nvkm_object_insert(struct nvkm_object *);
void nvkm_object_remove(struct nvkm_object *);
struct nvkm_object *nvkm_object_search(struct nvkm_client *, u64 object,
const struct nvkm_object_func *);
struct nvkm_sclass {
int minver;
int maxver;

View File

@ -25,6 +25,65 @@
#include <core/client.h>
#include <core/engine.h>
struct nvkm_object *
nvkm_object_search(struct nvkm_client *client, u64 handle,
const struct nvkm_object_func *func)
{
struct nvkm_object *object;
if (handle) {
struct rb_node *node = client->objroot.rb_node;
while (node) {
object = rb_entry(node, typeof(*object), node);
if (handle < object->object)
node = node->rb_left;
else
if (handle > object->object)
node = node->rb_right;
else
goto done;
}
return ERR_PTR(-ENOENT);
} else {
object = &client->object;
}
done:
if (unlikely(func && object->func != func))
return ERR_PTR(-EINVAL);
return object;
}
void
nvkm_object_remove(struct nvkm_object *object)
{
if (!RB_EMPTY_NODE(&object->node))
rb_erase(&object->node, &object->client->objroot);
}
bool
nvkm_object_insert(struct nvkm_object *object)
{
struct rb_node **ptr = &object->client->objroot.rb_node;
struct rb_node *parent = NULL;
while (*ptr) {
struct nvkm_object *this = rb_entry(*ptr, typeof(*this), node);
parent = *ptr;
if (object->object < this->object)
ptr = &parent->rb_left;
else
if (object->object > this->object)
ptr = &parent->rb_right;
else
return false;
}
rb_link_node(&object->node, parent, ptr);
rb_insert_color(&object->node, &object->client->objroot);
return true;
}
int
nvkm_object_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
@ -214,7 +273,7 @@ nvkm_object_del(struct nvkm_object **pobject)
struct nvkm_object *object = *pobject;
if (object && !WARN_ON(!object->func)) {
*pobject = nvkm_object_dtor(object);
nvkm_client_remove(object->client, object);
nvkm_object_remove(object);
list_del(&object->head);
kfree(*pobject);
*pobject = NULL;