drm/radeon: add locking around atombios scratch space usage
Subsystems (2)
Dave Airlie
maintainerPATCH 1/1 drm/radeon: add locking around atombios scratch space usage
From: Dave Airlie <[email protected]>
While developing MST support I noticed I often got the wrong data back from a transaction, in a racy fashion. I noticed the scratch space wasn't locked against concurrent users.
Based on a patch by Alex, but I've made it a bit more obvious when things are locked.
--- drivers/gpu/drm/radeon/atom.c | 11 ++++++++++- drivers/gpu/drm/radeon/atom.h | 2 ++ drivers/gpu/drm/radeon/atombios_dp.c | 4 +++- drivers/gpu/drm/radeon/atombios_i2c.c | 4 +++- drivers/gpu/drm/radeon/radeon_device.c | 1 + 5 files changed, 19 insertions(+), 3 deletions(-)
drivers/gpu/drm/radeon/atom.c +10 -1
@@ -1218,7 +1218,7 @@ free:return ret; } -int atom_execute_table (struct atom_context *ctx,int index,uint32_t * params) +int atom_execute_table_scratch_unlocked (struct atom_context *ctx,int index,uint32_t * params) {int r;
@@ -1239,6 +1239,15 @@ int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)return r; } +int atom_execute_table (struct atom_context *ctx,int index,uint32_t * params) +{ +int r; +mutex_lock (&ctx->scratch_mutex); + r =atom_execute_table_scratch_unlocked (ctx, index, params); +mutex_unlock (&ctx->scratch_mutex); +return r; +} +static int atom_iio_len[] = {1 ,2 ,3 ,3 ,3 ,3 ,4 ,4 ,4 ,3 };static void atom_index_iio (struct atom_context *ctx,int base)
drivers/gpu/drm/radeon/atom.h +2 -0
@@ -125,6 +125,7 @@ struct card_info {struct atom_context {struct card_info *card;struct mutex mutex; +struct mutex scratch_mutex;void *bios;uint32_t cmd_table, data_table;uint16_t *iio;
@@ -146,6 +147,7 @@ extern int atom_reg_debug;struct atom_context *atom_parse (struct card_info *,void *);int atom_execute_table (struct atom_context *,int ,uint32_t *); +int atom_execute_table_scratch_unlocked (struct atom_context *,int ,uint32_t *);int atom_asic_init (struct atom_context *);void atom_destroy (struct atom_context *); bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,
drivers/gpu/drm/radeon/atombios_dp.c +3 -1
@@ -100,6 +100,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,memset (&args,0 ,sizeof (args));mutex_lock (&chan->mutex); +mutex_lock (&rdev->mode_info.atom_context->scratch_mutex); base = (unsigned char *)(rdev->mode_info.atom_context->scratch +1 );
@@ -113,7 +114,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,if (ASIC_IS_DCE4 (rdev)) args.v2.ucHPD_ID = chan->rec.hpd; -atom_execute_table (rdev->mode_info.atom_context, index, (uint32_t *)&args); +atom_execute_table_scratch_unlocked (rdev->mode_info.atom_context, index, (uint32_t *)&args); *ack = args.v1.ucReplyStatus;
@@ -147,6 +148,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, r = recv_bytes; done: +mutex_unlock (&rdev->mode_info.atom_context->scratch_mutex);mutex_unlock (&chan->mutex);return r;
drivers/gpu/drm/radeon/atombios_i2c.c +3 -1
@@ -48,6 +48,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,memset (&args,0 ,sizeof (args));mutex_lock (&chan->mutex); +mutex_lock (&rdev->mode_info.atom_context->scratch_mutex); base = (unsigned char *)rdev->mode_info.atom_context->scratch;
@@ -82,7 +83,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, args.ucSlaveAddr = slave_addr <<1 ; args.ucLineNumber = chan->rec.i2c_id; -atom_execute_table (rdev->mode_info.atom_context, index, (uint32_t *)&args); +atom_execute_table_scratch_unlocked (rdev->mode_info.atom_context, index, (uint32_t *)&args);/* error */ if (args.ucStatus !=HW_ASSISTED_I2C_STATUS_SUCCESS ) {
@@ -95,6 +96,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,radeon_atom_copy_swap (buf, base, num, false); done: +mutex_unlock (&rdev->mode_info.atom_context->scratch_mutex);mutex_unlock (&chan->mutex);return r;
drivers/gpu/drm/radeon/radeon_device.c +1 -0
@@ -950,6 +950,7 @@ int radeon_atombios_init(struct radeon_device *rdev) }mutex_init (&rdev->mode_info.atom_context->mutex); +mutex_init (&rdev->mode_info.atom_context->scratch_mutex);radeon_atom_initialize_bios_scratch_regs (rdev->ddev);atom_allocate_fb_scratch (rdev->mode_info.atom_context);return 0 ;
Signature · 6 lines
1.9.3 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Alex Deucher
AppliedQuoted 10 lines · Dave Airlie
From: Dave Airlie <[email protected]>
While developing MST support I noticed I often got the wrong data back from a transaction, in a racy fashion. I noticed the scratch space wasn't locked against concurrent users.
Based on a patch by Alex, but I've made it a bit more obvious when things are locked.
Signed-off-by Dave Airlie <[email protected]>
Applied to my -fixes tree.
Alex
Quoted 130 lines
--- drivers/gpu/drm/radeon/atom.c | 11 ++++++++++- drivers/gpu/drm/radeon/atom.h | 2 ++ drivers/gpu/drm/radeon/atombios_dp.c | 4 +++- drivers/gpu/drm/radeon/atombios_i2c.c | 4 +++- drivers/gpu/drm/radeon/radeon_device.c | 1 + 5 files changed, 19 insertions(+), 3 deletions(-)drivers/gpu/drm/radeon/atom.c +10
-1@@ -1218,7 +1218,7 @@ free:return ret; } -int atom_execute_table (struct atom_context *ctx,int index,uint32_t * params) +int atom_execute_table_scratch_unlocked (struct atom_context *ctx,int index,uint32_t * params) {int r;@@ -1239,6 +1239,15 @@ int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)return r; } +int atom_execute_table (struct atom_context *ctx,int index,uint32_t * params) +{ +int r; +mutex_lock (&ctx->scratch_mutex); + r =atom_execute_table_scratch_unlocked (ctx, index, params); +mutex_unlock (&ctx->scratch_mutex); +return r; +} +static int atom_iio_len[] = {1 ,2 ,3 ,3 ,3 ,3 ,4 ,4 ,4 ,3 };static void atom_index_iio (struct atom_context *ctx,int base)drivers/gpu/drm/radeon/atom.h +2
-0@@ -125,6 +125,7 @@ struct card_info {struct atom_context {struct card_info *card;struct mutex mutex; +struct mutex scratch_mutex;void *bios;uint32_t cmd_table, data_table;uint16_t *iio;@@ -146,6 +147,7 @@ extern int atom_reg_debug;struct atom_context *atom_parse (struct card_info *,void *);int atom_execute_table (struct atom_context *,int ,uint32_t *); +int atom_execute_table_scratch_unlocked (struct atom_context *,int ,uint32_t *);int atom_asic_init (struct atom_context *);void atom_destroy (struct atom_context *); bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,drivers/gpu/drm/radeon/atombios_dp.c +3
-1@@ -100,6 +100,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,memset (&args,0 ,sizeof (args));mutex_lock (&chan->mutex); +mutex_lock (&rdev->mode_info.atom_context->scratch_mutex); base = (unsigned char *)(rdev->mode_info.atom_context->scratch +1 );@@ -113,7 +114,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,if (ASIC_IS_DCE4 (rdev)) args.v2.ucHPD_ID = chan->rec.hpd; -atom_execute_table (rdev->mode_info.atom_context, index, (uint32_t *)&args); +atom_execute_table_scratch_unlocked (rdev->mode_info.atom_context, index, (uint32_t *)&args); *ack = args.v1.ucReplyStatus;@@ -147,6 +148,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, r = recv_bytes; done: +mutex_unlock (&rdev->mode_info.atom_context->scratch_mutex);mutex_unlock (&chan->mutex);return r;drivers/gpu/drm/radeon/atombios_i2c.c +3
-1@@ -48,6 +48,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,memset (&args,0 ,sizeof (args));mutex_lock (&chan->mutex); +mutex_lock (&rdev->mode_info.atom_context->scratch_mutex); base = (unsigned char *)rdev->mode_info.atom_context->scratch;@@ -82,7 +83,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, args.ucSlaveAddr = slave_addr <<1 ; args.ucLineNumber = chan->rec.i2c_id; -atom_execute_table (rdev->mode_info.atom_context, index, (uint32_t *)&args); +atom_execute_table_scratch_unlocked (rdev->mode_info.atom_context, index, (uint32_t *)&args);/* error */ if (args.ucStatus !=HW_ASSISTED_I2C_STATUS_SUCCESS ) {@@ -95,6 +96,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,radeon_atom_copy_swap (buf, base, num, false); done: +mutex_unlock (&rdev->mode_info.atom_context->scratch_mutex);mutex_unlock (&chan->mutex);return r;drivers/gpu/drm/radeon/radeon_device.c +1
-1@@ -950,6 +950,7 @@ int radeon_atombios_init(struct radeon_device *rdev) }mutex_init (&rdev->mode_info.atom_context->mutex); +mutex_init (&rdev->mode_info.atom_context->scratch_mutex);radeon_atom_initialize_bios_scratch_regs (rdev->ddev);atom_allocate_fb_scratch (rdev->mode_info.atom_context);return 0 ; --1.9.3
Quoted 4 lines
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel