diff options
author | Jerry Zuo <Jerry.Zuo@amd.com> | 2017-07-31 17:10:44 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-09-26 18:16:36 -0400 |
commit | e8cd26434df0cd8d97f31aeb4399afcdc37fcfda (patch) | |
tree | 26614c3e36f8cb14e10d34a5431c4dcf2efe820f /drivers/gpu/drm/amd/display/dc/core/dc_surface.c | |
parent | drm/amd/display: fix gamma distortion on Vega (diff) | |
download | linux-dev-e8cd26434df0cd8d97f31aeb4399afcdc37fcfda.tar.xz linux-dev-e8cd26434df0cd8d97f31aeb4399afcdc37fcfda.zip |
drm/amd/display: Use atomic types for ref_count
Current ref_count inc/dec is not guarded by locks which leads to
a raced condition where two threads try to access the variable
at the same time. In this case, both might act on the same cached
value and inc/dec from the same value, rather than inc/dec by 2.
Signed-off-by: Jerry Zuo <Jerry.Zuo@amd.com>
Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core/dc_surface.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c index 3bcca2d1872b..da19c7fa5151 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c @@ -76,7 +76,7 @@ struct dc_plane_state *dc_create_plane_state(const struct dc *dc) if (false == construct(core_dc->ctx, plane_state)) goto construct_fail; - ++plane_state->ref_count; + atomic_inc(&plane_state->ref_count); return plane_state; @@ -122,16 +122,16 @@ const struct dc_plane_status *dc_plane_get_status( void dc_plane_state_retain(struct dc_plane_state *plane_state) { - ASSERT(plane_state->ref_count > 0); - ++plane_state->ref_count; + ASSERT(atomic_read(&plane_state->ref_count) > 0); + atomic_inc(&plane_state->ref_count); } void dc_plane_state_release(struct dc_plane_state *plane_state) { - ASSERT(plane_state->ref_count > 0); - --plane_state->ref_count; + ASSERT(atomic_read(&plane_state->ref_count) > 0); + atomic_dec(&plane_state->ref_count); - if (plane_state->ref_count == 0) { + if (atomic_read(&plane_state->ref_count) == 0) { destruct(plane_state); dm_free(plane_state); } @@ -139,16 +139,16 @@ void dc_plane_state_release(struct dc_plane_state *plane_state) void dc_gamma_retain(struct dc_gamma *gamma) { - ASSERT(gamma->ref_count > 0); - ++gamma->ref_count; + ASSERT(atomic_read(&gamma->ref_count) > 0); + atomic_inc(&gamma->ref_count); } void dc_gamma_release(struct dc_gamma **gamma) { - ASSERT((*gamma)->ref_count > 0); - --(*gamma)->ref_count; + ASSERT(atomic_read(&(*gamma)->ref_count) > 0); + atomic_dec(&(*gamma)->ref_count); - if ((*gamma)->ref_count == 0) + if (atomic_read(&(*gamma)->ref_count) == 0) dm_free((*gamma)); *gamma = NULL; @@ -161,7 +161,7 @@ struct dc_gamma *dc_create_gamma() if (gamma == NULL) goto alloc_fail; - ++gamma->ref_count; + atomic_inc(&gamma->ref_count); return gamma; @@ -171,16 +171,16 @@ alloc_fail: void dc_transfer_func_retain(struct dc_transfer_func *tf) { - ASSERT(tf->ref_count > 0); - ++tf->ref_count; + ASSERT(atomic_read(&tf->ref_count) > 0); + atomic_inc(&tf->ref_count); } void dc_transfer_func_release(struct dc_transfer_func *tf) { - ASSERT(tf->ref_count > 0); - --tf->ref_count; + ASSERT(atomic_read(&tf->ref_count) > 0); + atomic_dec(&tf->ref_count); - if (tf->ref_count == 0) + if (atomic_read(&tf->ref_count) == 0) dm_free(tf); } @@ -191,7 +191,7 @@ struct dc_transfer_func *dc_create_transfer_func() if (tf == NULL) goto alloc_fail; - ++tf->ref_count; + atomic_inc(&tf->ref_count); return tf; |