[PATCH] drm/radeon: add locking around atombios scratch space usage
Alex Deucher
alexdeucher at gmail.com
Tue Nov 11 14:23:08 PST 2014
On Mon, Nov 10, 2014 at 6:16 PM, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> 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 <airlied at redhat.com>
Applied to my -fixes tree.
Alex
> ---
> 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(-)
>
> diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
> index 6f26eb7..bec41c4 100644
> --- a/drivers/gpu/drm/radeon/atom.c
> +++ b/drivers/gpu/drm/radeon/atom.c
> @@ -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)
> diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h
> index bf9e6f2..6dffe15 100644
> --- a/drivers/gpu/drm/radeon/atom.h
> +++ b/drivers/gpu/drm/radeon/atom.h
> @@ -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,
> diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
> index bd96ae7..0f39d96 100644
> --- a/drivers/gpu/drm/radeon/atombios_dp.c
> +++ b/drivers/gpu/drm/radeon/atombios_dp.c
> @@ -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;
> diff --git a/drivers/gpu/drm/radeon/atombios_i2c.c b/drivers/gpu/drm/radeon/atombios_i2c.c
> index 9c570fb..4157780 100644
> --- a/drivers/gpu/drm/radeon/atombios_i2c.c
> +++ b/drivers/gpu/drm/radeon/atombios_i2c.c
> @@ -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;
> diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
> index 0d77dce..e63c9a4 100644
> --- a/drivers/gpu/drm/radeon/radeon_device.c
> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> @@ -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
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
More information about the dri-devel
mailing list