Skip to content

Instantly share code, notes, and snippets.

@Steve-Tech
Created December 11, 2024 00:58
Show Gist options
  • Save Steve-Tech/02d5231e94253472ea35c3c4d4d7e15f to your computer and use it in GitHub Desktop.
Save Steve-Tech/02d5231e94253472ea35c3c4d4d7e15f to your computer and use it in GitHub Desktop.
Get memory usage from i915 drivers
#include <assert.h>
#include <drm/drm.h>
#include <drm/i915_drm.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
// Copied from https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/intel/common/intel_gem.h
static inline int intel_ioctl(int fd, unsigned long request, void *arg) {
int ret;
do {
ret = ioctl(fd, request, arg);
} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
return ret;
}
// End Copy
// Copied from https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/intel/common/i915/intel_gem.h
static inline int intel_i915_query(int fd, uint64_t query_id, void *buffer, int32_t *buffer_len) {
struct drm_i915_query_item item = {
.query_id = query_id,
.length = *buffer_len,
.flags = 0,
.data_ptr = (uintptr_t)buffer,
};
struct drm_i915_query args = {
.num_items = 1,
.flags = 0,
.items_ptr = (uintptr_t)&item,
};
int ret = intel_ioctl(fd, DRM_IOCTL_I915_QUERY, &args);
if (ret != 0)
return -errno;
else if (item.length < 0)
return item.length;
*buffer_len = item.length;
return 0;
}
static inline void *intel_i915_query_alloc(int fd, uint64_t query_id, int32_t *query_length) {
if (query_length)
*query_length = 0;
int32_t length = 0;
int ret = intel_i915_query(fd, query_id, NULL, &length);
if (ret < 0)
return NULL;
void *data = calloc(1, length);
assert(data != NULL); /* This shouldn't happen in practice */
if (data == NULL)
return NULL;
ret = intel_i915_query(fd, query_id, data, &length);
assert(ret == 0); /* We should have caught the error above */
if (ret < 0) {
free(data);
return NULL;
}
if (query_length)
*query_length = length;
return data;
}
// End Copy
int main() {
int fd = open("/dev/dri/card0", O_WRONLY);
if (fd < 0) {
perror("Failed to open /dev/dri/card0");
return 1;
}
struct drm_i915_query_memory_regions *regions;
int32_t length = 0;
regions = intel_i915_query_alloc(fd, DRM_I915_QUERY_MEMORY_REGIONS, &length);
printf("Length of the blob: %d\n", length);
printf("Number of regions: %d\n", regions->num_regions);
for (size_t i = 0; i < regions->num_regions; i++) {
struct drm_i915_memory_region_info mr = regions->regions[i];
printf("Region %d\n", i);
printf("Class: %d\n", mr.region.memory_class);
printf("Instance: %d\n", mr.region.memory_instance);
printf("Probed size: %llu KB\n", mr.probed_size);
printf("Unallocated size: %llu KB\n", mr.unallocated_size);
}
close(fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment