buildroot/package/libdrm/0003-Add-sync_file_info-and...

149 lines
3.8 KiB
Diff

From a3188f2de5c1c45d4f9ec0a30ee3d30e4c82d6ea Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Mon, 9 Mar 2020 14:52:17 +0000
Subject: [PATCH 3/3] Add sync_file_info and sync_get_fence_info
For pre-4.7 kernels, sync_file_info calls the SYNC_IOC_FENCE_INFO ioctl,
and converts the data to SYNC_IOC_FILE_INFO form. For newer kernels,
sync_file_info returns data from the SYNC_IOC_FILE_INFO ioctl.
This patch depends on patch "Add sync_fence_info and sync_pt_info",
which added legacy sync info support, using the structure and ioctl
definitions at the top of the patch, as well as the sync_pt_info
function.
---
libsync.h | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/libsync.h b/libsync.h
index 44f7330d..54acb6fa 100644
--- a/libsync.h
+++ b/libsync.h
@@ -351,6 +351,123 @@ static inline void sync_fence_info_free(struct sync_fence_info_data *info)
{
free(info);
}
+
+static inline struct sync_fence_info *sync_get_fence_info(
+ struct sync_file_info *file_info)
+{
+ return (struct sync_fence_info *)(uintptr_t)file_info->sync_fence_info;
+}
+
+static inline struct sync_file_info *file_info_from_info_data(
+ struct sync_fence_info_data *info)
+{
+ struct sync_pt_info *pt_info = NULL;
+ uint32_t num_fences = 0;
+ struct sync_file_info *file_info;
+ struct sync_fence_info *fence_info;
+ uint32_t i;
+
+ while ((pt_info = sync_pt_info(info, pt_info)) != NULL)
+ num_fences++;
+
+ file_info = calloc(1, sizeof(*file_info) + num_fences *
+ sizeof(*fence_info));
+ if (!file_info)
+ return NULL;
+
+ strncpy(file_info->name, info->name, sizeof(file_info->name));
+ file_info->status = info->status;
+ file_info->num_fences = num_fences;
+ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1);
+
+ fence_info = sync_get_fence_info(file_info);
+ for (i = 0; i < num_fences; i++) {
+ pt_info = sync_pt_info(info, pt_info);
+ assert(pt_info);
+
+ strncpy(fence_info->obj_name, pt_info->obj_name,
+ sizeof(fence_info->obj_name));
+ strncpy(fence_info->driver_name, pt_info->driver_name,
+ sizeof(fence_info->driver_name));
+ fence_info->status = pt_info->status;
+ fence_info->timestamp_ns = pt_info->timestamp_ns;
+
+ fence_info++;
+ }
+
+ return file_info;
+}
+
+static inline struct sync_file_info *sync_legacy_file_info(int fd)
+{
+ const uint32_t len = 4096;
+ struct sync_fence_info_data *info = malloc(len);
+ struct sync_file_info *file_info;
+ int ret;
+
+ if (!info)
+ return NULL;
+
+ info->len = len;
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0) {
+ free(info);
+ return NULL;
+ }
+
+ file_info = file_info_from_info_data(info);
+
+ free(info);
+
+ return file_info;
+}
+
+static inline void sync_file_info_free(struct sync_file_info *file_info)
+{
+ free(file_info);
+}
+
+static inline struct sync_file_info *sync_file_info(int fd)
+{
+ struct sync_file_info initial_info = {""};
+ struct sync_file_info *file_info;
+ int ret;
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_FILE_INFO, &initial_info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0) {
+ if (errno == ENOTTY)
+ return sync_legacy_file_info(fd);
+ else
+ return NULL;
+ }
+
+ file_info = calloc(1, sizeof(*file_info) + initial_info.num_fences *
+ sizeof(struct sync_fence_info));
+ if (!file_info)
+ return NULL;
+
+ file_info->num_fences = initial_info.num_fences;
+ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1);
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_FILE_INFO, file_info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0) {
+ sync_file_info_free(file_info);
+ return NULL;
+ }
+
+ return file_info;
+}
+
#if defined(__cplusplus)
}
#endif
--
2.34.1