drm: drmGetDevice return correct device on multi GPU setups
Currently drmGetDevice always returns the first device it finds under /dev/dri/. Move the target device to the start of the list during iteration. This way during deduplication it'll preserve its place and will be returned to the user. v2: Keep the memory leak separate. v3: Move the drmFoldDuplicatedDevices description Signed-off-by: Qiang Yu <Qiang.Yu@amd.com> [Emil Velikov: move drmFoldDuplicatedDevices description, add changelog, reword commit message] Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>main
parent
5d83081948
commit
3c20893daa
20
xf86drm.c
20
xf86drm.c
|
@ -3050,6 +3050,11 @@ free_device:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Consider devices located on the same bus as duplicate and fold the respective
|
||||||
|
* entries into a single one.
|
||||||
|
*
|
||||||
|
* Note: this leaves "gaps" in the array, while preserving the length.
|
||||||
|
*/
|
||||||
static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count)
|
static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count)
|
||||||
{
|
{
|
||||||
int node_type, i, j;
|
int node_type, i, j;
|
||||||
|
@ -3088,6 +3093,7 @@ int drmGetDevice(int fd, drmDevicePtr *device)
|
||||||
int maj, min;
|
int maj, min;
|
||||||
int ret, i, node_count;
|
int ret, i, node_count;
|
||||||
int max_count = 16;
|
int max_count = 16;
|
||||||
|
dev_t find_rdev;
|
||||||
|
|
||||||
if (fd == -1 || device == NULL)
|
if (fd == -1 || device == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -3095,6 +3101,7 @@ int drmGetDevice(int fd, drmDevicePtr *device)
|
||||||
if (fstat(fd, &sbuf))
|
if (fstat(fd, &sbuf))
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
|
find_rdev = sbuf.st_rdev;
|
||||||
maj = major(sbuf.st_rdev);
|
maj = major(sbuf.st_rdev);
|
||||||
min = minor(sbuf.st_rdev);
|
min = minor(sbuf.st_rdev);
|
||||||
|
|
||||||
|
@ -3155,17 +3162,21 @@ int drmGetDevice(int fd, drmDevicePtr *device)
|
||||||
local_devices = temp;
|
local_devices = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
local_devices[i] = d;
|
/* store target at local_devices[0] for ease to use below */
|
||||||
|
if (find_rdev == sbuf.st_rdev && i) {
|
||||||
|
local_devices[i] = local_devices[0];
|
||||||
|
local_devices[0] = d;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
local_devices[i] = d;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
node_count = i;
|
node_count = i;
|
||||||
|
|
||||||
/* Fold nodes into a single device if they share the same bus info */
|
|
||||||
drmFoldDuplicatedDevices(local_devices, node_count);
|
drmFoldDuplicatedDevices(local_devices, node_count);
|
||||||
|
|
||||||
*device = local_devices[0];
|
*device = local_devices[0];
|
||||||
for (i = 1; i < node_count && local_devices[i]; i++)
|
drmFreeDevices(&local_devices[1], node_count - 1);
|
||||||
drmFreeDevice(&local_devices[i]);
|
|
||||||
|
|
||||||
closedir(sysdir);
|
closedir(sysdir);
|
||||||
free(local_devices);
|
free(local_devices);
|
||||||
|
@ -3264,7 +3275,6 @@ int drmGetDevices(drmDevicePtr devices[], int max_devices)
|
||||||
}
|
}
|
||||||
node_count = i;
|
node_count = i;
|
||||||
|
|
||||||
/* Fold nodes into a single device if they share the same bus info */
|
|
||||||
drmFoldDuplicatedDevices(local_devices, node_count);
|
drmFoldDuplicatedDevices(local_devices, node_count);
|
||||||
|
|
||||||
device_count = 0;
|
device_count = 0;
|
||||||
|
|
Loading…
Reference in New Issue