xf86drm: Allocate drmDevicePtr's on stack

Currently we dynamically allocate 16 pointers and reallocate more as
needed.

Instead, allocate the maximum number (256) on stack - the number is
small enough and is unlikely to change in the foreseeable future.

This allows us to simplify the error handling and even shed a few bytes
off the final binary.

v2:
 - add a define & description behind the magic 256
 - report error to strerr and skip when over 256 device nodes

Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
Tested-by: Robert Foss <robert.foss@collabora.com> (v1)
Reviewed-by: Robert Foss <robert.foss@collabora.com>
Reviewed-by: Eric Engestrom <eric@engestrom.ch> (v1)
main
Emil Velikov 2018-05-15 16:32:10 +01:00 committed by Emil Velikov
parent f808fee90d
commit 95b262f019
1 changed files with 23 additions and 56 deletions

View File

@ -3766,6 +3766,13 @@ drm_device_has_rdev(drmDevicePtr device, dev_t find_rdev)
return false; return false;
} }
/*
* The kernel drm core has a number of places that assume maximum of
* 3x64 devices nodes. That's 64 for each of primary, control and
* render nodes. Rounded it up to 256 for simplicity.
*/
#define MAX_DRM_NODES 256
/** /**
* Get information about the opened drm device * Get information about the opened drm device
* *
@ -3846,7 +3853,7 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
return 0; return 0;
#else #else
drmDevicePtr *local_devices; drmDevicePtr local_devices[MAX_DRM_NODES];
drmDevicePtr d; drmDevicePtr d;
DIR *sysdir; DIR *sysdir;
struct dirent *dent; struct dirent *dent;
@ -3854,7 +3861,6 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
int subsystem_type; int subsystem_type;
int maj, min; int maj, min;
int ret, i, node_count; int ret, i, node_count;
int max_count = 16;
dev_t find_rdev; dev_t find_rdev;
if (drm_device_validate_flags(flags)) if (drm_device_validate_flags(flags))
@ -3877,15 +3883,9 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
if (subsystem_type < 0) if (subsystem_type < 0)
return subsystem_type; return subsystem_type;
local_devices = calloc(max_count, sizeof(drmDevicePtr));
if (local_devices == NULL)
return -ENOMEM;
sysdir = opendir(DRM_DIR_NAME); sysdir = opendir(DRM_DIR_NAME);
if (!sysdir) { if (!sysdir)
ret = -errno; return -errno;
goto free_locals;
}
i = 0; i = 0;
while ((dent = readdir(sysdir))) { while ((dent = readdir(sysdir))) {
@ -3893,16 +3893,12 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
if (ret) if (ret)
continue; continue;
if (i >= max_count) { if (i >= MAX_DRM_NODES) {
drmDevicePtr *temp; fprintf(stderr, "More than %d drm nodes detected. "
"Please report a bug - that should not happen.\n"
max_count += 16; "Skipping extra nodes\n", MAX_DRM_NODES);
temp = realloc(local_devices, max_count * sizeof(drmDevicePtr)); break;
if (!temp)
goto free_devices;
local_devices = temp;
} }
local_devices[i] = d; local_devices[i] = d;
i++; i++;
} }
@ -3921,18 +3917,9 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
} }
closedir(sysdir); closedir(sysdir);
free(local_devices);
if (*device == NULL) if (*device == NULL)
return -ENODEV; return -ENODEV;
return 0; return 0;
free_devices:
drmFreeDevices(local_devices, i);
closedir(sysdir);
free_locals:
free(local_devices);
return ret;
#endif #endif
} }
@ -3968,25 +3955,18 @@ int drmGetDevice(int fd, drmDevicePtr *device)
*/ */
int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices) int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices)
{ {
drmDevicePtr *local_devices; drmDevicePtr local_devices[MAX_DRM_NODES];
drmDevicePtr device; drmDevicePtr device;
DIR *sysdir; DIR *sysdir;
struct dirent *dent; struct dirent *dent;
int ret, i, node_count, device_count; int ret, i, node_count, device_count;
int max_count = 16;
if (drm_device_validate_flags(flags)) if (drm_device_validate_flags(flags))
return -EINVAL; return -EINVAL;
local_devices = calloc(max_count, sizeof(drmDevicePtr));
if (local_devices == NULL)
return -ENOMEM;
sysdir = opendir(DRM_DIR_NAME); sysdir = opendir(DRM_DIR_NAME);
if (!sysdir) { if (!sysdir)
ret = -errno; return -errno;
goto free_locals;
}
i = 0; i = 0;
while ((dent = readdir(sysdir))) { while ((dent = readdir(sysdir))) {
@ -3994,16 +3974,12 @@ int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices)
if (ret) if (ret)
continue; continue;
if (i >= max_count) { if (i >= MAX_DRM_NODES) {
drmDevicePtr *temp; fprintf(stderr, "More than %d drm nodes detected. "
"Please report a bug - that should not happen.\n"
max_count += 16; "Skipping extra nodes\n", MAX_DRM_NODES);
temp = realloc(local_devices, max_count * sizeof(drmDevicePtr)); break;
if (!temp)
goto free_devices;
local_devices = temp;
} }
local_devices[i] = device; local_devices[i] = device;
i++; i++;
} }
@ -4025,16 +4001,7 @@ int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices)
} }
closedir(sysdir); closedir(sysdir);
free(local_devices);
return device_count; return device_count;
free_devices:
drmFreeDevices(local_devices, i);
closedir(sysdir);
free_locals:
free(local_devices);
return ret;
} }
/** /**