[PATCH 5/5] drm/amdgpu: add more inject control

Alex Deucher alexdeucher at gmail.com
Thu Mar 21 15:58:15 UTC 2019


On Thu, Mar 21, 2019 at 3:34 AM Pan, Xinhui <Xinhui.Pan at amd.com> wrote:
>
> TA accept some options like address is in sram or vram. Most default
> options are enough to use. But allow user to setup them.
>
> reuse inject.value to place these options.
>
> At the same time, we need translate the address to a physical/gpu
> address which the pages are mapped at.
>
> Signed-off-by: xinhui pan <xinhui.pan at amd.com>

Acked-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 83 ++++++++++++++++++++++++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h | 20 +++++-
>  2 files changed, 101 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
> index 469cb6477b8e..ca823675a1c0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
> @@ -121,6 +121,21 @@ const char *ras_block_string[] = {
>  #define AMDGPU_RAS_FLAG_INIT_BY_VBIOS 1
>  #define RAS_DEFAULT_FLAGS (AMDGPU_RAS_FLAG_INIT_BY_VBIOS)
>
> +static int amdgpu_ras_reserve_vram(struct amdgpu_device *adev,
> +               uint64_t offset, uint64_t size,
> +               struct amdgpu_bo **bo_ptr);
> +
> +static int amdgpu_ras_release_vram(struct amdgpu_device *adev,
> +               struct amdgpu_bo **bo_ptr);
> +
> +static int amdgpu_ras_translate_addr(struct amdgpu_device *adev,
> +               u64 *gpu_addr, int addr_type)
> +{
> +       /* TODO */
> +
> +       return -EINVAL;
> +}
> +
>  static void amdgpu_ras_self_test(struct amdgpu_device *adev)
>  {
>         /* TODO */
> @@ -176,6 +191,28 @@ static int amdgpu_ras_find_block_id_by_name(const char *name, int *block_id)
>         return -EINVAL;
>  }
>
> +static bool amdgpu_ras_extract_inject_data(const struct ras_inject_if *inject,
> +               u64 *address, u64 *value, int *addr_type, int *inject_type)
> +{
> +       const struct inject_data *data = &inject->data;
> +
> +       if (data->magic != AMDGPU_RAS_INJECT_MAGIC ||
> +                       data->u8_reserved ||
> +                       data->u32_reserved) {
> +               *address = inject->address;
> +               *value = inject->value;
> +
> +               return false;
> +       }
> +
> +       *address = inject->address;
> +       *value = data->value;
> +       *addr_type = data->addr_type;
> +       *inject_type = data->inject_type;
> +
> +       return true;
> +}
> +
>  static int amdgpu_ras_debugfs_ctrl_parse_data(struct file *f,
>                 const char __user *buf, size_t size,
>                 loff_t *pos, struct ras_debug_if *data)
> @@ -300,7 +337,14 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user *
>  {
>         struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
>         struct ras_debug_if data;
> +       struct amdgpu_bo *bo = NULL;
>         int ret = 0;
> +       u64 address;
> +       u64 value;
> +       int addr_type = 0;
> +       int inject_type;
> +
> +       BUILD_BUG_ON(sizeof(struct inject_data) > sizeof(uint64_t));
>
>         ret = amdgpu_ras_debugfs_ctrl_parse_data(f, buf, size, pos, &data);
>         if (ret)
> @@ -317,7 +361,44 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user *
>                 ret = amdgpu_ras_feature_enable(adev, &data.head, 1);
>                 break;
>         case 2:
> -               ret = amdgpu_ras_error_inject(adev, &data.inject);
> +               do {
> +                       if (amdgpu_ras_extract_inject_data(&data.inject,
> +                                               &address,
> +                                               &value,
> +                                               &addr_type,
> +                                               &inject_type))
> +                               /* not documented yet. */
> +                               data.inject.value = inject_type;
> +                       else
> +                               data.inject.value = value;
> +
> +                       /* 0 is vram, 1 is sram. */
> +                       data.inject.head.sub_block_index = addr_type;
> +
> +                       /*
> +                        * Need translate address to phy address accodring to
> +                        * addr_type.
> +                        */
> +                       ret = amdgpu_ras_translate_addr(adev,
> +                                       &address, addr_type);
> +                       /* address is not mapped with physical pages */
> +                       if (ret) {
> +                               if (addr_type)
> +                                       break;
> +
> +                               /* try to reserve vram at address for inject.*/
> +                               if (amdgpu_ras_reserve_vram(adev,
> +                                                       address >> PAGE_SHIFT,
> +                                                       PAGE_SIZE, &bo))
> +                                       break;
> +                       }
> +
> +                       data.inject.address = address;
> +
> +                       ret = amdgpu_ras_error_inject(adev, &data.inject);
> +                       if (bo)
> +                               amdgpu_ras_release_vram(adev, &bo);
> +               } while (0);
>                 break;
>         default:
>                 ret = -EINVAL;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
> index 682f2be0d68c..adcf7d88d59d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
> @@ -121,10 +121,28 @@ struct ras_query_if {
>         unsigned long ce_count;
>  };
>
> +#define AMDGPU_RAS_INJECT_MAGIC 0xaa55
>  struct ras_inject_if {
>         struct ras_common_if head;
>         uint64_t address;
> -       uint64_t value;
> +       union {
> +               uint64_t value;
> +               struct inject_data {
> +                       u8 value;
> +                       /* 0 is vram, 1 is sram */
> +                       u8 addr_type:1;
> +                       /* TA has several inject types,
> +                        * but looks like 0 is the most case.
> +                        */
> +                       u8 inject_type:3;
> +                       /* must be 0 */
> +                       u8 u8_reserved;
> +                       /* identify value or inject_data. */
> +                       u8 magic;
> +                       /* must be 0 */
> +                       u32 u32_reserved;
> +               } data;
> +       };
>  };
>
>  struct ras_cure_if {
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list