drm/i915: Wrap i915_active in a simple kreffed struct
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 27 Mar 2020 11:22:11 +0000 (11:22 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Mon, 30 Mar 2020 17:20:34 +0000 (18:20 +0100)
For conveniences of callers that just want to use an i915_active to
track a wide array of concurrent timelines, wrap the base i915_active
struct inside a kref. This i915_active will self-destruct after use.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200327112212.16046-2-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_active.c
drivers/gpu/drm/i915/i915_active.h

index 7b685032cc1e2c78e4ab78b32b4a48dd1352f26e..5df7704369fd372b3e71e928f8d5b9212c038250 100644 (file)
@@ -939,6 +939,59 @@ void i915_active_noop(struct dma_fence *fence, struct dma_fence_cb *cb)
        active_fence_cb(fence, cb);
 }
 
+struct auto_active {
+       struct i915_active base;
+       struct kref ref;
+};
+
+struct i915_active *i915_active_get(struct i915_active *ref)
+{
+       struct auto_active *aa = container_of(ref, typeof(*aa), base);
+
+       kref_get(&aa->ref);
+       return &aa->base;
+}
+
+static void auto_release(struct kref *ref)
+{
+       struct auto_active *aa = container_of(ref, typeof(*aa), ref);
+
+       i915_active_fini(&aa->base);
+       kfree(aa);
+}
+
+void i915_active_put(struct i915_active *ref)
+{
+       struct auto_active *aa = container_of(ref, typeof(*aa), base);
+
+       kref_put(&aa->ref, auto_release);
+}
+
+static int auto_active(struct i915_active *ref)
+{
+       i915_active_get(ref);
+       return 0;
+}
+
+static void auto_retire(struct i915_active *ref)
+{
+       i915_active_put(ref);
+}
+
+struct i915_active *i915_active_create(void)
+{
+       struct auto_active *aa;
+
+       aa = kmalloc(sizeof(*aa), GFP_KERNEL);
+       if (!aa)
+               return NULL;
+
+       kref_init(&aa->ref);
+       i915_active_init(&aa->base, auto_active, auto_retire);
+
+       return &aa->base;
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftests/i915_active.c"
 #endif
index 4f9aa7bab5147ccd8f5aa58bcbb85b001f4c55de..b526d310a585f856d6913f0e3e6cfcc372efaa41 100644 (file)
@@ -225,4 +225,8 @@ void i915_request_add_active_barriers(struct i915_request *rq);
 void i915_active_print(struct i915_active *ref, struct drm_printer *m);
 void i915_active_unlock_wait(struct i915_active *ref);
 
+struct i915_active *i915_active_create(void);
+struct i915_active *i915_active_get(struct i915_active *ref);
+void i915_active_put(struct i915_active *ref);
+
 #endif /* _I915_ACTIVE_H_ */