[PATCH libdrm] xf86drm: Parse the separate files to retrieve the vendor/device info

Mauro Santos registo.mailling at gmail.com
Tue Nov 8 15:27:19 UTC 2016


On 08-11-2016 15:00, Emil Velikov wrote:
> On 8 November 2016 at 13:38, Mauro Santos <registo.mailling at gmail.com> wrote:
>> On 08-11-2016 11:06, Emil Velikov wrote:
>>> On 1 November 2016 at 18:47, Mauro Santos <registo.mailling at gmail.com> wrote:
>>>> On 01-11-2016 18:13, Emil Velikov wrote:
>>>>> From: Emil Velikov <emil.velikov at collabora.com>
>>>>>
>>>>> Parsing config sysfs file wakes up the device. The latter of which may
>>>>> be slow and isn't required to begin with.
>>>>>
>>>>> Reading through config is/was required since the revision is not
>>>>> available by other means, although with a kernel patch in the way we can
>>>>> 'cheat' temporarily.
>>>>>
>>>>> That should be fine, since no open-source project has ever used the
>>>>> value.
>>>>>
>>>>> Cc: Michel Dänzer <michel.daenzer at amd.com>
>>>>> Cc: Mauro Santos <registo.mailling at gmail.com>
>>>>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98502
>>>>> Signed-off-by: Emil Velikov <emil.velikov at collabora.com>
>>>>> ---
>>>>> Mauro can you apply this against libdrm and rebuild it. You do _not_
>>>>> need to rebuild mesa afterwords.
>>>>>
>>>>> Thanks
>>>>> ---
>>>>>  xf86drm.c | 50 +++++++++++++++++++++++++++++++++++---------------
>>>>>  1 file changed, 35 insertions(+), 15 deletions(-)
>>>>>
>>>>> diff --git a/xf86drm.c b/xf86drm.c
>>>>> index 52add5e..5a5100c 100644
>>>>> --- a/xf86drm.c
>>>>> +++ b/xf86drm.c
>>>>> @@ -2950,25 +2950,45 @@ static int drmParsePciDeviceInfo(const char *d_name,
>>>>>                                   drmPciDeviceInfoPtr device)
>>>>>  {
>>>>>  #ifdef __linux__
>>>>> +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
>>>>> +    static const char *attrs[] = {
>>>>> +      "revision", /* XXX: make sure it's always first, see note below */
>>>>> +      "vendor",
>>>>> +      "device",
>>>>> +      "subsystem_vendor",
>>>>> +      "subsystem_device",
>>>>> +    };
>>>>>      char path[PATH_MAX + 1];
>>>>> -    unsigned char config[64];
>>>>> -    int fd, ret;
>>>>> +    unsigned int data[ARRAY_SIZE(attrs)];
>>>>> +    FILE *fp;
>>>>> +    int ret;
>>>>>
>>>>> -    snprintf(path, PATH_MAX, "/sys/class/drm/%s/device/config", d_name);
>>>>> -    fd = open(path, O_RDONLY);
>>>>> -    if (fd < 0)
>>>>> -        return -errno;
>>>>> +    for (unsigned i = 0; i < ARRAY_SIZE(attrs); i++) {
>>>>> +        snprintf(path, PATH_MAX, "/sys/class/drm/%s/device/%s",
>>>>> +                 d_name, attrs[i]);
>>>>> +        fp = fopen(path, "r");
>>>>> +        if (!fp) {
>>>>> +            /* Note: First we check the revision, since older kernels
>>>>> +             * may not have it. Default to zero in such cases. */
>>>>> +            if (i == 0) {
>>>>> +                data[i] = 0;
>>>>> +                continue;
>>>>> +            }
>>>>> +            return -errno;
>>>>> +        }
>>>>>
>>>>> -    ret = read(fd, config, sizeof(config));
>>>>> -    close(fd);
>>>>> -    if (ret < 0)
>>>>> -        return -errno;
>>>>> +        ret = fscanf(fp, "%x", &data[i]);
>>>>> +        fclose(fp);
>>>>> +        if (ret != 1)
>>>>> +            return -errno;
>>>>> +
>>>>> +    }
>>>>>
>>>>> -    device->vendor_id = config[0] | (config[1] << 8);
>>>>> -    device->device_id = config[2] | (config[3] << 8);
>>>>> -    device->revision_id = config[8];
>>>>> -    device->subvendor_id = config[44] | (config[45] << 8);
>>>>> -    device->subdevice_id = config[46] | (config[47] << 8);
>>>>> +    device->revision_id = data[0] & 0xff;
>>>>> +    device->vendor_id = data[1] & 0xffff;
>>>>> +    device->device_id = data[2] & 0xffff;
>>>>> +    device->subvendor_id = data[3] & 0xffff;
>>>>> +    device->subdevice_id = data[4] & 0xffff;
>>>>>
>>>>>      return 0;
>>>>>  #else
>>>>>
>>>>
>>>> I have applied this against libdrm 2.4.71 and I don't see any delays
>>>> when starting firefox/chromium/thunderbird/glxgears.
>>>>
>>>> There is also no indication in dmesg that the dGPU is being
>>>> reinitialized when starting the programs where I've detected the problem.
>>>>
>>> Thanks Mauro. Can you give this a try alongside the kernel fix [1] ?
>>> I'd love to get the latter merged soon(ish).
>>> Independent of the kernel side, I might need to go another way for
>>> libdrm/mesa so I'll CC you on future patches.
>>>
>>> Your help is greatly appreciated !
>>>
>>> Thanks
>>> Emil
>>>
>>> [1] http://patchwork.ozlabs.org/patch/689975/
>>>
>>
>> I have applied the patch on top of kernel 4.8.6 and I'm using the libdrm
>> with the patch you sent me previously.
>>
>> With this patch things still seem work fine, I don't see any of the
>> problems I've seen before, but I don't know how to confirm that the
>> value from sysfs is now being used by libdrm instead of defaulting to zero.
>>
> Grr my bad. $libdrm_builddir/tests/drmdevice should do it. You might
> need to explicitly build it (cd tests && make drmdevice)
> 

When running drmdevice as my user it still wakes up the dGPU. The
correct device revisions are being reported by I suppose that is not
being read from sysfs.

sudo dmesg -C && dmesg -w & ./drmdevice

device[0]
	available_nodes 0007
	nodes
		nodes[0] /dev/dri/card1
		nodes[1] /dev/dri/controlD65
		nodes[2] /dev/dri/renderD129
	bustype 0000
	businfo
		pci
			domain	0000
			bus	03
			dev	00
			func	0
	deviceinfo
		pci
			vendor_id	1002
			device_id	6600
			subvendor_id	17aa
			subdevice_id	5049
			revision_id	81

Opening device 0 node /dev/dri/card1
[ 7155.613212] [drm] probing gen 2 caps for device 8086:9d18 = 9724043/e
[ 7155.613218] [drm] enabling PCIE gen 3 link speeds, disable with
radeon.pcie_gen2=0
[ 7157.006460] [drm] PCIE GART of 2048M enabled (table at
0x00000000001D6000).
[ 7157.006603] radeon 0000:03:00.0: WB enabled
[ 7157.006607] radeon 0000:03:00.0: fence driver on ring 0 use gpu addr
0x0000000080000c00 and cpu addr 0xffff88042bb1fc00
[ 7157.006610] radeon 0000:03:00.0: fence driver on ring 1 use gpu addr
0x0000000080000c04 and cpu addr 0xffff88042bb1fc04
[ 7157.006612] radeon 0000:03:00.0: fence driver on ring 2 use gpu addr
0x0000000080000c08 and cpu addr 0xffff88042bb1fc08
[ 7157.006614] radeon 0000:03:00.0: fence driver on ring 3 use gpu addr
0x0000000080000c0c and cpu addr 0xffff88042bb1fc0c
[ 7157.006616] radeon 0000:03:00.0: fence driver on ring 4 use gpu addr
0x0000000080000c10 and cpu addr 0xffff88042bb1fc10
[ 7157.007411] radeon 0000:03:00.0: fence driver on ring 5 use gpu addr
0x0000000000075a18 and cpu addr 0xffffc90002235a18
[ 7157.109456] radeon 0000:03:00.0: failed VCE resume (-110).
[ 7157.340129] [drm] ring test on 0 succeeded in 1 usecs
[ 7157.340136] [drm] ring test on 1 succeeded in 1 usecs
[ 7157.340142] [drm] ring test on 2 succeeded in 1 usecs
[ 7157.340153] [drm] ring test on 3 succeeded in 4 usecs
[ 7157.340163] [drm] ring test on 4 succeeded in 4 usecs
[ 7157.517337] [drm] ring test on 5 succeeded in 2 usecs
[ 7157.517344] [drm] UVD initialized successfully.
[ 7157.517392] [drm] ib test on ring 0 succeeded in 0 usecs
[ 7157.517431] [drm] ib test on ring 1 succeeded in 0 usecs
[ 7157.517474] [drm] ib test on ring 2 succeeded in 0 usecs
[ 7157.517510] [drm] ib test on ring 3 succeeded in 0 usecs
[ 7157.517546] [drm] ib test on ring 4 succeeded in 0 usecs
[ 7158.169561] [drm] ib test on ring 5 succeeded
device[0]
	available_nodes 0007
	nodes
		nodes[0] /dev/dri/card1
		nodes[1] /dev/dri/controlD65
		nodes[2] /dev/dri/renderD129
	bustype 0000
	businfo
		pci
			domain	0000
			bus	03
			dev	00
			func	0
	deviceinfo
		pci
			vendor_id	1002
			device_id	6600
			subvendor_id	17aa
			subdevice_id	5049
			revision_id	81

Opening device 0 node /dev/dri/controlD65
Failed - Permission denied (13)
Opening device 0 node /dev/dri/renderD129
device[0]
	available_nodes 0007
	nodes
		nodes[0] /dev/dri/card1
		nodes[1] /dev/dri/controlD65
		nodes[2] /dev/dri/renderD129
	bustype 0000
	businfo
		pci
			domain	0000
			bus	03
			dev	00
			func	0
	deviceinfo
		pci
			vendor_id	1002
			device_id	6600
			subvendor_id	17aa
			subdevice_id	5049
			revision_id	81

device[1]
	available_nodes 0007
	nodes
		nodes[0] /dev/dri/card0
		nodes[1] /dev/dri/controlD64
		nodes[2] /dev/dri/renderD128
	bustype 0000
	businfo
		pci
			domain	0000
			bus	00
			dev	02
			func	0
	deviceinfo
		pci
			vendor_id	8086
			device_id	1916
			subvendor_id	17aa
			subdevice_id	5049
			revision_id	07

Opening device 1 node /dev/dri/card0
device[1]
	available_nodes 0007
	nodes
		nodes[0] /dev/dri/card0
		nodes[1] /dev/dri/controlD64
		nodes[2] /dev/dri/renderD128
	bustype 0000
	businfo
		pci
			domain	0000
			bus	00
			dev	02
			func	0
	deviceinfo
		pci
			vendor_id	8086
			device_id	1916
			subvendor_id	17aa
			subdevice_id	5049
			revision_id	07

Opening device 1 node /dev/dri/controlD64
Failed - Permission denied (13)
Opening device 1 node /dev/dri/renderD128
device[1]
	available_nodes 0007
	nodes
		nodes[0] /dev/dri/card0
		nodes[1] /dev/dri/controlD64
		nodes[2] /dev/dri/renderD128
	bustype 0000
	businfo
		pci
			domain	0000
			bus	00
			dev	02
			func	0
	deviceinfo
		pci
			vendor_id	8086
			device_id	1916
			subvendor_id	17aa
			subdevice_id	5049
			revision_id	07




>> The values in /sys/class/drm/card{0,1}/device/revision match what is
>> reported by lspci for the iGPU and dGPU.
>> I don't know if it's related but the revision file in
>> /sys/class/pci_bus/0000\:03/device/ does show 0xf1 for both GPUs, which
>> is different from what is shown in /sys/class/drm/card{0,1}/device/revision.
>>
> That's perfect, thanks.
> 
> 0000:03 is (in all likelihood) is the PCI bridge. You can check with
> the device uevent/PCI_SLOT_NAME and cross reference with lspci.
> 

This is right on the money, uevent/PCI_SLOT_NAME does point to the PCI
bridge.

> 
> Emil
> 


-- 
Mauro Santos


More information about the dri-devel mailing list