static DEFINE_SPINLOCK(i915_sw_fence_lock);
 
+enum {
+       DEBUG_FENCE_IDLE = 0,
+       DEBUG_FENCE_NOTIFY,
+};
+
+#ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
+
+static void *i915_sw_fence_debug_hint(void *addr)
+{
+       return (void *)(((struct i915_sw_fence *)addr)->flags & I915_SW_FENCE_MASK);
+}
+
+static struct debug_obj_descr i915_sw_fence_debug_descr = {
+       .name = "i915_sw_fence",
+       .debug_hint = i915_sw_fence_debug_hint,
+};
+
+static inline void debug_fence_init(struct i915_sw_fence *fence)
+{
+       debug_object_init(fence, &i915_sw_fence_debug_descr);
+}
+
+static inline void debug_fence_activate(struct i915_sw_fence *fence)
+{
+       debug_object_activate(fence, &i915_sw_fence_debug_descr);
+}
+
+static inline void debug_fence_set_state(struct i915_sw_fence *fence,
+                                        int old, int new)
+{
+       debug_object_active_state(fence, &i915_sw_fence_debug_descr, old, new);
+}
+
+static inline void debug_fence_deactivate(struct i915_sw_fence *fence)
+{
+       debug_object_deactivate(fence, &i915_sw_fence_debug_descr);
+}
+
+static inline void debug_fence_destroy(struct i915_sw_fence *fence)
+{
+       debug_object_destroy(fence, &i915_sw_fence_debug_descr);
+}
+
+static inline void debug_fence_free(struct i915_sw_fence *fence)
+{
+       debug_object_free(fence, &i915_sw_fence_debug_descr);
+}
+
+static inline void debug_fence_assert(struct i915_sw_fence *fence)
+{
+       debug_object_assert_init(fence, &i915_sw_fence_debug_descr);
+}
+
+#else
+
+static inline void debug_fence_init(struct i915_sw_fence *fence)
+{
+}
+
+static inline void debug_fence_activate(struct i915_sw_fence *fence)
+{
+}
+
+static inline void debug_fence_set_state(struct i915_sw_fence *fence,
+                                        int old, int new)
+{
+}
+
+static inline void debug_fence_deactivate(struct i915_sw_fence *fence)
+{
+}
+
+static inline void debug_fence_destroy(struct i915_sw_fence *fence)
+{
+}
+
+static inline void debug_fence_free(struct i915_sw_fence *fence)
+{
+}
+
+static inline void debug_fence_assert(struct i915_sw_fence *fence)
+{
+}
+
+#endif
+
 static int __i915_sw_fence_notify(struct i915_sw_fence *fence,
                                  enum i915_sw_fence_notify state)
 {
        return fn(fence, state);
 }
 
-static void i915_sw_fence_free(struct kref *kref)
+#ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
+void i915_sw_fence_fini(struct i915_sw_fence *fence)
+{
+       debug_fence_free(fence);
+}
+#endif
+
+static void i915_sw_fence_release(struct kref *kref)
 {
        struct i915_sw_fence *fence = container_of(kref, typeof(*fence), kref);
 
        WARN_ON(atomic_read(&fence->pending) > 0);
+       debug_fence_destroy(fence);
 
-       if (fence->flags & I915_SW_FENCE_MASK)
+       if (fence->flags & I915_SW_FENCE_MASK) {
                __i915_sw_fence_notify(fence, FENCE_FREE);
-       else
+       } else {
+               i915_sw_fence_fini(fence);
                kfree(fence);
+       }
 }
 
 static void i915_sw_fence_put(struct i915_sw_fence *fence)
 {
-       kref_put(&fence->kref, i915_sw_fence_free);
+       debug_fence_assert(fence);
+       kref_put(&fence->kref, i915_sw_fence_release);
 }
 
 static struct i915_sw_fence *i915_sw_fence_get(struct i915_sw_fence *fence)
 {
+       debug_fence_assert(fence);
        kref_get(&fence->kref);
        return fence;
 }
        wait_queue_t *pos, *next;
        unsigned long flags;
 
+       debug_fence_deactivate(fence);
        atomic_set_release(&fence->pending, -1); /* 0 -> -1 [done] */
 
        /*
                } while (1);
        }
        spin_unlock_irqrestore(&x->lock, flags);
+
+       debug_fence_assert(fence);
 }
 
 static void __i915_sw_fence_complete(struct i915_sw_fence *fence,
                                     struct list_head *continuation)
 {
+       debug_fence_assert(fence);
+
        if (!atomic_dec_and_test(&fence->pending))
                return;
 
+       debug_fence_set_state(fence, DEBUG_FENCE_IDLE, DEBUG_FENCE_NOTIFY);
+
        if (fence->flags & I915_SW_FENCE_MASK &&
            __i915_sw_fence_notify(fence, FENCE_COMPLETE) != NOTIFY_DONE)
                return;
 
+       debug_fence_set_state(fence, DEBUG_FENCE_NOTIFY, DEBUG_FENCE_IDLE);
+
        __i915_sw_fence_wake_up_all(fence, continuation);
 }
 
 static void i915_sw_fence_complete(struct i915_sw_fence *fence)
 {
+       debug_fence_assert(fence);
+
        if (WARN_ON(i915_sw_fence_done(fence)))
                return;
 
 
 static void i915_sw_fence_await(struct i915_sw_fence *fence)
 {
+       debug_fence_assert(fence);
        WARN_ON(atomic_inc_return(&fence->pending) <= 1);
 }
 
 {
        BUG_ON((unsigned long)fn & ~I915_SW_FENCE_MASK);
 
+       debug_fence_init(fence);
+
        __init_waitqueue_head(&fence->wait, name, key);
        kref_init(&fence->kref);
        atomic_set(&fence->pending, 1);
        fence->flags = (unsigned long)fn;
 }
 
-void i915_sw_fence_commit(struct i915_sw_fence *fence)
+static void __i915_sw_fence_commit(struct i915_sw_fence *fence)
 {
        i915_sw_fence_complete(fence);
        i915_sw_fence_put(fence);
 }
 
+void i915_sw_fence_commit(struct i915_sw_fence *fence)
+{
+       debug_fence_activate(fence);
+       __i915_sw_fence_commit(fence);
+}
+
 static int i915_sw_fence_wake(wait_queue_t *wq, unsigned mode, int flags, void *key)
 {
        list_del(&wq->task_list);
        unsigned long flags;
        int pending;
 
+       debug_fence_assert(fence);
+
        if (i915_sw_fence_done(signaler))
                return 0;
 
+       debug_fence_assert(signaler);
+
        /* The dependency graph must be acyclic. */
        if (unlikely(i915_sw_fence_check_if_after(fence, signaler)))
                return -EINVAL;
        dma_fence_put(cb->dma);
        cb->dma = NULL;
 
-       i915_sw_fence_commit(cb->fence);
+       __i915_sw_fence_commit(cb->fence);
        cb->timer.function = NULL;
 }
 
 
        del_timer_sync(&cb->timer);
        if (cb->timer.function)
-               i915_sw_fence_commit(cb->fence);
+               __i915_sw_fence_commit(cb->fence);
        dma_fence_put(cb->dma);
 
        kfree(cb);
        struct i915_sw_dma_fence_cb *cb;
        int ret;
 
+       debug_fence_assert(fence);
+
        if (dma_fence_is_signaled(dma))
                return 0;
 
        struct dma_fence *excl;
        int ret = 0, pending;
 
+       debug_fence_assert(fence);
+
        if (write) {
                struct dma_fence **shared;
                unsigned int count, i;