[Mesa-dev] [PATCH 1/5] radeonsi: align command buffer starting address to fix some Raven hangs

Christian König ckoenig.leichtzumerken at gmail.com
Thu Mar 8 09:27:44 UTC 2018


Am 07.03.2018 um 21:34 schrieb Marek Olšák:
> From: Marek Olšák <marek.olsak at amd.com>
>
> Cc: 17.3 18.0 <mesa-stable at lists.freedesktop.org>

Reviewed-by: Christian König <christian.koenig at amd.com>.

> ---
>   src/amd/common/ac_gpu_info.c                      | 21 ++++++++++++++++++++-
>   src/amd/common/ac_gpu_info.h                      |  1 +
>   src/gallium/drivers/radeonsi/si_pm4.c             |  5 +++--
>   src/gallium/winsys/amdgpu/drm/amdgpu_cs.c         |  5 +++--
>   src/gallium/winsys/radeon/drm/radeon_drm_winsys.c |  1 +
>   5 files changed, 28 insertions(+), 5 deletions(-)
>
> diff --git a/src/amd/common/ac_gpu_info.c b/src/amd/common/ac_gpu_info.c
> index 146098b..7c13e5f 100644
> --- a/src/amd/common/ac_gpu_info.c
> +++ b/src/amd/common/ac_gpu_info.c
> @@ -91,21 +91,23 @@ static bool has_syncobj(int fd)
>   		return false;
>   	return value ? true : false;
>   }
>   
>   bool ac_query_gpu_info(int fd, amdgpu_device_handle dev,
>   		       struct radeon_info *info,
>   		       struct amdgpu_gpu_info *amdinfo)
>   {
>   	struct amdgpu_buffer_size_alignments alignment_info = {};
>   	struct amdgpu_heap_info vram, vram_vis, gtt;
> -	struct drm_amdgpu_info_hw_ip dma = {}, compute = {}, uvd = {}, uvd_enc = {}, vce = {}, vcn_dec = {}, vcn_enc = {};
> +	struct drm_amdgpu_info_hw_ip dma = {}, compute = {}, uvd = {};
> +	struct drm_amdgpu_info_hw_ip uvd_enc = {}, vce = {}, vcn_dec = {};
> +	struct drm_amdgpu_info_hw_ip vcn_enc = {}, gfx = {};
>   	uint32_t vce_version = 0, vce_feature = 0, uvd_version = 0, uvd_feature = 0;
>   	int r, i, j;
>   	drmDevicePtr devinfo;
>   
>   	/* Get PCI info. */
>   	r = drmGetDevice2(fd, 0, &devinfo);
>   	if (r) {
>   		fprintf(stderr, "amdgpu: drmGetDevice2 failed.\n");
>   		return false;
>   	}
> @@ -147,20 +149,26 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev,
>   		fprintf(stderr, "amdgpu: amdgpu_query_heap_info(gtt) failed.\n");
>   		return false;
>   	}
>   
>   	r = amdgpu_query_hw_ip_info(dev, AMDGPU_HW_IP_DMA, 0, &dma);
>   	if (r) {
>   		fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(dma) failed.\n");
>   		return false;
>   	}
>   
> +	r = amdgpu_query_hw_ip_info(dev, AMDGPU_HW_IP_GFX, 0, &gfx);
> +	if (r) {
> +		fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(gfx) failed.\n");
> +		return false;
> +	}
> +
>   	r = amdgpu_query_hw_ip_info(dev, AMDGPU_HW_IP_COMPUTE, 0, &compute);
>   	if (r) {
>   		fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(compute) failed.\n");
>   		return false;
>   	}
>   
>   	r = amdgpu_query_hw_ip_info(dev, AMDGPU_HW_IP_UVD, 0, &uvd);
>   	if (r) {
>   		fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(uvd) failed.\n");
>   		return false;
> @@ -333,20 +341,31 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev,
>   
>   	memcpy(info->cik_macrotile_mode_array, amdinfo->gb_macro_tile_mode,
>   		sizeof(amdinfo->gb_macro_tile_mode));
>   
>   	info->pte_fragment_size = alignment_info.size_local;
>   	info->gart_page_size = alignment_info.size_remote;
>   
>   	if (info->chip_class == SI)
>   		info->gfx_ib_pad_with_type2 = TRUE;
>   
> +	unsigned ib_align = 0;
> +	ib_align = MAX2(ib_align, gfx.ib_start_alignment);
> +	ib_align = MAX2(ib_align, compute.ib_start_alignment);
> +	ib_align = MAX2(ib_align, dma.ib_start_alignment);
> +	ib_align = MAX2(ib_align, uvd.ib_start_alignment);
> +	ib_align = MAX2(ib_align, uvd_enc.ib_start_alignment);
> +	ib_align = MAX2(ib_align, vce.ib_start_alignment);
> +	ib_align = MAX2(ib_align, vcn_dec.ib_start_alignment);
> +	ib_align = MAX2(ib_align, vcn_enc.ib_start_alignment);
> +	info->ib_start_alignment = ib_align;
> +
>   	return true;
>   }
>   
>   void ac_compute_driver_uuid(char *uuid, size_t size)
>   {
>   	char amd_uuid[] = "AMD-MESA-DRV";
>   
>   	assert(size >= sizeof(amd_uuid));
>   
>   	memset(uuid, 0, size);
> diff --git a/src/amd/common/ac_gpu_info.h b/src/amd/common/ac_gpu_info.h
> index 7c86dc1..0beba96 100644
> --- a/src/amd/common/ac_gpu_info.h
> +++ b/src/amd/common/ac_gpu_info.h
> @@ -55,20 +55,21 @@ struct radeon_info {
>   	uint64_t                    gart_size;
>   	uint64_t                    vram_size;
>   	uint64_t                    vram_vis_size;
>   	uint64_t                    max_alloc_size;
>   	uint32_t                    min_alloc_size;
>   	uint32_t                    address32_hi;
>   	bool                        has_dedicated_vram;
>   	bool                        has_virtual_memory;
>   	bool                        gfx_ib_pad_with_type2;
>   	bool                        has_hw_decode;
> +	unsigned                    ib_start_alignment;
>   	uint32_t                    num_sdma_rings;
>   	uint32_t                    num_compute_rings;
>   	uint32_t                    uvd_fw_version;
>   	uint32_t                    vce_fw_version;
>   	bool                        uvd_enc_supported;
>   	uint32_t                    me_fw_version;
>   	uint32_t                    me_fw_feature;
>   	uint32_t                    pfp_fw_version;
>   	uint32_t                    pfp_fw_feature;
>   	uint32_t                    ce_fw_version;
> diff --git a/src/gallium/drivers/radeonsi/si_pm4.c b/src/gallium/drivers/radeonsi/si_pm4.c
> index 96e4e1d..f4c41f5 100644
> --- a/src/gallium/drivers/radeonsi/si_pm4.c
> +++ b/src/gallium/drivers/radeonsi/si_pm4.c
> @@ -160,22 +160,23 @@ void si_pm4_upload_indirect_buffer(struct si_context *sctx,
>   
>   	/* only supported on CIK and later */
>   	if (sctx->b.chip_class < CIK)
>   		return;
>   
>   	assert(state->ndw);
>   	assert(aligned_ndw <= SI_PM4_MAX_DW);
>   
>   	r600_resource_reference(&state->indirect_buffer, NULL);
>   	state->indirect_buffer = (struct r600_resource*)
> -		pipe_buffer_create(screen, 0,
> -				   PIPE_USAGE_DEFAULT, aligned_ndw * 4);
> +		si_aligned_buffer_create(screen, 0,
> +					 PIPE_USAGE_DEFAULT, aligned_ndw * 4,
> +					 sctx->screen->info.ib_start_alignment);
>   	if (!state->indirect_buffer)
>   		return;
>   
>   	/* Pad the IB to 8 DWs to meet CP fetch alignment requirements. */
>   	if (sctx->screen->info.gfx_ib_pad_with_type2) {
>   		for (int i = state->ndw; i < aligned_ndw; i++)
>   			state->pm4[i] = 0x80000000; /* type2 nop packet */
>   	} else {
>   		for (int i = state->ndw; i < aligned_ndw; i++)
>   			state->pm4[i] = 0xffff1000; /* type3 nop packet */
> diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
> index 92d5394..d9a95c0 100644
> --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
> +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
> @@ -793,24 +793,25 @@ static bool amdgpu_get_new_ib(struct radeon_winsys *ws, struct amdgpu_cs *cs,
>   static void amdgpu_set_ib_size(struct amdgpu_ib *ib)
>   {
>      if (ib->ptr_ib_size_inside_ib) {
>         *ib->ptr_ib_size = ib->base.current.cdw |
>                            S_3F2_CHAIN(1) | S_3F2_VALID(1);
>      } else {
>         *ib->ptr_ib_size = ib->base.current.cdw;
>      }
>   }
>   
> -static void amdgpu_ib_finalize(struct amdgpu_ib *ib)
> +static void amdgpu_ib_finalize(struct amdgpu_winsys *ws, struct amdgpu_ib *ib)
>   {
>      amdgpu_set_ib_size(ib);
>      ib->used_ib_space += ib->base.current.cdw * 4;
> +   ib->used_ib_space = align(ib->used_ib_space, ws->info.ib_start_alignment);
>      ib->max_ib_size = MAX2(ib->max_ib_size, ib->base.prev_dw + ib->base.current.cdw);
>   }
>   
>   static bool amdgpu_init_cs_context(struct amdgpu_cs_context *cs,
>                                      enum ring_type ring_type)
>   {
>      switch (ring_type) {
>      case RING_DMA:
>         cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_DMA;
>         break;
> @@ -1554,21 +1555,21 @@ static int amdgpu_cs_flush(struct radeon_winsys_cs *rcs,
>         fprintf(stderr, "amdgpu: command stream overflowed\n");
>      }
>   
>      /* If the CS is not empty or overflowed.... */
>      if (likely(radeon_emitted(&cs->main.base, 0) &&
>          cs->main.base.current.cdw <= cs->main.base.current.max_dw &&
>          !debug_get_option_noop())) {
>         struct amdgpu_cs_context *cur = cs->csc;
>   
>         /* Set IB sizes. */
> -      amdgpu_ib_finalize(&cs->main);
> +      amdgpu_ib_finalize(ws, &cs->main);
>   
>         /* Create a fence. */
>         amdgpu_fence_reference(&cur->fence, NULL);
>         if (cs->next_fence) {
>            /* just move the reference */
>            cur->fence = cs->next_fence;
>            cs->next_fence = NULL;
>         } else {
>            cur->fence = amdgpu_fence_create(cs->ctx,
>                                             cur->ib[IB_MAIN].ip_type,
> diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
> index 85a186a..036e986 100644
> --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
> +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
> @@ -520,20 +520,21 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
>           }
>       }
>   
>       /* Hawaii with old firmware needs type2 nop packet.
>        * accel_working2 with value 3 indicates the new firmware.
>        */
>       ws->info.gfx_ib_pad_with_type2 = ws->info.chip_class <= SI ||
>   				     (ws->info.family == CHIP_HAWAII &&
>   				      ws->accel_working2 < 3);
>       ws->info.tcc_cache_line_size = 64; /* TC L2 line size on GCN */
> +    ws->info.ib_start_alignment = 4096;
>   
>       ws->check_vm = strstr(debug_get_option("R600_DEBUG", ""), "check_vm") != NULL;
>   
>       return true;
>   }
>   
>   static void radeon_winsys_destroy(struct radeon_winsys *rws)
>   {
>       struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
>   



More information about the mesa-dev mailing list