All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
To: "Zbigniew Kempczyński" <zbigniew.kempczynski@intel.com>
Cc: igt-dev@lists.freedesktop.org,
	Petri Latvala <petri.latvala@intel.com>,
	Daniel Vetter <daniel@ffwll.ch>
Subject: Re: [igt-dev] [PATCH i-g-t v6 3/3] Introduce device selection lsgpu tool
Date: Tue, 10 Sep 2019 14:48:54 +0300	[thread overview]
Message-ID: <20190910114854.hq6cdbeyzbs7h7in@ahiler-desk1.fi.intel.com> (raw)
In-Reply-To: <20190904103701.20490-4-zbigniew.kempczynski@intel.com>

On Wed, Sep 04, 2019 at 12:37:01PM +0200, Zbigniew Kempczyński wrote:
> Tool uses device selection API to scan and display GPU devices.
> It can be used to check filter correctness as well as order
> of filter applying (.igtrc, IGT_DEVICE and --device argument).
> 
> Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> Cc: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: Petri Latvala <petri.latvala@intel.com>
> ---
>  tools/Makefile.sources |   1 +
>  tools/lsgpu.c          | 299 +++++++++++++++++++++++++++++++++++++++++
>  tools/meson.build      |   1 +
>  3 files changed, 301 insertions(+)
>  create mode 100644 tools/lsgpu.c
> 
> diff --git a/tools/Makefile.sources b/tools/Makefile.sources
> index 50706f41..0e67b654 100644
> --- a/tools/Makefile.sources
> +++ b/tools/Makefile.sources
> @@ -33,6 +33,7 @@ tools_prog_lists =		\
>  	intel_watermark		\
>  	intel_gem_info		\
>  	intel_gvtg_test     \
> +	lsgpu			\
>  	$(NULL)
>  
>  dist_bin_SCRIPTS = intel_gpu_abrt
> diff --git a/tools/lsgpu.c b/tools/lsgpu.c
> new file mode 100644
> index 00000000..964bcf88
> --- /dev/null
> +++ b/tools/lsgpu.c
> @@ -0,0 +1,299 @@
> +/*
> + * Copyright © 2019 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +
> +#include "igt_device_scan.h"
> +#include "igt.h"
> +#include <sys/ioctl.h>
> +#include <fcntl.h>
> +#include <errno.h>
> +#include <string.h>
> +#include <signal.h>
> +#include <glib.h>
> +
> +/**
> + * SECTION:lsgpu
> + * @short_description: lsgpu
> + * @title: lsgpu
> + * @include: lsgpu.c
> + *
> + * # lsgpu
> + *
> + * The devices can be scanned and displayed using 'lsgpu' tool. Tool also
> + * displays properties and sysattrs (-p switch, means print detail) which
> + * can be used during filter implementation.
> + *
> + * Tool can also be used to try out filters.
> + * To select device use '-d' or '--device' argument like:
> + *
> + * |[<!-- language="plain" -->
> + * ./lsgpu -d 'pci:vendor=Intel'
> + * === Device filter list ===
> + * [ 0]: pci:vendor=Intel
> +
> + * === Testing device open ===
> + * subsystem   : pci
> + * chipset     : 1
> + * drm card    : /dev/dri/card0
> + * drm render  : /dev/dri/renderD128
> + * Device /dev/dri/card0 successfully opened
> + * Device /dev/dri/renderD128 successfully opened
> + * ]|
> + *
> + * Additionally lsgpu tries to open the card and render nodes to verify
> + * permissions. It also uses IGT variable search order:
> + * - use --device first (it overrides IGT_DEVICE and .igtrc Common::Device
> + *   settings)
> + * - use IGT_DEVICE enviroment variable if no --device are passed
> + * - use .igtrc Common::Device if no --device nor IGT_DEVICE are passed
> + */

