@@ -27,7 +27,6 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/sysinfo.h>
#include <fcntl.h>
#include "i915/gem_create.h"
@@ -41,10 +40,42 @@
#include "intel_chipset.h"
#include "igt_collection.h"
#include "igt_device.h"
-#include "igt_aux.h"
#include "i915/intel_memory_region.h"
+#define i915_query_items(fd, items, n_items) do { \
+ igt_assert_eq(__i915_query_items(fd, items, n_items), 0); \
+ errno = 0; \
+ } while (0)
+#define i915_query_items_err(fd, items, n_items, err) do { \
+ igt_assert_eq(__i915_query_items(fd, items, n_items), -err); \
+ } while (0)
+
+static int
+__i915_query(int fd, struct drm_i915_query *q)
+{
+ if (igt_ioctl(fd, DRM_IOCTL_I915_QUERY, q))
+ return -errno;
+ return 0;
+}
+
+static int
+__i915_query_items(int fd, struct drm_i915_query_item *items, uint32_t n_items)
+{
+ struct drm_i915_query q = {
+ .num_items = n_items,
+ .items_ptr = to_user_pointer(items),
+ };
+ return __i915_query(fd, &q);
+}
+
+bool gem_has_query_support(int fd)
+{
+ struct drm_i915_query query = {};
+
+ return __i915_query(fd, &query) == 0;
+}
+
const char *get_memory_region_name(uint32_t region)
{
uint16_t class = MEMORY_TYPE_FROM_REGION(region);
@@ -59,76 +90,77 @@ const char *get_memory_region_name(uint32_t region)
* gem_get_batch_size:
* @fd: open i915 drm file descriptor
* @mem_region_type: used memory_region type
+ *
+ * With introduction of LMEM we observe different page sizes for those two
+ * memory regions. Without this helper funtion we may be prone to forget
+ * about setting proper page size.
*/
uint32_t gem_get_batch_size(int fd, uint8_t mem_region_type)
{
- /* temporary solution, to be erased later */
- (void) fd;
- (void) mem_region_type;
-
- return 4096;
+ return (mem_region_type == I915_MEMORY_CLASS_DEVICE) ? 65536 : 4096;
}
-static uint64_t __get_meminfo(const char *info, const char *tag)
+/**
+ * gem_get_query_memory_regions:
+ * @fd: open i915 drm file descriptor
+ *
+ * This function wraps query mechanism for memory regions.
+ *
+ * Returns: Filled struct with available memory regions.
+ */
+struct drm_i915_query_memory_regions *gem_get_query_memory_regions(int fd)
{
- const char *str;
- unsigned long val;
+ struct drm_i915_query_item item;
+ struct drm_i915_query_memory_regions *query_info;
- str = strstr(info, tag);
- if (str && sscanf(str + strlen(tag), " %lu", &val) == 1)
- return (uint64_t)val << 10;
+ memset(&item, 0, sizeof(item));
+ item.query_id = DRM_I915_QUERY_MEMORY_REGIONS;
+ i915_query_items(fd, &item, 1);
- igt_warn("Unrecognized /proc/meminfo field: '%s'\n", tag);
- return 0;
-}
+ query_info = calloc(1, item.length);
-static uint64_t __get_available_smem(int fd)
-{
- uint64_t retval;
- char *info;
- int proc_fd;
+ item.data_ptr = to_user_pointer(query_info);
+ i915_query_items(fd, &item, 1);
- intel_purge_vm_caches(fd);
+ return query_info;
+}
- proc_fd = open("/proc", O_RDONLY);
- info = igt_sysfs_get(proc_fd, "meminfo");
- close(proc_fd);
+/**
+ * gem_get_lmem_region_count:
+ * @fd: open i915 drm file descriptor
+ *
+ * Helper function to check how many lmem regions are available on device.
+ *
+ * Returns: Number of found lmem regions.
+ */
+uint8_t gem_get_lmem_region_count(int fd)
+{
+ struct drm_i915_query_memory_regions *query_info;
+ uint8_t num_regions;
+ uint8_t lmem_regions = 0;
- if (info) {
- retval = __get_meminfo(info, "MemAvailable:");
- } else {
- struct sysinfo sysinf;
+ query_info = gem_get_query_memory_regions(fd);
+ num_regions = query_info->num_regions;
- igt_assert(sysinfo(&sysinf) == 0);
- retval = sysinf.freeram;
- retval *= sysinf.mem_unit;
+ for (int i = 0; i < num_regions; i++) {
+ if (query_info->regions[i].region.memory_class == I915_MEMORY_CLASS_DEVICE)
+ lmem_regions += 1;
}
- return retval;
+ return lmem_regions;
}
/**
- * gem_get_query_memory_regions:
+ * gem_has_lmem:
* @fd: open i915 drm file descriptor
*
- * This function is prepared as a wrapper for the upcoming memory
- * regions implementation.
+ * Helper function to check if lmem is available on device.
*
- * Returns: Filled struct with available memory regions.
+ * Returns: True if at least one lmem region was found.
*/
-struct drm_i915_query_memory_regions *gem_get_query_memory_regions(int fd)
+bool gem_has_lmem(int fd)
{
- struct drm_i915_query_memory_regions *query_info;
-
- query_info = calloc(1, sizeof(struct drm_i915_query_memory_regions)
- + sizeof(struct drm_i915_memory_region_info));
-
- query_info->num_regions = 1;
- query_info->regions[0].region.memory_class = I915_MEMORY_CLASS_SYSTEM;
- query_info->regions[0].probed_size = intel_get_total_ram_mb() << 20;
- query_info->regions[0].unallocated_size = __get_available_smem(fd);
-
- return query_info;
+ return gem_get_lmem_region_count(fd) > 0;
}
/* A version of gem_create_in_memory_region_list which can be allowed to
@@ -39,11 +39,16 @@
#define REGION_SMEM INTEL_MEMORY_REGION_ID(I915_MEMORY_CLASS_SYSTEM, 0)
+bool gem_has_query_support(int fd);
+
const char *get_memory_region_name(uint32_t region);
uint32_t gem_get_batch_size(int fd, uint8_t mem_region_type);
struct drm_i915_query_memory_regions *gem_get_query_memory_regions(int fd);
+uint8_t gem_get_lmem_region_count(int fd);
+
+bool gem_has_lmem(int fd);
int __gem_create_in_memory_region_list(int fd, uint32_t *handle, uint64_t size,
struct drm_i915_gem_memory_class_instance *mem_regions,