u64 timeline;
};
+static void
+__active_park(struct i915_active *ref)
+{
+ struct active_node *it, *n;
+
+ rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
+ GEM_BUG_ON(i915_gem_active_isset(&it->base));
+ kfree(it);
+ }
+ ref->tree = RB_ROOT;
+}
+
static void
__active_retire(struct i915_active *ref)
{
GEM_BUG_ON(!ref->count);
- if (!--ref->count)
- ref->retire(ref);
+ if (--ref->count)
+ return;
+
+ /* return the unused nodes to our slabcache */
+ __active_park(ref);
+
+ ref->retire(ref);
}
static void
return 0;
}
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
void i915_active_fini(struct i915_active *ref)
{
- struct active_node *it, *n;
-
GEM_BUG_ON(i915_gem_active_isset(&ref->last));
-
- rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
- GEM_BUG_ON(i915_gem_active_isset(&it->base));
- kfree(it);
- }
- ref->tree = RB_ROOT;
+ GEM_BUG_ON(!RB_EMPTY_ROOT(&ref->tree));
+ GEM_BUG_ON(ref->count);
}
+#endif
#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
#include "selftests/i915_active.c"
return !ref->count;
}
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
void i915_active_fini(struct i915_active *ref);
+#else
+static inline void i915_active_fini(struct i915_active *ref) { }
+#endif
#endif /* _I915_ACTIVE_H_ */