note to self: add tools/* to the generated documentation

> +
> +enum {
> +	OPT_PRINT_DETAIL   = 'p',
> +	OPT_LIST_VENDORS   = 'v',
> +	OPT_LIST_FILTERS   = 'l',
> +	OPT_DEVICE         = 'd',
> +	OPT_HELP           = 'h'
> +};
> +
> +static bool g_show_vendors;
> +static bool g_list_filters;
> +static bool g_device;
> +static bool g_help;
> +static char *igt_rc_device;
> +
> +static const char *usage_str =
> +	"usage: lsgpu [options]\n\n"
> +	"Options:\n"
> +	"  -p, --print-details         Print devices with details\n"
> +	"  -v, --list-vendors          List recognized vendors\n"
> +	"  -l, --list-filter-types     List registered device filters types\n"
> +	"  -d, --device filter         Device filter, can be given multiple times\n"
> +	"  -h, --help                  Show this help message and exit\n";
> +
> +static void test_device_open(struct igt_device_card *card)
> +{
> +	int fd;
> +
> +	if (!card)
> +		return;
> +
> +	fd = drm_open_card(card);
> +	if (fd >= 0) {
> +		printf("Device %s successfully opened\n", card->card);
> +		close(fd);
> +	} else {
> +		if (strlen(card->card))
> +			printf("Cannot open card %s device\n", card->card);
> +		else
> +			printf("Cannot open card device, empty name\n");
> +	}
> +
> +	fd = drm_open_render(card);
> +	if (fd >= 0) {
> +		printf("Device %s successfully opened\n", card->render);
> +		close(fd);
> +	} else {
> +		if (strlen(card->render))
> +			printf("Cannot open render %s device\n", card->render);
> +		else
> +			printf("Cannot open render device, empty name\n");
> +	}
> +}
> +
> +static void print_card(struct igt_device_card *card)
> +{
> +	if (!card)
> +		return;
> +
> +	printf("subsystem   : %s\n", card->subsystem);
> +	printf("chipset     : %x\n", card->chipset);
> +	printf("drm card    : %s\n", card->card);
> +	printf("drm render  : %s\n", card->render);
> +}
> +
> +/* Partially copied from igt_core to simulate device selection order:
> + * 1. --device        (IGT_DEVICE and .igtrc Common::Device are ignored)
> + * 2. IGT_DEVICE env  (.igtrc Common::Device is ignored)
> + * 3. .igtrc          (overrides
> + */
> +static void common_init_config(void)
> +{
> +	char *key_file_env = NULL;
> +	char *key_file_loc = NULL;
> +	GError *error = NULL;
> +	GKeyFile *igt_key_file;
> +	int ret;
> +
> +	/* Filter count > 0, just skip .igtrc */
> +	if (igt_device_filter_count())
> +		return;
> +
> +	/* Determine igt config path */
> +	key_file_env = getenv("IGT_CONFIG_PATH");
> +	if (key_file_env) {
> +		key_file_loc = key_file_env;
> +	} else {
> +		key_file_loc = malloc(100);
> +		snprintf(key_file_loc, 100, "%s/.igtrc", g_get_home_dir());
> +	}
> +
> +	/* Load igt config file */
> +	igt_key_file = g_key_file_new();
> +	ret = g_key_file_load_from_file(igt_key_file, key_file_loc,
> +					G_KEY_FILE_NONE, &error);
> +	if (!ret) {
> +		g_error_free(error);
> +		g_key_file_free(igt_key_file);
> +		igt_key_file = NULL;
> +
> +		return;
> +	}
> +
> +	g_clear_error(&error);
> +
> +	if (!igt_rc_device)
> +		igt_rc_device =	g_key_file_get_string(igt_key_file, "Common",
> +						      "Device", &error);
> +
> +	if (igt_rc_device) {
> +		igt_device_filter_add(igt_rc_device);
> +		g_device = true;
> +	}
> +
> +	g_clear_error(&error);
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	static struct option long_options[] = {
> +		{"print-detail",      no_argument,       NULL, OPT_PRINT_DETAIL},
> +		{"list-vendors",      no_argument,       NULL, OPT_LIST_VENDORS},
> +		{"list-filter-types", no_argument,       NULL, OPT_LIST_FILTERS},
> +		{"device",            required_argument, NULL, OPT_DEVICE},
> +		{"help",              no_argument,       NULL, OPT_HELP},
> +		{0, 0, 0, 0}
> +	};
> +	int c, index = 0;
> +	const char *env;
> +	enum igt_devices_print_type printtype = IGT_PRINT_SIMPLE;
> +
> +	env = getenv("IGT_DEVICE");
> +	if (env) {
> +		igt_device_filter_add(env);
> +		g_device = true;
> +	}
> +
> +	while ((c = getopt_long(argc, argv, "pvld:h",
> +				long_options, &index)) != -1) {
> +		switch(c) {
> +
> +		case OPT_PRINT_DETAIL:
> +			printtype = IGT_PRINT_DETAIL;
> +			break;
> +		case OPT_LIST_VENDORS:
> +			g_show_vendors = true;
> +			break;
> +		case OPT_LIST_FILTERS:
> +			g_list_filters = true;
> +			break;
> +		case OPT_DEVICE:
> +			g_device = true;
> +			if (getenv("IGT_DEVICE") && igt_device_filter_count()) {
> +				unsetenv("IGT_DEVICE");
> +				igt_rc_device = NULL;
> +				igt_device_filter_free_all();
> +			}
> +			igt_device_filter_add(optarg);
> +			break;
> +		case OPT_HELP:
> +			g_help = true;
> +			break;
> +		}
> +	}
> +	common_init_config();
> +
> +	if (g_help) {
> +		printf("%s\n", usage_str);
> +		exit(0);
> +	}
> +
> +	if (g_show_vendors) {
> +		igt_devices_print_vendors();
> +		return 0;
> +	}
> +
> +	if (g_list_filters) {
> +		igt_device_print_filter_types();
> +		return 0;
> +	}
> +
> +	igt_devices_scan(false);
> +
> +	if (getenv("IGT_DEVICE")) {
> +		printf("Notice: Using IGT_DEVICE device settings [%s]\n",
> +		       getenv("IGT_DEVICE"));
> +	} else if (igt_rc_device) {
> +		printf("Notice: Using .igtrc device settings [%s]\n",
> +		       igt_rc_device);
> +	} else {
> +		if (igt_device_filter_count())
> +			printf("Notice: Using --device filters\n");
> +	}

wow, this mimicking igt_core made this really hard to follow...

note to self: rework both, and use igt_load_igtrc() once [Petri's patch]
lands.

[Petri's patch]: https://patchwork.freedesktop.org/patch/329762/

The only think that was a bit confusing for me is that there is no
(clear) way of getting rid of a filter set elsewhere, e.g.:

 $ export IGT_DEVICE=vgem:card=0

 $ build/tools/lsgpu
  Notice: Using IGT_DEVICE device settings [vgem:card=0]
  === Device filter list ===
  [ 0]: vgem:card=0

  === Testing device open ===
  [ 0]: No device found for filter

 $ build/tools/lsgpu --device
  build/tools/lsgpu: option '--device' requires an argument
  Notice: Using IGT_DEVICE device settings [vgem:card=0]
  === Device filter list ===
  [ 0]: vgem:card=0

  === Testing device open ===
  [ 0]: No device found for filter

 $ build/tools/lsgpu --device ""
  === Device filter list ===

  === Testing device open ===

 $ build/tools/lsgpu --device "*"
  (lsgpu:9275) igt_device_scan-WARNING: No filter with name [*]
  (lsgpu:9275) igt_device_scan-WARNING: Warning on condition !is_valid in function igt_device_filter_add, file ../lib/igt_device_scan.c:1274
  === Device filter list ===

  === Testing device open ===

 $ build/tools/lsgpu --device "any"
  (lsgpu:9296) igt_device_scan-WARNING: No filter with name [any]
  (lsgpu:9296) igt_device_scan-WARNING: Warning on condition !is_valid in function igt_device_filter_add, file ../lib/igt_device_scan.c:1274
  === Device filter list ===

  === Testing device open ===

But I don't think it will haunt many people and it clearly states what
is going on with the filters. We can fix the behavior for "" or "any"
later.

I'll open issues based on the two notes above when mergeing the series.

Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>

> +
> +	if (g_device) {
> +		int n = igt_device_filter_count();
> +		printf("=== Device filter list ===\n");
> +		for (int i = 0; i < n; i++) {
> +			printf("[%2d]: %s\n", i,
> +			       igt_device_filter_get(i));
> +		}
> +		printf("\n");
> +
> +		printf("=== Testing device open ===\n");
> +		for (int i = 0; i < n; i++) {
> +			struct igt_device_card card;
> +			const char *filter = igt_device_filter_get(i);
> +
> +			if (!igt_device_card_match(filter, &card)) {
> +				printf("[%2d]: No device found for filter\n\n",
> +				       i);
> +				continue;
> +			}
> +			printf("[%2d]: Device detail:\n", i);
> +			print_card(&card);
> +			test_device_open(&card);
> +			if (printtype == IGT_PRINT_DETAIL) {
> +				printf("\n");
> +				igt_devices_print(printtype);
> +			}
> +			printf("-------------------------------------------\n");
> +		}
> +
> +		return 0;
> +	}
> +
> +	igt_devices_print(printtype);
> +
> +	return 0;
> +}
> diff --git a/tools/meson.build b/tools/meson.build
> index 6e72b263..9b3a2a69 100644
> --- a/tools/meson.build
> +++ b/tools/meson.build
> @@ -36,6 +36,7 @@ tools_progs = [
>  	'intel_gem_info',
>  	'intel_gvtg_test',
>  	'dpcd_reg',
> +	'lsgpu',
>  ]
>  tool_deps = igt_deps
>  
> -- 
> 2.23.0
> 
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

  reply	other threads:[~2019-09-10 11:48 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-04 10:36 [igt-dev] [PATCH i-g-t v6 0/3] Add device selection methods Zbigniew Kempczyński
2019-09-04 10:36 ` [igt-dev] [PATCH i-g-t v6 1/3] Introduce device selection API Zbigniew Kempczyński
2019-09-04 10:37 ` [igt-dev] [PATCH i-g-t v6 2/3] Add device selection in IGT Zbigniew Kempczyński
2019-09-10 12:18   ` Arkadiusz Hiler
2019-09-04 10:37 ` [igt-dev] [PATCH i-g-t v6 3/3] Introduce device selection lsgpu tool Zbigniew Kempczyński
2019-09-10 11:48   ` Arkadiusz Hiler [this message]
2019-09-04 11:14 ` [igt-dev] ✓ Fi.CI.BAT: success for Add device selection methods (rev6) Patchwork
2019-09-04 13:12 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork
2019-09-09  8:23 ` [igt-dev] ✓ Fi.CI.IGT: success " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190910114854.hq6cdbeyzbs7h7in@ahiler-desk1.fi.intel.com \
    --to=arkadiusz.hiler@intel.com \
    --cc=daniel@ffwll.ch \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=petri.latvala@intel.com \
    --cc=zbigniew.kempczynski@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.