egl+libsync: Add check for valid fence-fd
Debugging fd mix-ups (ie. where, possibly via close()ing the original fd, etc, you end up with something that is a valid fd but not a valid *fence* fd) can be difficult. Fortunately we can use the FILE_INFO ioctl, which will return an error if the fd is not a fence fd. For android, we instead use the libsync API, which does a similar thing on modern kernels, but has a fallback path for older android kernels. Note that the FILE_INFO ioctl has existed upstream since at least prior to destaging of sync_file. Signed-off-by: Rob Clark <robdclark@chromium.org> Reviewed-by: Emma Anholt <emma@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11202>
This commit is contained in:
parent
bfeff2c687
commit
964efdfba9
|
@ -17,4 +17,13 @@ int sync_merge(const char *name, int fd, int fd2)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sync_file_info* sync_file_info(int32_t fd)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sync_file_info_free(struct sync_file_info* info)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
#include "egl_dri2.h"
|
#include "egl_dri2.h"
|
||||||
#include "GL/mesa_glinterop.h"
|
#include "GL/mesa_glinterop.h"
|
||||||
#include "loader/loader.h"
|
#include "loader/loader.h"
|
||||||
|
#include "util/libsync.h"
|
||||||
#include "util/os_file.h"
|
#include "util/os_file.h"
|
||||||
#include "util/u_atomic.h"
|
#include "util/u_atomic.h"
|
||||||
#include "util/u_vector.h"
|
#include "util/u_vector.h"
|
||||||
|
@ -3495,6 +3496,8 @@ dri2_dup_native_fence_fd(_EGLDisplay *disp, _EGLSync *sync)
|
||||||
return EGL_NO_NATIVE_FENCE_FD_ANDROID;
|
return EGL_NO_NATIVE_FENCE_FD_ANDROID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(sync_valid_fd(sync->SyncFd));
|
||||||
|
|
||||||
return os_dupfd_cloexec(sync->SyncFd);
|
return os_dupfd_cloexec(sync->SyncFd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
@ -46,6 +47,25 @@ extern "C" {
|
||||||
* Android kernels.
|
* Android kernels.
|
||||||
*/
|
*/
|
||||||
#include <android/sync.h>
|
#include <android/sync.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the fd represents a valid fence-fd.
|
||||||
|
*
|
||||||
|
* The android variant of this debug helper is implemented on top of the
|
||||||
|
* system's libsync for compatibility with pre-4.7 android kernels.
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
sync_valid_fd(int fd)
|
||||||
|
{
|
||||||
|
/* sync_file_info() only available in SDK 26. */
|
||||||
|
#if ANDROID_API_LEVEL >= 26
|
||||||
|
struct sync_file_info *info = sync_file_info(fd);
|
||||||
|
if (!info)
|
||||||
|
return false;
|
||||||
|
sync_file_info_free(info);
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifndef SYNC_IOC_MERGE
|
#ifndef SYNC_IOC_MERGE
|
||||||
|
@ -61,8 +81,20 @@ struct sync_merge_data {
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint32_t pad;
|
uint32_t pad;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sync_file_info {
|
||||||
|
char name[32];
|
||||||
|
int32_t status;
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t num_fences;
|
||||||
|
uint32_t pad;
|
||||||
|
|
||||||
|
uint64_t sync_fence_info;
|
||||||
|
};
|
||||||
|
|
||||||
#define SYNC_IOC_MAGIC '>'
|
#define SYNC_IOC_MAGIC '>'
|
||||||
#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data)
|
#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data)
|
||||||
|
#define SYNC_IOC_FILE_INFO _IOWR(SYNC_IOC_MAGIC, 4, struct sync_file_info)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,6 +141,16 @@ static inline int sync_merge(const char *name, int fd1, int fd2)
|
||||||
return data.fence;
|
return data.fence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the fd represents a valid fence-fd.
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
sync_valid_fd(int fd)
|
||||||
|
{
|
||||||
|
struct sync_file_info info = {{0}};
|
||||||
|
return ioctl(fd, SYNC_IOC_FILE_INFO, &info) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !ANDROID */
|
#endif /* !ANDROID */
|
||||||
|
|
||||||
/* accumulate fd2 into fd1. If *fd1 is not a valid fd then dup fd2,
|
/* accumulate fd2 into fd1. If *fd1 is not a valid fd then dup fd2,
|
||||||
|
|
Loading…
Reference in New Issue