diff options
author | Dave Airlie <airlied@redhat.com> | 2021-11-05 06:50:09 +0300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2021-11-05 06:50:15 +0300 |
commit | 5275a99e35e5a1d1f68038b0560d0e7eaf624e86 (patch) | |
tree | 36109ac35e451d3b710a85ab57b3e8be01730bea /drivers/gpu/drm/drm_modeset_lock.c | |
parent | d9bd054177fbd2c4762546aec40fc3071bfe4cc0 (diff) | |
parent | b3ec8cdf457e5e63d396fe1346cc788cf7c1b578 (diff) | |
download | linux-5275a99e35e5a1d1f68038b0560d0e7eaf624e86.tar.xz |
Merge tag 'drm-misc-next-2021-10-14' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.16:
UAPI Changes:
Cross-subsystem Changes:
Core Changes:
- fbdev: Fix double-free, Remove unused scrolling acceleration
- locking: improve logging for contented locks without backoff
- dma-buf: Add dma_resv_for_each_fence iterator, and conversion of
users
Driver Changes:
- nouveau: Various code style improvements
- bridge: HPD improvements for lt9611uxc, eDP aux-bus support for
ps8640, lvds-codec data-mapping selection support
- panels: Vivax TPC-9150, Innolux G070Y2-T02, LOGIC Technologies
LTTD800480070-L2RT, Sharp LS060T1SX01,
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20211014120452.2wicnt6hobu3kbwb@gilmour
Diffstat (limited to 'drivers/gpu/drm/drm_modeset_lock.c')
-rw-r--r-- | drivers/gpu/drm/drm_modeset_lock.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index bf8a6e823a15..4d32b61fa1fd 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -25,6 +25,7 @@ #include <drm/drm_crtc.h> #include <drm/drm_device.h> #include <drm/drm_modeset_lock.h> +#include <drm/drm_print.h> /** * DOC: kms locking @@ -77,6 +78,45 @@ static DEFINE_WW_CLASS(crtc_ww_class); +#if IS_ENABLED(CONFIG_DRM_DEBUG_MODESET_LOCK) +static noinline depot_stack_handle_t __stack_depot_save(void) +{ + unsigned long entries[8]; + unsigned int n; + + n = stack_trace_save(entries, ARRAY_SIZE(entries), 1); + + return stack_depot_save(entries, n, GFP_NOWAIT | __GFP_NOWARN); +} + +static void __stack_depot_print(depot_stack_handle_t stack_depot) +{ + struct drm_printer p = drm_debug_printer("drm_modeset_lock"); + unsigned long *entries; + unsigned int nr_entries; + char *buf; + + buf = kmalloc(PAGE_SIZE, GFP_NOWAIT | __GFP_NOWARN); + if (!buf) + return; + + nr_entries = stack_depot_fetch(stack_depot, &entries); + stack_trace_snprint(buf, PAGE_SIZE, entries, nr_entries, 2); + + drm_printf(&p, "attempting to lock a contended lock without backoff:\n%s", buf); + + kfree(buf); +} +#else /* CONFIG_DRM_DEBUG_MODESET_LOCK */ +static depot_stack_handle_t __stack_depot_save(void) +{ + return 0; +} +static void __stack_depot_print(depot_stack_handle_t stack_depot) +{ +} +#endif /* CONFIG_DRM_DEBUG_MODESET_LOCK */ + /** * drm_modeset_lock_all - take all modeset locks * @dev: DRM device @@ -225,7 +265,9 @@ EXPORT_SYMBOL(drm_modeset_acquire_fini); */ void drm_modeset_drop_locks(struct drm_modeset_acquire_ctx *ctx) { - WARN_ON(ctx->contended); + if (WARN_ON(ctx->contended)) + __stack_depot_print(ctx->stack_depot); + while (!list_empty(&ctx->locked)) { struct drm_modeset_lock *lock; @@ -243,7 +285,8 @@ static inline int modeset_lock(struct drm_modeset_lock *lock, { int ret; - WARN_ON(ctx->contended); + if (WARN_ON(ctx->contended)) + __stack_depot_print(ctx->stack_depot); if (ctx->trylock_only) { lockdep_assert_held(&ctx->ww_ctx); @@ -274,6 +317,7 @@ static inline int modeset_lock(struct drm_modeset_lock *lock, ret = 0; } else if (ret == -EDEADLK) { ctx->contended = lock; + ctx->stack_depot = __stack_depot_save(); } return ret; @@ -296,6 +340,7 @@ int drm_modeset_backoff(struct drm_modeset_acquire_ctx *ctx) struct drm_modeset_lock *contended = ctx->contended; ctx->contended = NULL; + ctx->stack_depot = 0; if (WARN_ON(!contended)) return 0; |