drm/nouveau/object: merge with handle
authorBen Skeggs <bskeggs@redhat.com>
Thu, 20 Aug 2015 04:54:22 +0000 (14:54 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 28 Aug 2015 02:40:47 +0000 (12:40 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
18 files changed:
drivers/gpu/drm/nouveau/include/nvkm/core/client.h
drivers/gpu/drm/nouveau/include/nvkm/core/handle.h [deleted file]
drivers/gpu/drm/nouveau/include/nvkm/core/object.h
drivers/gpu/drm/nouveau/nouveau_abi16.c
drivers/gpu/drm/nouveau/nouveau_chan.c
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/nouveau/nvkm/core/Kbuild
drivers/gpu/drm/nouveau/nvkm/core/client.c
drivers/gpu/drm/nouveau/nvkm/core/handle.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
drivers/gpu/drm/nouveau/nvkm/core/object.c
drivers/gpu/drm/nouveau/nvkm/core/oproxy.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c

index 5485bba..eaf5905 100644 (file)
@@ -12,8 +12,6 @@ struct nvkm_client {
        struct rb_root objroot;
        struct rb_root dmaroot;
 
-       struct nvkm_handle *root;
-
        bool super;
        void *data;
        int (*ntfy)(const void *, u32, const void *, u32);
@@ -21,9 +19,9 @@ struct nvkm_client {
        struct nvkm_vm *vm;
 };
 
-bool nvkm_client_insert(struct nvkm_client *, struct nvkm_handle *);
-void nvkm_client_remove(struct nvkm_client *, struct nvkm_handle *);
-struct nvkm_handle *nvkm_client_search(struct nvkm_client *, u64 handle);
+bool nvkm_client_insert(struct nvkm_client *, struct nvkm_object *);
+void nvkm_client_remove(struct nvkm_client *, struct nvkm_object *);
+struct nvkm_object *nvkm_client_search(struct nvkm_client *, u64 object);
 
 int  nvkm_client_new(const char *name, u64 device, const char *cfg,
                     const char *dbg, struct nvkm_client **);
@@ -31,14 +29,6 @@ void nvkm_client_del(struct nvkm_client **);
 int  nvkm_client_init(struct nvkm_client *);
 int  nvkm_client_fini(struct nvkm_client *, bool suspend);
 
-static inline struct nvkm_client *
-nvkm_client(struct nvkm_object *object)
-{
-       while (object && object->parent)
-               object = object->parent;
-       return container_of(object, struct nvkm_client, object);
-}
-
 int nvkm_client_notify_new(struct nvkm_object *, struct nvkm_event *,
                           void *data, u32 size);
 int nvkm_client_notify_del(struct nvkm_client *, int index);
@@ -48,12 +38,15 @@ int nvkm_client_notify_put(struct nvkm_client *, int index);
 /* logging for client-facing objects */
 #define nvif_printk(o,l,p,f,a...) do {                                         \
        struct nvkm_object *_object = (o);                                     \
-       struct nvkm_client *_client = nvkm_client(_object);                    \
+       struct nvkm_client *_client = _object->client;                         \
        if (_client->debug >= NV_DBG_##l)                                      \
-               printk(KERN_##p "nouveau: %s: "f, _client->name, ##a);         \
+               printk(KERN_##p "nouveau: %s:%08x:%08x: "f, _client->name,     \
+                      _object->handle, _object->oclass, ##a);                 \
 } while(0)
+#define nvif_fatal(o,f,a...) nvif_printk((o), FATAL, CRIT, f, ##a)
 #define nvif_error(o,f,a...) nvif_printk((o), ERROR,  ERR, f, ##a)
 #define nvif_debug(o,f,a...) nvif_printk((o), DEBUG, INFO, f, ##a)
 #define nvif_trace(o,f,a...) nvif_printk((o), TRACE, INFO, f, ##a)
+#define nvif_info(o,f,a...)  nvif_printk((o),  INFO, INFO, f, ##a)
 #define nvif_ioctl(o,f,a...) nvif_trace((o), "ioctl: "f, ##a)
 #endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/handle.h b/drivers/gpu/drm/nouveau/include/nvkm/core/handle.h
deleted file mode 100644 (file)
index 5392789..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __NVKM_HANDLE_H__
-#define __NVKM_HANDLE_H__
-#include <core/os.h>
-struct nvkm_object;
-
-struct nvkm_handle {
-       struct list_head node;
-
-       struct list_head head;
-       struct list_head tree;
-       u32 name;
-       u32 priv;
-
-       u8  route;
-       u64 token;
-
-       struct nvkm_handle *parent;
-       struct nvkm_object *object;
-
-       struct rb_node rb;
-       u64 handle;
-};
-
-int  nvkm_handle_create(struct nvkm_handle *, u32 handle,
-                       struct nvkm_object *, struct nvkm_handle **);
-void nvkm_handle_destroy(struct nvkm_handle *);
-int  nvkm_handle_init(struct nvkm_handle *);
-int  nvkm_handle_fini(struct nvkm_handle *, bool suspend);
-
-struct nvkm_handle *nvkm_handle_get_class(struct nvkm_object *, u16);
-struct nvkm_handle *nvkm_handle_get_vinst(struct nvkm_object *, u64);
-struct nvkm_handle *nvkm_handle_get_cinst(struct nvkm_object *, u32);
-void nvkm_handle_put(struct nvkm_handle *);
-#endif
index b4b822f..dcd048b 100644 (file)
@@ -10,12 +10,15 @@ struct nvkm_object {
        const struct nvkm_object_func *func;
        struct nvkm_client *client;
        struct nvkm_engine *engine;
-       u32 oclass;
+       s32 oclass;
        u32 handle;
-       struct nvkm_object *parent;
-       u32 pclass;
-       atomic_t refcount;
-       atomic_t usecount;
+
+       struct list_head head;
+       struct list_head tree;
+       u8  route;
+       u64 token;
+       u64 object;
+       struct rb_node node;
 };
 
 struct nvkm_object_func {
@@ -43,6 +46,8 @@ int nvkm_object_new_(const struct nvkm_object_func *,
                     struct nvkm_object **);
 int nvkm_object_new(const struct nvkm_oclass *, void *data, u32 size,
                    struct nvkm_object **);
+void nvkm_object_del(struct nvkm_object **);
+void *nvkm_object_dtor(struct nvkm_object *);
 int nvkm_object_init(struct nvkm_object *);
 int nvkm_object_fini(struct nvkm_object *, bool suspend);
 int nvkm_object_mthd(struct nvkm_object *, u32 mthd, void *data, u32 size);
@@ -72,14 +77,12 @@ struct nvkm_oclass {
        struct nvkm_sclass base;
        const void *priv;
        const void *engn;
-       s32 handle;
+       u32 handle;
+       u8  route;
+       u64 token;
        u64 object;
        struct nvkm_client *client;
        struct nvkm_object *parent;
        struct nvkm_engine *engine;
 };
-
-void nvkm_object_ref(struct nvkm_object *, struct nvkm_object **);
-int  nvkm_object_inc(struct nvkm_object *);
-int  nvkm_object_dec(struct nvkm_object *, bool suspend);
 #endif
index 6634f42..40a903b 100644 (file)
@@ -134,6 +134,7 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16,
        /* destroy channel object, all children will be killed too */
        if (chan->chan) {
                abi16->handles &= ~(1ULL << (chan->chan->user.handle & 0xffff));
+               nouveau_channel_idle(chan->chan);
                nouveau_channel_del(&chan->chan);
        }
 
index 4a13bda..8c88c5e 100644 (file)
@@ -43,20 +43,26 @@ module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400);
 int
 nouveau_channel_idle(struct nouveau_channel *chan)
 {
-       struct nouveau_cli *cli = (void *)chan->user.client;
-       struct nouveau_fence *fence = NULL;
-       int ret;
+       if (likely(chan && chan->fence)) {
+               struct nouveau_cli *cli = (void *)chan->user.client;
+               struct nouveau_fence *fence = NULL;
+               int ret;
+
+               ret = nouveau_fence_new(chan, false, &fence);
+               if (!ret) {
+                       ret = nouveau_fence_wait(fence, false, false);
+                       nouveau_fence_unref(&fence);
+               }
 
-       ret = nouveau_fence_new(chan, false, &fence);
-       if (!ret) {
-               ret = nouveau_fence_wait(fence, false, false);
-               nouveau_fence_unref(&fence);
+               if (ret) {
+                       NV_PRINTK(err, cli, "failed to idle channel "
+                                           "0x%08x [%s]\n",
+                                 chan->user.handle,
+                                 nvxx_client(&cli->base)->name);
+                       return ret;
+               }
        }
-
-       if (ret)
-               NV_PRINTK(err, cli, "failed to idle channel 0x%08x [%s]\n",
-                         chan->user.handle, nvxx_client(&cli->base)->name);
-       return ret;
+       return 0;
 }
 
 void
@@ -64,10 +70,8 @@ nouveau_channel_del(struct nouveau_channel **pchan)
 {
        struct nouveau_channel *chan = *pchan;
        if (chan) {
-               if (chan->fence) {
-                       nouveau_channel_idle(chan);
+               if (chan->fence)
                        nouveau_fence(chan->drm)->context_del(chan);
-               }
                nvif_object_fini(&chan->nvsw);
                nvif_object_fini(&chan->gart);
                nvif_object_fini(&chan->vram);
index d04d08c..14a1348 100644 (file)
@@ -139,13 +139,17 @@ nouveau_cli_destroy(struct nouveau_cli *cli)
 static void
 nouveau_accel_fini(struct nouveau_drm *drm)
 {
-       nvif_notify_fini(&drm->flip);
-       nouveau_channel_del(&drm->channel);
+       nouveau_channel_idle(drm->channel);
        nvif_object_fini(&drm->ntfy);
        nvkm_gpuobj_del(&drm->notify);
+       nvif_notify_fini(&drm->flip);
        nvif_object_fini(&drm->nvsw);
-       nouveau_channel_del(&drm->cechan);
+       nouveau_channel_del(&drm->channel);
+
+       nouveau_channel_idle(drm->cechan);
        nvif_object_fini(&drm->ttm.copy);
+       nouveau_channel_del(&drm->cechan);
+
        if (drm->fence)
                nouveau_fence(drm)->dtor(drm);
 }
index 09044cf..7f66963 100644 (file)
@@ -3,7 +3,6 @@ nvkm-y += nvkm/core/engine.o
 nvkm-y += nvkm/core/enum.o
 nvkm-y += nvkm/core/event.o
 nvkm-y += nvkm/core/gpuobj.o
-nvkm-y += nvkm/core/handle.o
 nvkm-y += nvkm/core/ioctl.o
 nvkm-y += nvkm/core/memory.o
 nvkm-y += nvkm/core/mm.o
index ab98f8c..297e1e9 100644 (file)
@@ -23,7 +23,6 @@
  */
 #include <core/client.h>
 #include <core/device.h>
-#include <core/handle.h>
 #include <core/notify.h>
 #include <core/option.h>
 
@@ -91,7 +90,7 @@ int
 nvkm_client_notify_new(struct nvkm_object *object,
                       struct nvkm_event *event, void *data, u32 size)
 {
-       struct nvkm_client *client = nvkm_client(object);
+       struct nvkm_client *client = object->client;
        struct nvkm_client_notify *notify;
        union {
                struct nvif_notify_req_v0 v0;
@@ -207,47 +206,47 @@ nvkm_client_object_func = {
 };
 
 void
-nvkm_client_remove(struct nvkm_client *client, struct nvkm_handle *object)
+nvkm_client_remove(struct nvkm_client *client, struct nvkm_object *object)
 {
-       if (!RB_EMPTY_NODE(&object->rb))
-               rb_erase(&object->rb, &client->objroot);
+       if (!RB_EMPTY_NODE(&object->node))
+               rb_erase(&object->node, &client->objroot);
 }
 
 bool
-nvkm_client_insert(struct nvkm_client *client, struct nvkm_handle *object)
+nvkm_client_insert(struct nvkm_client *client, struct nvkm_object *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);
+               struct nvkm_object *this =
+                       container_of(*ptr, typeof(*this), node);
                parent = *ptr;
-               if (object->handle < this->handle)
+               if (object->object < this->object)
                        ptr = &parent->rb_left;
                else
-               if (object->handle > this->handle)
+               if (object->object > this->object)
                        ptr = &parent->rb_right;
                else
                        return false;
        }
 
-       rb_link_node(&object->rb, parent, ptr);
-       rb_insert_color(&object->rb, &client->objroot);
+       rb_link_node(&object->node, parent, ptr);
+       rb_insert_color(&object->node, &client->objroot);
        return true;
 }
 
-struct nvkm_handle *
+struct nvkm_object *
 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)
+               struct nvkm_object *object =
+                       container_of(node, typeof(*object), node);
+               if (handle < object->object)
                        node = node->rb_left;
                else
-               if (handle > object->handle)
+               if (handle > object->object)
                        node = node->rb_right;
                else
                        return object;
@@ -260,26 +259,17 @@ nvkm_client_fini(struct nvkm_client *client, bool suspend)
 {
        struct nvkm_object *object = &client->object;
        const char *name[2] = { "fini", "suspend" };
-       int ret, i;
-       nvif_trace(object, "%s running\n", name[suspend]);
-       nvif_trace(object, "%s notify\n", name[suspend]);
+       int i;
+       nvif_debug(object, "%s notify\n", name[suspend]);
        for (i = 0; i < ARRAY_SIZE(client->notify); i++)
                nvkm_client_notify_put(client, i);
-       nvif_trace(object, "%s object\n", name[suspend]);
-       ret = nvkm_handle_fini(client->root, suspend);
-       nvif_trace(object, "%s completed with %d\n", name[suspend], ret);
-       return ret;
+       return nvkm_object_fini(&client->object, suspend);
 }
 
 int
 nvkm_client_init(struct nvkm_client *client)
 {
-       struct nvkm_object *object = &client->object;
-       int ret;
-       nvif_trace(object, "init running\n");
-       ret = nvkm_handle_init(client->root);
-       nvif_trace(object, "init completed with %d\n", ret);
-       return ret;
+       return nvkm_object_init(&client->object);
 }
 
 void
@@ -291,7 +281,7 @@ nvkm_client_del(struct nvkm_client **pclient)
                nvkm_client_fini(client, false);
                for (i = 0; i < ARRAY_SIZE(client->notify); i++)
                        nvkm_client_notify_del(client, i);
-               nvkm_handle_destroy(client->root);
+               nvkm_object_dtor(&client->object);
                kfree(*pclient);
                *pclient = NULL;
        }
@@ -303,7 +293,6 @@ nvkm_client_new(const char *name, u64 device, const char *cfg,
 {
        struct nvkm_oclass oclass = {};
        struct nvkm_client *client;
-       int ret;
 
        if (!(client = *pclient = kzalloc(sizeof(*client), GFP_KERNEL)))
                return -ENOMEM;
@@ -315,9 +304,5 @@ nvkm_client_new(const char *name, u64 device, const char *cfg,
        client->debug = nvkm_dbgopt(dbg, "CLIENT");
        client->objroot = RB_ROOT;
        client->dmaroot = RB_ROOT;
-
-       ret = nvkm_handle_create(NULL, ~0, &client->object, &client->root);
-       if (ret)
-               nvkm_client_del(pclient);
-       return ret;
+       return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/handle.c b/drivers/gpu/drm/nouveau/nvkm/core/handle.c
deleted file mode 100644 (file)
index d185cae..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include <core/handle.h>
-#include <core/client.h>
-
-#define hprintk(h,l,f,a...) do {                                               \
-       struct nvkm_handle *p = (h)->parent; u32 n = p ? p->name : ~0;         \
-       nvif_printk((h)->object, l, INFO, "0x%08x:0x%08x "f, n, (h)->name, ##a);\
-} while(0)
-
-int
-nvkm_handle_init(struct nvkm_handle *handle)
-{
-       struct nvkm_handle *item;
-       int ret;
-
-       hprintk(handle, TRACE, "init running\n");
-       ret = nvkm_object_inc(handle->object);
-       if (ret)
-               return ret;
-
-       hprintk(handle, TRACE, "init children\n");
-       list_for_each_entry(item, &handle->tree, head) {
-               ret = nvkm_handle_init(item);
-               if (ret)
-                       goto fail;
-       }
-
-       hprintk(handle, TRACE, "init completed\n");
-       return 0;
-fail:
-       hprintk(handle, ERROR, "init failed with %d\n", ret);
-       list_for_each_entry_continue_reverse(item, &handle->tree, head) {
-               nvkm_handle_fini(item, false);
-       }
-
-       nvkm_object_dec(handle->object, false);
-       return ret;
-}
-
-int
-nvkm_handle_fini(struct nvkm_handle *handle, bool suspend)
-{
-       static char *name[2] = { "fini", "suspend" };
-       struct nvkm_handle *item;
-       int ret;
-
-       hprintk(handle, TRACE, "%s children\n", name[suspend]);
-       list_for_each_entry(item, &handle->tree, head) {
-               ret = nvkm_handle_fini(item, suspend);
-               if (ret && suspend)
-                       goto fail;
-       }
-
-       hprintk(handle, TRACE, "%s running\n", name[suspend]);
-       if (handle->object) {
-               ret = nvkm_object_dec(handle->object, suspend);
-               if (ret && suspend)
-                       goto fail;
-       }
-
-       hprintk(handle, TRACE, "%s completed\n", name[suspend]);
-       return 0;
-fail:
-       hprintk(handle, ERROR, "%s failed with %d\n", name[suspend], ret);
-       list_for_each_entry_continue_reverse(item, &handle->tree, head) {
-               int rret = nvkm_handle_init(item);
-               if (rret)
-                       hprintk(handle, FATAL, "failed to restart, %d\n", rret);
-       }
-
-       return ret;
-}
-
-int
-nvkm_handle_create(struct nvkm_handle *parent, u32 _handle,
-                  struct nvkm_object *object, struct nvkm_handle **phandle)
-{
-       struct nvkm_handle *handle;
-
-       handle = kzalloc(sizeof(*handle), GFP_KERNEL);
-       if (!handle)
-               return -ENOMEM;
-
-       INIT_LIST_HEAD(&handle->head);
-       INIT_LIST_HEAD(&handle->tree);
-       handle->name = _handle;
-       handle->priv = ~0;
-       RB_CLEAR_NODE(&handle->rb);
-       handle->parent = parent;
-       nvkm_object_ref(object, &handle->object);
-
-       if (parent)
-               list_add(&handle->head, &handle->parent->tree);
-
-       hprintk(handle, TRACE, "created\n");
-       *phandle = handle;
-       return 0;
-}
-
-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);
-
-       hprintk(handle, TRACE, "destroy completed\n");
-       nvkm_object_ref(NULL, &handle->object);
-       kfree(handle);
-}
index d9bb039..d87d6ab 100644 (file)
 #include <core/ioctl.h>
 #include <core/client.h>
 #include <core/engine.h>
-#include <core/handle.h>
 
 #include <nvif/unpack.h>
 #include <nvif/ioctl.h>
 
 static int
-nvkm_ioctl_nop(struct nvkm_handle *handle, void *data, u32 size)
+nvkm_ioctl_nop(struct nvkm_object *object, void *data, u32 size)
 {
-       struct nvkm_object *object = handle->object;
        union {
                struct nvif_ioctl_nop_v0 v0;
        } *args = data;
@@ -48,9 +46,8 @@ nvkm_ioctl_nop(struct nvkm_handle *handle, void *data, u32 size)
 }
 
 static int
-nvkm_ioctl_sclass(struct nvkm_handle *handle, void *data, u32 size)
+nvkm_ioctl_sclass(struct nvkm_object *object, void *data, u32 size)
 {
-       struct nvkm_object *object = handle->object;
        union {
                struct nvif_ioctl_sclass_v0 v0;
        } *args = data;
@@ -81,13 +78,12 @@ nvkm_ioctl_sclass(struct nvkm_handle *handle, void *data, u32 size)
 }
 
 static int
-nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size)
+nvkm_ioctl_new(struct nvkm_object *parent, void *data, u32 size)
 {
        union {
                struct nvif_ioctl_new_v0 v0;
        } *args = data;
-       struct nvkm_client *client = handle->object->client;
-       struct nvkm_object *parent = handle->object;
+       struct nvkm_client *client = parent->client;
        struct nvkm_object *object = NULL;
        struct nvkm_oclass oclass;
        int ret, i = 0;
@@ -124,38 +120,30 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size)
        }
 
        ret = oclass.ctor(&oclass, data, size, &object);
-       if (ret)
-               goto fail_object;
-
-       ret = nvkm_object_inc(object);
-       if (ret)
-               goto fail_object;
-
-       ret = nvkm_handle_create(handle, args->v0.handle, object, &handle);
-       if (ret)
-               goto fail_handle;
-
-       ret = nvkm_handle_init(handle);
-       handle->route = args->v0.route;
-       handle->token = args->v0.token;
-       if (ret)
-               nvkm_handle_destroy(handle);
-
-       handle->handle = args->v0.object;
-       nvkm_client_insert(client, handle);
-       client->data = object;
-fail_handle:
-       nvkm_object_dec(object, false);
-fail_object:
-       nvkm_object_ref(NULL, &object);
        nvkm_engine_unref(&oclass.engine);
+       if (ret == 0) {
+               ret = nvkm_object_init(object);
+               if (ret == 0) {
+                       list_add(&object->head, &parent->tree);
+                       object->route = args->v0.route;
+                       object->token = args->v0.token;
+                       object->object = args->v0.object;
+                       if (nvkm_client_insert(client, object)) {
+                               client->data = object;
+                               return 0;
+                       }
+                       ret = -EEXIST;
+               }
+               nvkm_object_fini(object, false);
+       }
+
+       nvkm_object_del(&object);
        return ret;
 }
 
 static int
-nvkm_ioctl_del(struct nvkm_handle *handle, void *data, u32 size)
+nvkm_ioctl_del(struct nvkm_object *object, void *data, u32 size)
 {
-       struct nvkm_object *object = handle->object;
        union {
                struct nvif_ioctl_del none;
        } *args = data;
@@ -164,17 +152,16 @@ nvkm_ioctl_del(struct nvkm_handle *handle, void *data, u32 size)
        nvif_ioctl(object, "delete size %d\n", size);
        if (nvif_unvers(args->none)) {
                nvif_ioctl(object, "delete\n");
-               nvkm_handle_fini(handle, false);
-               nvkm_handle_destroy(handle);
+               nvkm_object_fini(object, false);
+               nvkm_object_del(&object);
        }
 
        return ret;
 }
 
 static int
-nvkm_ioctl_mthd(struct nvkm_handle *handle, void *data, u32 size)
+nvkm_ioctl_mthd(struct nvkm_object *object, void *data, u32 size)
 {
-       struct nvkm_object *object = handle->object;
        union {
                struct nvif_ioctl_mthd_v0 v0;
        } *args = data;
@@ -192,9 +179,8 @@ nvkm_ioctl_mthd(struct nvkm_handle *handle, void *data, u32 size)
 
 
 static int
-nvkm_ioctl_rd(struct nvkm_handle *handle, void *data, u32 size)
+nvkm_ioctl_rd(struct nvkm_object *object, void *data, u32 size)
 {
-       struct nvkm_object *object = handle->object;
        union {
                struct nvif_ioctl_rd_v0 v0;
        } *args = data;
@@ -232,9 +218,8 @@ nvkm_ioctl_rd(struct nvkm_handle *handle, void *data, u32 size)
 }
 
 static int
-nvkm_ioctl_wr(struct nvkm_handle *handle, void *data, u32 size)
+nvkm_ioctl_wr(struct nvkm_object *object, void *data, u32 size)
 {
-       struct nvkm_object *object = handle->object;
        union {
                struct nvif_ioctl_wr_v0 v0;
        } *args = data;
@@ -261,9 +246,8 @@ nvkm_ioctl_wr(struct nvkm_handle *handle, void *data, u32 size)
 }
 
 static int
-nvkm_ioctl_map(struct nvkm_handle *handle, void *data, u32 size)
+nvkm_ioctl_map(struct nvkm_object *object, void *data, u32 size)
 {
-       struct nvkm_object *object = handle->object;
        union {
                struct nvif_ioctl_map_v0 v0;
        } *args = data;
@@ -280,9 +264,8 @@ nvkm_ioctl_map(struct nvkm_handle *handle, void *data, u32 size)
 }
 
 static int
-nvkm_ioctl_unmap(struct nvkm_handle *handle, void *data, u32 size)
+nvkm_ioctl_unmap(struct nvkm_object *object, void *data, u32 size)
 {
-       struct nvkm_object *object = handle->object;
        union {
                struct nvif_ioctl_unmap none;
        } *args = data;
@@ -297,9 +280,8 @@ nvkm_ioctl_unmap(struct nvkm_handle *handle, void *data, u32 size)
 }
 
 static int
-nvkm_ioctl_ntfy_new(struct nvkm_handle *handle, void *data, u32 size)
+nvkm_ioctl_ntfy_new(struct nvkm_object *object, void *data, u32 size)
 {
-       struct nvkm_object *object = handle->object;
        union {
                struct nvif_ioctl_ntfy_new_v0 v0;
        } *args = data;
@@ -324,10 +306,9 @@ nvkm_ioctl_ntfy_new(struct nvkm_handle *handle, void *data, u32 size)
 }
 
 static int
-nvkm_ioctl_ntfy_del(struct nvkm_handle *handle, void *data, u32 size)
+nvkm_ioctl_ntfy_del(struct nvkm_object *object, void *data, u32 size)
 {
-       struct nvkm_client *client = nvkm_client(handle->object);
-       struct nvkm_object *object = handle->object;
+       struct nvkm_client *client = object->client;
        union {
                struct nvif_ioctl_ntfy_del_v0 v0;
        } *args = data;
@@ -344,10 +325,9 @@ nvkm_ioctl_ntfy_del(struct nvkm_handle *handle, void *data, u32 size)
 }
 
 static int
-nvkm_ioctl_ntfy_get(struct nvkm_handle *handle, void *data, u32 size)
+nvkm_ioctl_ntfy_get(struct nvkm_object *object, void *data, u32 size)
 {
-       struct nvkm_client *client = nvkm_client(handle->object);
-       struct nvkm_object *object = handle->object;
+       struct nvkm_client *client = object->client;
        union {
                struct nvif_ioctl_ntfy_get_v0 v0;
        } *args = data;
@@ -364,10 +344,9 @@ nvkm_ioctl_ntfy_get(struct nvkm_handle *handle, void *data, u32 size)
 }
 
 static int
-nvkm_ioctl_ntfy_put(struct nvkm_handle *handle, void *data, u32 size)
+nvkm_ioctl_ntfy_put(struct nvkm_object *object, void *data, u32 size)
 {
-       struct nvkm_client *client = nvkm_client(handle->object);
-       struct nvkm_object *object = handle->object;
+       struct nvkm_client *client = object->client;
        union {
                struct nvif_ioctl_ntfy_put_v0 v0;
        } *args = data;
@@ -385,7 +364,7 @@ nvkm_ioctl_ntfy_put(struct nvkm_handle *handle, void *data, u32 size)
 
 static struct {
        int version;
-       int (*func)(struct nvkm_handle *, void *, u32);
+       int (*func)(struct nvkm_object *, void *, u32);
 }
 nvkm_ioctl_v0[] = {
        { 0x00, nvkm_ioctl_nop },
@@ -407,13 +386,13 @@ static int
 nvkm_ioctl_path(struct nvkm_client *client, u64 handle, u32 type,
                void *data, u32 size, u8 owner, u8 *route, u64 *token)
 {
-       struct nvkm_handle *object;
+       struct nvkm_object *object;
        int ret;
 
        if (handle)
                object = nvkm_client_search(client, handle);
        else
-               object = client->root;
+               object = &client->object;
        if (unlikely(!object)) {
                nvif_ioctl(&client->object, "object not found\n");
                return -ENOENT;
index 8976526..67aa722 100644 (file)
@@ -22,6 +22,7 @@
  * Authors: Ben Skeggs
  */
 #include <core/object.h>
+#include <core/client.h>
 #include <core/engine.h>
 
 int
@@ -109,28 +110,112 @@ nvkm_object_bind(struct nvkm_object *object, struct nvkm_gpuobj *gpuobj,
 int
 nvkm_object_fini(struct nvkm_object *object, bool suspend)
 {
-       if (object->func->fini)
-               return object->func->fini(object, suspend);
+       const char *action = suspend ? "suspend" : "fini";
+       struct nvkm_object *child;
+       s64 time;
+       int ret;
+
+       nvif_debug(object, "%s children...\n", action);
+       time = ktime_to_us(ktime_get());
+       list_for_each_entry(child, &object->tree, head) {
+               ret = nvkm_object_fini(child, suspend);
+               if (ret && suspend)
+                       goto fail_child;
+       }
+
+       nvif_debug(object, "%s running...\n", action);
+       if (object->func->fini) {
+               ret = object->func->fini(object, suspend);
+               if (ret) {
+                       nvif_error(object, "%s failed with %d\n", action, ret);
+                       if (suspend)
+                               goto fail;
+               }
+       }
+
+       time = ktime_to_us(ktime_get()) - time;
+       nvif_debug(object, "%s completed in %lldus\n", action, time);
        return 0;
+
+fail:
+       if (object->func->init) {
+               int rret = object->func->init(object);
+               if (rret)
+                       nvif_fatal(object, "failed to restart, %d\n", rret);
+       }
+fail_child:
+       list_for_each_entry_continue_reverse(child, &object->tree, head) {
+               nvkm_object_init(child);
+       }
+       return ret;
 }
 
 int
 nvkm_object_init(struct nvkm_object *object)
 {
-       if (object->func->init)
-               return object->func->init(object);
+       struct nvkm_object *child;
+       s64 time;
+       int ret;
+
+       nvif_debug(object, "init running...\n");
+       time = ktime_to_us(ktime_get());
+       if (object->func->init) {
+               ret = object->func->init(object);
+               if (ret)
+                       goto fail;
+       }
+
+       nvif_debug(object, "init children...\n");
+       list_for_each_entry(child, &object->tree, head) {
+               ret = nvkm_object_init(child);
+               if (ret)
+                       goto fail_child;
+       }
+
+       time = ktime_to_us(ktime_get()) - time;
+       nvif_debug(object, "init completed in %lldus\n", time);
        return 0;
+
+fail_child:
+       list_for_each_entry_continue_reverse(child, &object->tree, head)
+               nvkm_object_fini(child, false);
+fail:
+       nvif_error(object, "init failed with %d\n", ret);
+       if (object->func->fini)
+               object->func->fini(object, false);
+       return ret;
 }
 
-static void
+void *
+nvkm_object_dtor(struct nvkm_object *object)
+{
+       struct nvkm_object *child, *ctemp;
+       void *data = object;
+       s64 time;
+
+       nvif_debug(object, "destroy children...\n");
+       time = ktime_to_us(ktime_get());
+       list_for_each_entry_safe(child, ctemp, &object->tree, head) {
+               nvkm_object_del(&child);
+       }
+
+       nvif_debug(object, "destroy running...\n");
+       if (object->func->dtor)
+               data = object->func->dtor(object);
+       nvkm_engine_unref(&object->engine);
+       time = ktime_to_us(ktime_get()) - time;
+       nvif_debug(object, "destroy completed in %lldus...\n", time);
+       return data;
+}
+
+void
 nvkm_object_del(struct nvkm_object **pobject)
 {
        struct nvkm_object *object = *pobject;
-
        if (object && !WARN_ON(!object->func)) {
-               if (object->func->dtor)
-                       *pobject = object->func->dtor(object);
-               nvkm_engine_unref(&object->engine);
+               *pobject = nvkm_object_dtor(object);
+               nvkm_client_remove(object->client, object);
+               list_del(&object->head);
                kfree(*pobject);
                *pobject = NULL;
        }
@@ -145,9 +230,10 @@ nvkm_object_ctor(const struct nvkm_object_func *func,
        object->engine = nvkm_engine_ref(oclass->engine);
        object->oclass = oclass->base.oclass;
        object->handle = oclass->handle;
-       object->parent = oclass->parent;
-       atomic_set(&object->refcount, 1);
-       atomic_set(&object->usecount, 0);
+       INIT_LIST_HEAD(&object->head);
+       INIT_LIST_HEAD(&object->tree);
+       RB_CLEAR_NODE(&object->node);
+       WARN_ON(oclass->engine && !object->engine);
 }
 
 int
@@ -176,106 +262,3 @@ nvkm_object_new(const struct nvkm_oclass *oclass, void *data, u32 size,
                oclass->base.func ? oclass->base.func : &nvkm_object_func;
        return nvkm_object_new_(func, oclass, data, size, pobject);
 }
-
-void
-nvkm_object_ref(struct nvkm_object *obj, struct nvkm_object **ref)
-{
-       if (obj) {
-               atomic_inc(&obj->refcount);
-       }
-
-       if (*ref) {
-               int dead = atomic_dec_and_test(&(*ref)->refcount);
-               if (dead)
-                       nvkm_object_del(ref);
-       }
-
-       *ref = obj;
-}
-
-int
-nvkm_object_inc(struct nvkm_object *object)
-{
-       int ref = atomic_add_return(1, &object->usecount);
-       int ret;
-
-       if (ref != 1)
-               return 0;
-
-       if (object->parent) {
-               ret = nvkm_object_inc(object->parent);
-               if (ret)
-                       goto fail_parent;
-       }
-
-       ret = nvkm_object_init(object);
-       atomic_set(&object->usecount, 1);
-       if (ret)
-               goto fail_self;
-
-       return 0;
-
-fail_self:
-       if (object->parent)
-                nvkm_object_dec(object->parent, false);
-fail_parent:
-       atomic_dec(&object->usecount);
-       return ret;
-}
-
-static int
-nvkm_object_decf(struct nvkm_object *object)
-{
-       nvkm_object_fini(object, false);
-       atomic_set(&object->usecount, 0);
-
-       if (object->parent)
-               nvkm_object_dec(object->parent, false);
-
-       return 0;
-}
-
-static int
-nvkm_object_decs(struct nvkm_object *object)
-{
-       int ret;
-
-       ret = nvkm_object_fini(object, true);
-       atomic_set(&object->usecount, 0);
-       if (ret)
-               return ret;
-
-       if (object->parent) {
-               ret = nvkm_object_dec(object->parent, true);
-               if (ret)
-                       goto fail_parent;
-       }
-
-       return 0;
-
-fail_parent:
-       nvkm_object_init(object);
-
-       return ret;
-}
-
-int
-nvkm_object_dec(struct nvkm_object *object, bool suspend)
-{
-       int ref = atomic_add_return(-1, &object->usecount);
-       int ret;
-
-       if (ref == 0) {
-               if (suspend)
-                       ret = nvkm_object_decs(object);
-               else
-                       ret = nvkm_object_decf(object);
-
-               if (ret) {
-                       atomic_inc(&object->usecount);
-                       return ret;
-               }
-       }
-
-       return 0;
-}
index f32aa0d..e31a047 100644 (file)
@@ -109,9 +109,11 @@ nvkm_oproxy_fini(struct nvkm_object *object, bool suspend)
                        return ret;
        }
 
-       ret = nvkm_object_fini(oproxy->object, suspend);
-       if (ret && suspend)
-               return ret;
+       if (oproxy->object->func->fini) {
+               ret = oproxy->object->func->fini(oproxy->object, suspend);
+               if (ret && suspend)
+                       return ret;
+       }
 
        if (oproxy->func->fini[1]) {
                ret = oproxy->func->fini[1](oproxy, suspend);
@@ -134,9 +136,11 @@ nvkm_oproxy_init(struct nvkm_object *object)
                        return ret;
        }
 
-       ret = nvkm_object_init(oproxy->object);
-       if (ret)
-               return ret;
+       if (oproxy->object->func->init) {
+               ret = oproxy->object->func->init(oproxy->object);
+               if (ret)
+                       return ret;
+       }
 
        if (oproxy->func->init[1]) {
                ret = oproxy->func->init[1](oproxy);
@@ -153,7 +157,7 @@ nvkm_oproxy_dtor(struct nvkm_object *object)
        struct nvkm_oproxy *oproxy = nvkm_oproxy(object);
        if (oproxy->func->dtor[0])
                oproxy->func->dtor[0](oproxy);
-       nvkm_object_ref(NULL, &oproxy->object);
+       nvkm_object_del(&oproxy->object);
        if (oproxy->func->dtor[1])
                oproxy->func->dtor[1](oproxy);
        return oproxy;
index b05c04a..9c6645a 100644 (file)
@@ -25,7 +25,6 @@
 #include "rootnv50.h"
 
 #include <core/client.h>
-#include <core/handle.h>
 #include <core/oproxy.h>
 #include <core/ramht.h>
 #include <subdev/fb.h>
index a56e56e..9921482 100644 (file)
@@ -116,7 +116,7 @@ nvkm_fifo_chan_child_del(struct nvkm_oproxy *base)
        if (!--engn->refcount) {
                if (chan->func->engine_dtor)
                        chan->func->engine_dtor(chan, engine);
-               nvkm_object_ref(NULL, &engn->object);
+               nvkm_object_del(&engn->object);
                if (chan->vm)
                        atomic_dec(&chan->vm->engref[engine->subdev.index]);
        }
index 172f243..ff6fcbd 100644 (file)
@@ -27,7 +27,6 @@
 #include <core/client.h>
 #include <core/enum.h>
 #include <core/gpuobj.h>
-#include <core/handle.h>
 #include <subdev/bar.h>
 #include <engine/sw.h>
 
index fc0ff2d..98970a0 100644 (file)
@@ -27,7 +27,6 @@
 #include <core/client.h>
 #include <core/enum.h>
 #include <core/gpuobj.h>
-#include <core/handle.h>
 #include <subdev/bar.h>
 #include <engine/sw.h>
 
index e6f04e8..ad707ff 100644 (file)
@@ -26,7 +26,6 @@
 #include "regsnv04.h"
 
 #include <core/client.h>
-#include <core/handle.h>
 #include <core/ramht.h>
 #include <subdev/instmem.h>
 #include <subdev/timer.h>
index ef36ba1..a381196 100644 (file)
@@ -24,7 +24,6 @@
 #include "nv50.h"
 
 #include <core/gpuobj.h>
-#include <core/handle.h>
 #include <engine/disp.h>
 #include <engine/fifo/chan.h>
 #include <subdev/bar.h>