From 024a459fe7fd6bb2aa052276d79f77171ce0c5d4 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Thu, 19 Dec 2019 21:44:38 +0900 Subject: [PATCH] tbm_sync: support mainline interface of fence 1. first try to call maline FENCE_MERGE ioctl in tbm_sync_fence_merge. 2. use poll instead of legacy FENCE_WAIT ioctl in tbm_sync_fence_wait. Change-Id: I636a99b4f49806c2a6519e44e2675b53ea83d3a5 --- src/tbm_sync.c | 66 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/src/tbm_sync.c b/src/tbm_sync.c index 49d0266..d4bcd66 100644 --- a/src/tbm_sync.c +++ b/src/tbm_sync.c @@ -40,6 +40,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include /* IOCTLs for timeline file object. */ #define TIMELINE_IOC_MAGIC 'W' @@ -47,9 +48,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define TIMELINE_IOC_INC _IOW(TIMELINE_IOC_MAGIC, 1, __u32) /* IOCTLs for fence file object. */ -#define FENCE_IOC_MAGIC '>' -#define FENCE_IOC_WAIT _IOW(FENCE_IOC_MAGIC, 0, __s32) -#define FENCE_IOC_MERGE _IOWR(FENCE_IOC_MAGIC, 1, struct sync_merge_data) +#define FENCE_IOC_MAGIC '>' +#define FENCE_IOC_MERGE _IOWR(FENCE_IOC_MAGIC, 3, struct sync_merge_data) + +#define FENCE_IOC_LEGACY_WAIT _IOW(FENCE_IOC_MAGIC, 0, __s32) +#define FENCE_IOC_LEGACY_MERGE _IOWR(FENCE_IOC_MAGIC, 1, struct sync_legacy_merge_data) /* Path to the sync device legacy file. */ #define SYNC_DEVICE_PATH_LEGACY "/dev/sw_sync" @@ -66,6 +69,15 @@ struct create_fence_data { /* Argument data structure for the fence.merge ioctl. */ struct sync_merge_data { + char name[32]; /* Name of the new fence object (IN) */ + __s32 fd2; /* fence to merged with the fence (IN) */ + __s32 fence; /* File descriptor for the new fence (OUT) */ + __u32 flags; /* merge_data flags (IN) */ + __u32 pad; /* padding for 64-bit alignment, should always be zero */ +}; + +/* Argument data structure for the legacy fence.merge ioctl. */ +struct sync_legacy_merge_data { __s32 fd2; /* fence to merged with the fence (IN) */ char name[32]; /* Name of the new fence object (IN) */ __s32 fence; /* File descriptor for the new fence (OUT) */ @@ -154,23 +166,29 @@ tbm_sync_fence_create(tbm_fd timeline, const char *name, unsigned int value) int tbm_sync_fence_wait(tbm_fd fence, int timeout) { - __s32 arg = timeout; - int ret; + struct pollfd fds; + int ret; - /* Retry while ioctl() ended up with interrupt. */ - do { - ret = ioctl(fence, FENCE_IOC_WAIT, &arg); - } while (ret == -1 && errno == EINTR); - - /* ioctl() was successful. */ - if (ret == 0) - return 1; + fds.fd = fence; + fds.events = POLLIN; - /* ioctl() ended up with timeout. */ - if (errno == ETIME) - return -1; + do { + ret = poll(&fds, 1, timeout); + if (ret > 0) { + if (fds.revents & (POLLERR | POLLNVAL)) { + errno = EINVAL; + _log_errno(); + return 0; + } + + return 1; + } else if (ret == 0) { + errno = ETIME; + _log_errno(); + return 0; + } + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); - /* ioctl() failed for some reason. */ _log_errno(); return 0; } @@ -179,10 +197,22 @@ tbm_fd tbm_sync_fence_merge(const char *name, tbm_fd fence1, tbm_fd fence2) { struct sync_merge_data data = { .fd2 = fence2 }; + int ret; _copy_string(data.name, name, 32); - if (ioctl(fence1, FENCE_IOC_MERGE, &data) == -1) { + ret = ioctl(fence1, FENCE_IOC_MERGE, &data); + if (ret < 0 && errno == ENOTTY) { + struct sync_legacy_merge_data legacy_data = {. fd2 = fence2 }; + + _copy_string(legacy_data.name, name, 32); + + ret = ioctl(fence1, FENCE_IOC_LEGACY_MERGE, &legacy_data); + if (ret < 0) { + _log_errno(); + return -1; + } + } else if (ret < 0) { _log_errno(); return -1; } -- 2.7.4