Re: [igt-dev] [PATCH i-g-t v5 1/2] Introduce device selection API

Katarzyna Dec
2019-08-28T06:10:43Z

On Fri, Aug 23, 2019 at 09:03:50AM +0200, Zbigniew Kempczyński wrote:
> Change adds device selection based on scanning drm subsystem
> using udev library.
>
> Tool 'lsgpu' for device scanning and selection was added.
>
> 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>
> ---
> .../igt-gpu-tools/igt-gpu-tools-docs.xml | 1 +
> lib/Makefile.sources | 2 +
> lib/igt_device_scan.c | 1380 +++++++++++++++++
> lib/igt_device_scan.h | 74 +
> lib/meson.build | 1 +
> tools/Makefile.sources | 1 +
> tools/lsgpu.c | 261 ++++
> tools/meson.build | 1 +
> 8 files changed, 1721 insertions(+)
> create mode 100644 lib/igt_device_scan.c
> create mode 100644 lib/igt_device_scan.h
> create mode 100644 tools/lsgpu.c
>
> diff --git a/docs/reference/igt-gpu-tools/igt-gpu-tools-docs.xml b/docs/reference/igt-gpu-tools/igt-gpu-tools-docs.xml
> index ac83272f..4b3c38af 100644
> --- a/docs/reference/igt-gpu-tools/igt-gpu-tools-docs.xml
> +++ b/docs/reference/igt-gpu-tools/igt-gpu-tools-docs.xml
> @@ -23,6 +23,7 @@
> <xi:include href="xml/igt_core.xml"/>
> <xi:include href="xml/igt_debugfs.xml"/>
> <xi:include href="xml/igt_device.xml"/>
> + <xi:include href="xml/igt_device_scan.xml"/>
> <xi:include href="xml/igt_draw.xml"/>
> <xi:include href="xml/igt_dummyload.xml"/>
> <xi:include href="xml/igt_fb.xml"/>
> diff --git a/lib/Makefile.sources b/lib/Makefile.sources
> index cf094ab8..a9e9557a 100644
> --- a/lib/Makefile.sources
> +++ b/lib/Makefile.sources
> @@ -25,6 +25,8 @@ lib_source_list = \
> igt_debugfs.h \
> igt_device.c \
> igt_device.h \
> + igt_device_scan.c \
> + igt_device_scan.h \
> igt_aux.c \
> igt_aux.h \
> igt_color_encoding.c \
> diff --git a/lib/igt_device_scan.c b/lib/igt_device_scan.c
> new file mode 100644
> index 00000000..8de790d9
> --- /dev/null
> +++ b/lib/igt_device_scan.c
> @@ -0,0 +1,1380 @@
> +/*
> + * 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.h"
> +#include "igt_sysfs.h"
> +#include "igt_device.h"
> +#include "igt_device_scan.h"
> +#include <glib.h>
> +#include <libudev.h>
> +#include <linux/limits.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
> +#include <dirent.h>
> +#include <fcntl.h>
> +
> +/**
> + * SECTION:igt_device_scan
> + * @short_description: Device scanning and selection
> + * @title: Device selection
> + * @include: igt.h
> + *
> + * # Device scanning
> + *
> + * Device scanning iterates over drm subsystem using udev library
> + * to acquire drm devices.
> + * For each drm device we also get and store its parent in a device array
> + * to allow device selection in more contextual way.
> + *
> + * Parent devices are bus devices (like pci, platform, etc.) and contain a lot
> + * of usable information comparing to drm device.
> + *
> + * Udev keeps properties and sysattrs for the device as a list what is not
> + * convinient for key/value searching. So udev device properties and sysattrs
> + * are rewritten to internal hash tables in igt_device structure.
> + *
> + * # Filters
> + *
> + * Device selection can be done using filters. Filters allow sophisticated
> + * device matching and selection. Previously mentioned properties and sysattrs
> + * collected in igt_device hash tables simplify writing filter implementation.
> + *
> + * Direct device selection filter
> + * is special filter and it is checked first. Then contextual filter is chosen
> + * depending on filter name.
> + *
> + * Direct device selection filter must be:
> + *
> + * |[
> + * subsystem:/sys
> + * ]|
> + *
> + * So, when user passes filter which looks like follows:
> + * |[
> + * - drm:/sys/devices/pci0000:00/0000:00:02.0/drm/card0
> + * - pci:/sys/devices/pci0000:00/0000:00:02.0
> + * - platform:/sys/devices/platform/vgem
> + * ]|
> + *
> + * device from array which has subsystem and sys path will be returned.
> + *
> + * When /sys is not specified after colon contextual filters are taken
> + * into account. Drm device occurs in the system when appropriate module
> + * is loaded and device is detected (or exposed for platform devices). Loading
> + * drivers in different order can be problematic from CI point of view, where
> + * expectation is to get same device especially when multiple gpu devices
> + * exists in the system. For such devices its parent location on pci bus
> + * is constant and allows appropriate device selection using for example
> + * vendor / device ids.
> + *
> + * For tests which opens more than one device device filter collection API
> + * can be used. You can add a filter to the array using igt_device_filter_add(),
> + * get the nth filter stored using igt_device_filter_get() and get
> + * #igt_device_card using igt_device_card_match() with that filter.
> + *
> + * Implemented filters:
> + *
> + * - drm: get drm /dev/dri/... device directly
> + *
> + * |[
> + * drm:/dev/dri/...
> + * ]|
> + *
> + * - pci: select device using pci properties
> + * |[
> + * pci:[vendor=%04x/name][,device=%04x][,card=%d]
> + * ]|
> + *
> + * Filter allows device selection using vendor (hex or name), device id
> + * (hex) and nth-card from all matches. For example if there're 4 pci
> + * cards installed (let two cards have 1234 and other two 1235 device id,
> + * all of them of vendor Intel) you can select one using:
> + *
> + * |[
> + * pci:vendor=Intel,device=1234,card=0
> + * ]|
> + *
> + * or
> + *
> + * |[
> + * pci:vendor=8086,device=1234,card=0
> + * ]|
> + *
> + * This takes first device with 1234 id for Intel vendor (8086).
> + *
> + * |[
> + * pci:vendor=Intel,device=1234,card=1
> + * ]|
> + *
> + * or
> + *
> + * |[
> + * pci:vendor=8086,device=1234,card=1
> + * ]|
> + *
> + * It selects second one.
> + *
> + * As order on pci bus doesn't change (unless you'll add new device or
> + * reorder existing one) device selection using this filter will always
> + * return you same device regardless module loading time.
> + *
> + * - vgem: select virtual gem device
> + *
> + * |[
> + * vgem:[card=%d]
> + * ]|
> + *
> + * For example:
> + *
> + * |[
> + * vgem:
> + * vgem:card=0
> + * ]|
> + *
> + * Both selects first vgem device (no idea if more than one device will
> + * be visible, if yes use card= argument to point right one).
> + *
> + * - vkms: select virtual kms device
> + *
> + * |[
> + * vkms:[card=%d]
> + * ]|
> + *
> + * For example:
> + *
> + * |[
> + * vkms:
> + * vkms:card=0
> + * ]|
> + *
> + * Both selects first vkms device. Same as for vgem I assume more than
> + * one device can appear in the future.
> + *
> + * - vc4: select VC4 device
> + *
> + * |[
> + * vc4:[card=%d]
> + * ]|
> + *
> + * For example:
> + *
> + * |[
> + * vc4:
> + * vc4:card=0
> + * ]|
> + *
> + * Both selects first VC4 device. At the moment Rasperry PI has only
> + * one gpu, but filter is ready if there will be more.
> + *
> + * # 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:
> + *
> + * |[
> + * ./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
> + */
I looked thought code in all patch and it generally looks good.
I have a question about lsgpu usage.
'-p' prints all devices, but there is not information in help about that
'-d' used without '-p' filters and prints details about particular device
Mixing '-p' and '-d' has no affect - we still see all devices, not filtered
ones. Is it by desing?

Kasia :)