[Intel-gfx] [PATCH 1/4] drm: Introduce drm_modeset_lock_ctx_retry()
Ville Syrjala
ville.syrjala at linux.intel.com
Thu Jul 15 18:49:51 UTC 2021
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
Quite a few places are hand rolling the modeset lock backoff dance.
Let's suck that into a helper macro that is easier to use without
forgetting some steps.
The main downside is probably that the implementation of
drm_with_modeset_lock_ctx() is a bit harder to read than a hand
rolled version on account of being split across three functions,
but the actual code using it ends up being much simpler.
Cc: Sean Paul <seanpaul at chromium.org>
Cc: Daniel Vetter <daniel at ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
drivers/gpu/drm/drm_modeset_lock.c | 44 ++++++++++++++++++++++++++++++
include/drm/drm_modeset_lock.h | 20 ++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c
index fcfe1a03c4a1..083df96632e8 100644
--- a/drivers/gpu/drm/drm_modeset_lock.c
+++ b/drivers/gpu/drm/drm_modeset_lock.c
@@ -425,3 +425,47 @@ int drm_modeset_lock_all_ctx(struct drm_device *dev,
return 0;
}
EXPORT_SYMBOL(drm_modeset_lock_all_ctx);
+
+void _drm_modeset_lock_begin(struct drm_modeset_acquire_ctx *ctx,
+ struct drm_atomic_state *state,
+ unsigned int flags, int *ret)
+{
+ drm_modeset_acquire_init(ctx, flags);
+
+ if (state)
+ state->acquire_ctx = ctx;
+
+ *ret = -EDEADLK;
+}
+EXPORT_SYMBOL(_drm_modeset_lock_begin);
+
+bool _drm_modeset_lock_loop(int *ret)
+{
+ if (*ret == -EDEADLK) {
+ *ret = 0;
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL(_drm_modeset_lock_loop);
+
+void _drm_modeset_lock_end(struct drm_modeset_acquire_ctx *ctx,
+ struct drm_atomic_state *state,
+ int *ret)
+{
+ if (*ret == -EDEADLK) {
+ if (state)
+ drm_atomic_state_clear(state);
+
+ *ret = drm_modeset_backoff(ctx);
+ if (*ret == 0) {
+ *ret = -EDEADLK;
+ return;
+ }
+ }
+
+ drm_modeset_drop_locks(ctx);
+ drm_modeset_acquire_fini(ctx);
+}
+EXPORT_SYMBOL(_drm_modeset_lock_end);
diff --git a/include/drm/drm_modeset_lock.h b/include/drm/drm_modeset_lock.h
index aafd07388eb7..5eaad2533de5 100644
--- a/include/drm/drm_modeset_lock.h
+++ b/include/drm/drm_modeset_lock.h
@@ -26,6 +26,7 @@
#include <linux/ww_mutex.h>
+struct drm_atomic_state;
struct drm_modeset_lock;
/**
@@ -203,4 +204,23 @@ modeset_lock_fail: \
if (!drm_drv_uses_atomic_modeset(dev)) \
mutex_unlock(&dev->mode_config.mutex);
+void _drm_modeset_lock_begin(struct drm_modeset_acquire_ctx *ctx,
+ struct drm_atomic_state *state,
+ unsigned int flags,
+ int *ret);
+bool _drm_modeset_lock_loop(int *ret);
+void _drm_modeset_lock_end(struct drm_modeset_acquire_ctx *ctx,
+ struct drm_atomic_state *state,
+ int *ret);
+
+/*
+ * Note that one must always use "continue" rather than
+ * "break" or "return" to handle errors within the
+ * drm_modeset_lock_ctx_retry() block.
+ */
+#define drm_modeset_lock_ctx_retry(ctx, state, flags, ret) \
+ for (_drm_modeset_lock_begin((ctx), (state), (flags), &(ret)); \
+ _drm_modeset_lock_loop(&(ret)); \
+ _drm_modeset_lock_end((ctx), (state), &(ret)))
+
#endif /* DRM_MODESET_LOCK_H_ */
--
2.31.1
More information about the Intel-gfx
mailing list