[Mesa-dev] [PATCH 15/14] radeonsi: extend the SDMA L2T VM fault workaround to T2L

Nicolai Hähnle nhaehnle at gmail.com
Sun May 8 16:43:11 UTC 2016


For the history it'd probably be nicer to squash patch 15 in the 
appropriate place. Either way, patches 5 - 15 are

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

On 08.05.2016 07:10, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> Same algorithm, just applied to T2L.
> (and using a 0-based address and surface.bo_size instead of buf->size)
> ---
>   src/gallium/drivers/radeonsi/cik_sdma.c | 108 ++++++++++++++++----------------
>   1 file changed, 55 insertions(+), 53 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/cik_sdma.c b/src/gallium/drivers/radeonsi/cik_sdma.c
> index 17c3a83..cd7b0e6 100644
> --- a/src/gallium/drivers/radeonsi/cik_sdma.c
> +++ b/src/gallium/drivers/radeonsi/cik_sdma.c
> @@ -239,6 +239,7 @@ static bool cik_sdma_copy_texture(struct si_context *sctx,
>   		struct r600_texture *tiled = src_mode >= RADEON_SURF_MODE_1D ? rsrc : rdst;
>   		struct r600_texture *linear = tiled == rsrc ? rdst : rsrc;
>   		unsigned tiled_level =	tiled	== rsrc ? src_level : dst_level;
> +		unsigned linear_level =	linear	== rsrc ? src_level : dst_level;
>   		unsigned tiled_x =	tiled	== rsrc ? srcx : dstx;
>   		unsigned linear_x =	linear  == rsrc ? srcx : dstx;
>   		unsigned tiled_y =	tiled	== rsrc ? srcy : dsty;
> @@ -294,62 +295,63 @@ static bool cik_sdma_copy_texture(struct si_context *sctx,
>   		     tiled_y + copy_height == (1 << 14)))
>   			return false;
>
> -		/* The hw can read outside of the given linear buffer bounds.
> -		 * Out-of-bounds reads must be prevented.
> +		/* The hw can read outside of the given linear buffer bounds,
> +		 * or access those pages but not touch the memory in case
> +		 * of writes. (it still causes a VM fault)
> +		 *
> +		 * Out-of-bounds memory access or page directory access must
> +		 * be prevented.
>   		 */
> -		if (linear == rsrc) {
> -			uint64_t start_linear_address, end_linear_address;
> -			unsigned granularity;
> -
> -			/* Deduce the size of reads from the linear surface. */
> -			switch (tiled_micro_mode) {
> -			case V_009910_ADDR_SURF_DISPLAY_MICRO_TILING:
> -				granularity = bpp == 1 ? 64 / (8*bpp) :
> -							 128 / (8*bpp);
> -				break;
> -			case V_009910_ADDR_SURF_THIN_MICRO_TILING:
> -			case V_009910_ADDR_SURF_DEPTH_MICRO_TILING:
> -				if (0 /* TODO: THICK microtiling */)
> -					granularity = bpp == 1 ? 32 / (8*bpp) :
> -						      bpp == 2 ? 64 / (8*bpp) :
> -						      bpp <= 8 ? 128 / (8*bpp) :
> -								 256 / (8*bpp);
> -				else
> -					granularity = bpp <= 2 ? 64 / (8*bpp) :
> -						      bpp <= 8 ? 128 / (8*bpp) :
> -								 256 / (8*bpp);
> -				break;
> -			default:
> -				return false;
> -			}
> -
> -			/* The linear reads start at tiled_x & ~(granularity - 1).
> -			 * If linear_x == 0 && tiled_x % granularity != 0, the hw
> -			 * starts reading from an address preceding linear_address!!!
> -			 */
> -			start_linear_address =
> -				linear_address +
> -				bpp * (linear_z * src_slice_pitch +
> -				       linear_y * src_pitch +
> -				       linear_x -
> -				       tiled_x % granularity);
> -
> -			end_linear_address =
> -				linear_address +
> -				bpp * ((linear_z + copy_depth - 1) * src_slice_pitch +
> -				       (linear_y + copy_height - 1) * src_pitch +
> -				       (linear_x + copy_width));
> -
> -			if ((tiled_x + copy_width) % granularity)
> -				end_linear_address += granularity -
> -						      (tiled_x + copy_width) % granularity;
> -
> -			if (start_linear_address < linear->resource.gpu_address ||
> -			    end_linear_address > (linear->resource.gpu_address +
> -						  linear->resource.buf->size))
> -				return false;
> +		int64_t start_linear_address, end_linear_address;
> +		unsigned granularity;
> +
> +		/* Deduce the size of reads from the linear surface. */
> +		switch (tiled_micro_mode) {
> +		case V_009910_ADDR_SURF_DISPLAY_MICRO_TILING:
> +			granularity = bpp == 1 ? 64 / (8*bpp) :
> +						 128 / (8*bpp);
> +			break;
> +		case V_009910_ADDR_SURF_THIN_MICRO_TILING:
> +		case V_009910_ADDR_SURF_DEPTH_MICRO_TILING:
> +			if (0 /* TODO: THICK microtiling */)
> +				granularity = bpp == 1 ? 32 / (8*bpp) :
> +					      bpp == 2 ? 64 / (8*bpp) :
> +					      bpp <= 8 ? 128 / (8*bpp) :
> +							 256 / (8*bpp);
> +			else
> +				granularity = bpp <= 2 ? 64 / (8*bpp) :
> +					      bpp <= 8 ? 128 / (8*bpp) :
> +							 256 / (8*bpp);
> +			break;
> +		default:
> +			return false;
>   		}
>
> +		/* The linear reads start at tiled_x & ~(granularity - 1).
> +		 * If linear_x == 0 && tiled_x % granularity != 0, the hw
> +		 * starts reading from an address preceding linear_address!!!
> +		 */
> +		start_linear_address =
> +			linear->surface.level[linear_level].offset +
> +			bpp * (linear_z * linear_slice_pitch +
> +			       linear_y * linear_pitch +
> +			       linear_x);
> +		start_linear_address -= (int)(bpp * (tiled_x % granularity));
> +
> +		end_linear_address =
> +			linear->surface.level[linear_level].offset +
> +			bpp * ((linear_z + copy_depth - 1) * linear_slice_pitch +
> +			       (linear_y + copy_height - 1) * linear_pitch +
> +			       (linear_x + copy_width));
> +
> +		if ((tiled_x + copy_width) % granularity)
> +			end_linear_address += granularity -
> +					      (tiled_x + copy_width) % granularity;
> +
> +		if (start_linear_address < 0 ||
> +		    end_linear_address > linear->surface.bo_size)
> +			return false;
> +
>   		/* Check requirements. */
>   		if (tiled_address % 256 == 0 &&
>   		    linear_address % 4 == 0 &&
>


More information about the mesa-dev mailing list