[igt-dev] [PATCH i-g-t] i915/gem_ccs: Remove race in creating batch buffers
Kamil Konieczny
kamil.konieczny at linux.intel.com
Mon Jan 16 19:10:30 UTC 2023
Hi Zbigniew,
On 2023-01-14 at 20:49:10 +0100, Zbigniew Kempczyński wrote:
> Creating buffers from pool allows achieve pipelined execution easier -
---------------------------------------------------------------------- ^
Maybe just ',' (comma) instead of '-' ?
> returned buffer is not active from driver point of view. Unfortunately
> buffer should be created before use, otherwise we can hit the race.
>
> In the test in rare cases batch created for ctrl-surf from pool was
> immediate executed and not active so batch created for block-copy had
> same handle. Problem occurred when block-copy was executed immediately
> after surf-copy without stalls - both batches used same handle,
-------------------------------- ^
Maybe s/-/and/ ?
> so latter just overwrites instructions of previous one.
>
> Instead of using buffer pool we create two separate batches - one for
------------------------------------------------------------- ^
Same here s/-/,/
> surf-copy and second for block-copy. This will remove the buffer
> creation race from the pool. Additionally add surface compare diff
------------------------------ ^
> grouped by 8x8 blocks of pixels.
This is rather compare used in dumping difference, original compare
is still memcmp. Maybe put this into new paragraph ?
>
> Fixes: https://gitlab.freedesktop.org/drm/intel/-/issues/6683
>
> Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
> Cc: Kamil Konieczny <kamil.konieczny at linux.intel.com>
> ---
> tests/i915/gem_ccs.c | 69 +++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 61 insertions(+), 8 deletions(-)
>
> diff --git a/tests/i915/gem_ccs.c b/tests/i915/gem_ccs.c
> index 751f65e63d..ad2ef0cb41 100644
> --- a/tests/i915/gem_ccs.c
> +++ b/tests/i915/gem_ccs.c
> @@ -158,6 +158,54 @@ static void set_blt_object(struct blt_copy_object *obj,
> if (param.write_png) \
> blt_surface_to_png((fd), (id), (name), (obj), (w), (h)); } while (0)
>
> +static int compare_nxn(const struct blt_copy_object *surf1,
> + const struct blt_copy_object *surf2,
> + int xsize, int ysize, int bx, int by)
> +{
> + int x, y, corrupted;
> + uint32_t pos, px1, px2;
> +
> + corrupted = 0;
> + for (y = 0; y < ysize; y++) {
> + for (x = 0; x < xsize; x++) {
> + pos = bx * xsize + by * ysize * surf1->pitch / 4;
> + pos += x + y * surf1->pitch / 4;
> + px1 = surf1->ptr[pos];
> + px2 = surf2->ptr[pos];
> + if (px1 != px2)
> + corrupted++;
> + }
> + }
> +
> + return corrupted;
> +}
> +
> +static void dump_corruption_info(const struct blt_copy_object *surf1,
> + const struct blt_copy_object *surf2)
> +{
> + const int xsize = 8, ysize = 8;
> + int w, h, bx, by, corrupted;
> +
> + igt_assert(surf1->x1 == surf2->x1 && surf1->x2 == surf2->x2);
> + igt_assert(surf1->y1 == surf2->y1 && surf1->y2 == surf2->y2);
> + w = surf1->x2;
> + h = surf1->y2;
> +
> + igt_info("dump corruption - width: %d, height: %d, sizex: %x, sizey: %x\n",
> + surf1->x2, surf1->y2, xsize, ysize);
> +
> + for (by = 0; by < h / ysize; by++) {
> + for (bx = 0; bx < w / xsize; bx++) {
> + corrupted = compare_nxn(surf1, surf2, xsize, ysize, bx, by);
> + if (corrupted == 0)
> + igt_info(".");
> + else
> + igt_info("%c", '0' + corrupted);
> + }
> + igt_info("\n");
> + }
> +}
> +
> static void surf_copy(int i915,
> const intel_ctx_t *ctx,
> const struct intel_execution_engine2 *e,
> @@ -170,7 +218,7 @@ static void surf_copy(int i915,
> struct blt_copy_data blt = {};
> struct blt_block_copy_data_ext ext = {};
> struct blt_ctrl_surf_copy_data surf = {};
> - uint32_t bb, ccs, ccs2, *ccsmap, *ccsmap2;
> + uint32_t bb1, bb2, ccs, ccs2, *ccsmap, *ccsmap2;
> uint64_t bb_size, ccssize = mid->size / CCS_RATIO;
> uint32_t *ccscopy;
> uint8_t uc_mocs = intel_get_uc_mocs(i915);
> @@ -178,8 +226,6 @@ static void surf_copy(int i915,
>
> igt_assert(mid->compression);
> ccscopy = (uint32_t *) malloc(ccssize);
> - bb_size = 4096;
> - bb = gem_create_from_pool(i915, &bb_size, REGION_SMEM);
> ccs = gem_create(i915, ccssize);
> ccs2 = gem_create(i915, ccssize);
>
> @@ -189,7 +235,9 @@ static void surf_copy(int i915,
> uc_mocs, INDIRECT_ACCESS);
> set_surf_object(&surf.dst, ccs, REGION_SMEM, ccssize,
> uc_mocs, DIRECT_ACCESS);
> - set_batch(&surf.bb, bb, bb_size, REGION_SMEM);
> + bb_size = 4096;
> + igt_assert_eq(__gem_create(i915, &bb_size, &bb1), 0);
> + set_batch(&surf.bb, bb1, bb_size, REGION_SMEM);
> blt_ctrl_surf_copy(i915, ctx, e, ahnd, &surf);
> gem_sync(i915, surf.dst.handle);
>
> @@ -240,9 +288,8 @@ static void surf_copy(int i915,
> set_blt_object(&blt.dst, dst);
> set_object_ext(&ext.src, mid->compression_type, mid->x2, mid->y2, SURFACE_TYPE_2D);
> set_object_ext(&ext.dst, 0, dst->x2, dst->y2, SURFACE_TYPE_2D);
> - bb_size = 4096;
> - bb = gem_create_from_pool(i915, &bb_size, REGION_SMEM);
> - set_batch(&blt.bb, bb, bb_size, REGION_SMEM);
> + igt_assert_eq(__gem_create(i915, &bb_size, &bb2), 0);
> + set_batch(&blt.bb, bb2, bb_size, REGION_SMEM);
> blt_block_copy(i915, ctx, e, ahnd, &blt, &ext);
> gem_sync(i915, blt.dst.handle);
> WRITE_PNG(i915, run_id, "corrupted", &blt.dst, dst->x2, dst->y2);
> @@ -257,10 +304,16 @@ static void surf_copy(int i915,
> gem_sync(i915, blt.dst.handle);
> WRITE_PNG(i915, run_id, "corrected", &blt.dst, dst->x2, dst->y2);
> result = memcmp(src->ptr, dst->ptr, src->size);
> - igt_assert(result == 0);
> + if (result)
> + dump_corruption_info(src, dst);
>
> munmap(ccsmap, ccssize);
> gem_close(i915, ccs);
> + gem_close(i915, ccs2);
> + gem_close(i915, bb1);
> + gem_close(i915, bb2);
> +
> + igt_assert_f(result == 0, "Surface after retrieving ccs data is not correct\n");
Looks like logic slightly changed here ? Maybe it is worth for description.
Reviewed-by: Kamil Konieczny <kamil.konieczny at linux.intel.com>
Regards,
Kamil
> }
>
> struct blt_copy3_data {
> --
> 2.34.1
>
More information about the igt-dev
mailing list