[Intel-gfx] [PATCH i-g-t] kms_universal_plane: Check for cursor fb leaks

Daniel Vetter daniel at ffwll.ch
Fri Feb 27 07:19:59 PST 2015


On Thu, Feb 26, 2015 at 07:00:19PM -0800, Matt Roper wrote:
> We've been leaking the framebuffers that get created inside the
> legacy -> universal cursor compatibility layer and nobody noticed.  Add
> an i-g-t test to check debugfs and ensure we end up the same number of
> framebuffers we started with after performing cursor operations.
> 
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
> ---
>  tests/kms_universal_plane.c | 119 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 119 insertions(+)
> 
> diff --git a/tests/kms_universal_plane.c b/tests/kms_universal_plane.c
> index 6a05584..7898744 100644
> --- a/tests/kms_universal_plane.c
> +++ b/tests/kms_universal_plane.c
> @@ -532,6 +532,120 @@ pageflip_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output)
>  }
>  
>  static void
> +cursor_leak_test_fini(data_t *data,
> +		      igt_output_t *output,
> +		      struct igt_fb *bg,
> +		      struct igt_fb *curs)
> +{
> +	int i;
> +
> +	igt_remove_fb(data->drm_fd, bg);
> +	for (i = 0; i < 10; i++)
> +		igt_remove_fb(data->drm_fd, &curs[i]);
> +
> +	igt_output_set_pipe(output, PIPE_ANY);
> +}
> +
> +static int
> +i915_gem_fb_count(void)
> +{
> +	char buf[1024];
> +	FILE *fp;
> +	int count = 0;
> +
> +	fp = igt_debugfs_fopen("i915_gem_framebuffer", "r");
> +	igt_require(fp);
> +	while (fgets(buf, sizeof(buf), fp) != NULL)
> +		count++;
> +	fclose(fp);
> +
> +	return count;
> +}
> +
> +static void
> +cursor_leak_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output)
> +{
> +	igt_display_t *display = &data->display;
> +	igt_plane_t *primary, *cursor;
> +	drmModeModeInfo *mode;
> +	struct igt_fb background_fb;
> +	struct igt_fb cursor_fb[10];
> +	int i;
> +	int r, g, b;
> +	int count1, count2;
> +
> +	igt_assert(data->display.has_universal_planes);
> +	igt_skip_on(pipe >= display->n_pipes);
> +
> +	igt_output_set_pipe(output, pipe);
> +	mode = igt_output_get_mode(output);
> +
> +	/* Count GEM framebuffers before creating our cursor FB's */
> +	count1 = i915_gem_fb_count();
> +
> +	/* Black background FB */
> +	igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
> +			    DRM_FORMAT_XRGB8888,
> +			    false,
> +			    0.0, 0.0, 0.0,
> +			    &background_fb);
> +
> +	/* Random color cursors */
> +	for (i = 0; i < 10; i++) {
> +		r = rand() % 0xFF;
> +		g = rand() % 0xFF;
> +		b = rand() % 0xFF;
> +		igt_create_color_fb(data->drm_fd, 64, 64,
> +				    DRM_FORMAT_ARGB8888,
> +				    false,
> +				    (double)r / 0xFF,
> +				    (double)g / 0xFF,
> +				    (double)b / 0xFF,
> +				    &cursor_fb[i]);
> +	}
> +
> +	primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
> +	cursor = igt_output_get_plane(output, IGT_PLANE_CURSOR);
> +	if (!primary || !cursor) {
> +		cursor_leak_test_fini(data, output, &background_fb, cursor_fb);
> +		igt_skip("Primary and/or cursor are unavailable\n");
> +	}
> +
> +
> +	igt_plane_set_fb(primary, &background_fb);
> +	igt_display_commit2(display, COMMIT_LEGACY);
> +
> +	igt_plane_set_position(cursor, 100, 100);
> +
> +	/*
> +	 * Exercise both legacy and universal code paths.  Note that legacy
> +	 * handling in the kernel redirects through universal codepaths
> +	 * internally, so that redirection is where we're most worried about
> +	 * leaking.
> +	 */
> +	for (i = 0; i < 10; i++) {
> +		igt_plane_set_fb(cursor, &cursor_fb[i]);
> +		igt_display_commit2(display, COMMIT_UNIVERSAL);
> +	}
> +	for (i = 0; i < 10; i++) {
> +		igt_plane_set_fb(cursor, &cursor_fb[i]);
> +		igt_display_commit2(display, COMMIT_LEGACY);
> +	}
> +
> +	/* Release our framebuffer handles before we take a second count */
> +	igt_plane_set_fb(primary, NULL);
> +	igt_plane_set_fb(cursor, NULL);
> +	igt_display_commit2(display, COMMIT_LEGACY);
> +	cursor_leak_test_fini(data, output, &background_fb, cursor_fb);
> +
> +	/* We should be back to the same framebuffer count as when we started */
> +	count2 = i915_gem_fb_count();
> +
> +	igt_assert_f(count1 == count2, "Cursor framebuffer leak detected.  "
> +		     "Initial fb count=%d, final count=%d\n", count1, count2);

igt_assert_cmpint allows you to save some typing next time around. I've
bikeshedded that while applying.
-Daniel


> +}
> +
> +static void
>  run_tests_for_pipe(data_t *data, enum pipe pipe)
>  {
>  	igt_output_t *output;
> @@ -550,6 +664,11 @@ run_tests_for_pipe(data_t *data, enum pipe pipe)
>  		      kmstest_pipe_name(pipe))
>  		for_each_connected_output(&data->display, output)
>  			pageflip_test_pipe(data, pipe, output);
> +
> +	igt_subtest_f("cursor-fb-leak-pipe-%s",
> +		      kmstest_pipe_name(pipe))
> +		for_each_connected_output(&data->display, output)
> +			cursor_leak_test_pipe(data, pipe, output);
>  }
>  
>  static data_t data;
> -- 
> 1.8.5.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


More information about the Intel-gfx mailing list