Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
forked fromtorvalds/linux

Commit73a8825

Browse files
committed
drm/vmwgfx: Fix a destoy-while-held mutex problem.
When validating legacy surfaces, the backup bo might be destroyed atsurface validate time. However, the kms resource validation code may havethe bo reserved, so we will destroy a locked mutex. While there shouldn'tbe any other users of that mutex when it is destroyed, it causes a lockleak and thus throws a lockdep error.Fix this by having the kms resource validation code hold a reference tothe bo while we have it reserved. We do this by introducing a validationcontext which might come in handy when the kms code is extended to validatemultiple resources or buffers.Cc: <stable@vger.kernel.org>Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>Reviewed-by: Brian Paul <brianp@vmware.com>Reviewed-by: Sinclair Yeh <syeh@vmware.com>
1 parent140bcaa commit73a8825

File tree

4 files changed

+34
-16
lines changed

4 files changed

+34
-16
lines changed

‎drivers/gpu/drm/vmwgfx/vmwgfx_kms.c‎

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#include<drm/drm_atomic_helper.h>
3232
#include<drm/drm_rect.h>
3333

34-
3534
/* Might need a hrtimer here? */
3635
#defineVMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)
3736

@@ -2517,9 +2516,12 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
25172516
* Helper to be used if an error forces the caller to undo the actions of
25182517
* vmw_kms_helper_resource_prepare.
25192518
*/
2520-
voidvmw_kms_helper_resource_revert(structvmw_resource*res)
2519+
voidvmw_kms_helper_resource_revert(structvmw_validation_ctx*ctx)
25212520
{
2522-
vmw_kms_helper_buffer_revert(res->backup);
2521+
structvmw_resource*res=ctx->res;
2522+
2523+
vmw_kms_helper_buffer_revert(ctx->buf);
2524+
vmw_dmabuf_unreference(&ctx->buf);
25232525
vmw_resource_unreserve(res, false,NULL,0);
25242526
mutex_unlock(&res->dev_priv->cmdbuf_mutex);
25252527
}
@@ -2536,10 +2538,14 @@ void vmw_kms_helper_resource_revert(struct vmw_resource *res)
25362538
* interrupted by a signal.
25372539
*/
25382540
intvmw_kms_helper_resource_prepare(structvmw_resource*res,
2539-
boolinterruptible)
2541+
boolinterruptible,
2542+
structvmw_validation_ctx*ctx)
25402543
{
25412544
intret=0;
25422545

2546+
ctx->buf=NULL;
2547+
ctx->res=res;
2548+
25432549
if (interruptible)
25442550
ret=mutex_lock_interruptible(&res->dev_priv->cmdbuf_mutex);
25452551
else
@@ -2558,14 +2564,16 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
25582564
res->dev_priv->has_mob);
25592565
if (ret)
25602566
gotoout_unreserve;
2567+
2568+
ctx->buf=vmw_dmabuf_reference(res->backup);
25612569
}
25622570
ret=vmw_resource_validate(res);
25632571
if (ret)
25642572
gotoout_revert;
25652573
return0;
25662574

25672575
out_revert:
2568-
vmw_kms_helper_buffer_revert(res->backup);
2576+
vmw_kms_helper_buffer_revert(ctx->buf);
25692577
out_unreserve:
25702578
vmw_resource_unreserve(res, false,NULL,0);
25712579
out_unlock:
@@ -2581,11 +2589,13 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
25812589
* @out_fence: Optional pointer to a fence pointer. If non-NULL, a
25822590
* ref-counted fence pointer is returned here.
25832591
*/
2584-
voidvmw_kms_helper_resource_finish(structvmw_resource*res,
2585-
structvmw_fence_obj**out_fence)
2592+
voidvmw_kms_helper_resource_finish(structvmw_validation_ctx*ctx,
2593+
structvmw_fence_obj**out_fence)
25862594
{
2587-
if (res->backup||out_fence)
2588-
vmw_kms_helper_buffer_finish(res->dev_priv,NULL,res->backup,
2595+
structvmw_resource*res=ctx->res;
2596+
2597+
if (ctx->buf||out_fence)
2598+
vmw_kms_helper_buffer_finish(res->dev_priv,NULL,ctx->buf,
25892599
out_fence,NULL);
25902600

25912601
vmw_resource_unreserve(res, false,NULL,0);

‎drivers/gpu/drm/vmwgfx/vmwgfx_kms.h‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,11 @@ struct vmw_display_unit {
240240
intset_gui_y;
241241
};
242242

243+
structvmw_validation_ctx {
244+
structvmw_resource*res;
245+
structvmw_dma_buffer*buf;
246+
};
247+
243248
#definevmw_crtc_to_du(x) \
244249
container_of(x, struct vmw_display_unit, crtc)
245250
#definevmw_connector_to_du(x) \
@@ -296,9 +301,10 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
296301
structdrm_vmw_fence_rep__user*
297302
user_fence_rep);
298303
intvmw_kms_helper_resource_prepare(structvmw_resource*res,
299-
boolinterruptible);
300-
voidvmw_kms_helper_resource_revert(structvmw_resource*res);
301-
voidvmw_kms_helper_resource_finish(structvmw_resource*res,
304+
boolinterruptible,
305+
structvmw_validation_ctx*ctx);
306+
voidvmw_kms_helper_resource_revert(structvmw_validation_ctx*ctx);
307+
voidvmw_kms_helper_resource_finish(structvmw_validation_ctx*ctx,
302308
structvmw_fence_obj**out_fence);
303309
intvmw_kms_readback(structvmw_private*dev_priv,
304310
structdrm_file*file_priv,

‎drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -909,12 +909,13 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
909909
structvmw_framebuffer_surface*vfbs=
910910
container_of(framebuffer,typeof(*vfbs),base);
911911
structvmw_kms_sou_surface_dirtysdirty;
912+
structvmw_validation_ctxctx;
912913
intret;
913914

914915
if (!srf)
915916
srf=&vfbs->surface->res;
916917

917-
ret=vmw_kms_helper_resource_prepare(srf, true);
918+
ret=vmw_kms_helper_resource_prepare(srf, true,&ctx);
918919
if (ret)
919920
returnret;
920921

@@ -933,7 +934,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
933934
ret=vmw_kms_helper_dirty(dev_priv,framebuffer,clips,vclips,
934935
dest_x,dest_y,num_clips,inc,
935936
&sdirty.base);
936-
vmw_kms_helper_resource_finish(srf,out_fence);
937+
vmw_kms_helper_resource_finish(&ctx,out_fence);
937938

938939
returnret;
939940
}

‎drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -980,12 +980,13 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
980980
structvmw_framebuffer_surface*vfbs=
981981
container_of(framebuffer,typeof(*vfbs),base);
982982
structvmw_stdu_dirtysdirty;
983+
structvmw_validation_ctxctx;
983984
intret;
984985

985986
if (!srf)
986987
srf=&vfbs->surface->res;
987988

988-
ret=vmw_kms_helper_resource_prepare(srf, true);
989+
ret=vmw_kms_helper_resource_prepare(srf, true,&ctx);
989990
if (ret)
990991
returnret;
991992

@@ -1008,7 +1009,7 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
10081009
dest_x,dest_y,num_clips,inc,
10091010
&sdirty.base);
10101011
out_finish:
1011-
vmw_kms_helper_resource_finish(srf,out_fence);
1012+
vmw_kms_helper_resource_finish(&ctx,out_fence);
10121013

10131014
returnret;
10141015
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp