sync with OpenBSD -current
This commit is contained in:
parent
ee68147dcd
commit
1cefe29c7e
1651 changed files with 283292 additions and 68089 deletions
|
@ -136,6 +136,10 @@
|
|||
* requirement is inherited from the wait-before-signal behavior required by
|
||||
* the Vulkan timeline semaphore API.
|
||||
*
|
||||
* Alternatively, &DRM_IOCTL_SYNCOBJ_EVENTFD can be used to wait without
|
||||
* blocking: an eventfd will be signaled when the syncobj is. This is useful to
|
||||
* integrate the wait in an event loop.
|
||||
*
|
||||
*
|
||||
* Import/export of syncobjs
|
||||
* -------------------------
|
||||
|
@ -184,6 +188,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/anon_inodes.h>
|
||||
#include <linux/eventfd.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/sched/signal.h>
|
||||
|
@ -215,6 +220,20 @@ struct syncobj_wait_entry {
|
|||
static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
|
||||
struct syncobj_wait_entry *wait);
|
||||
|
||||
struct syncobj_eventfd_entry {
|
||||
struct list_head node;
|
||||
struct dma_fence *fence;
|
||||
struct dma_fence_cb fence_cb;
|
||||
struct drm_syncobj *syncobj;
|
||||
struct eventfd_ctx *ev_fd_ctx;
|
||||
u64 point;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
static void
|
||||
syncobj_eventfd_entry_func(struct drm_syncobj *syncobj,
|
||||
struct syncobj_eventfd_entry *entry);
|
||||
|
||||
/**
|
||||
* drm_syncobj_find - lookup and reference a sync object.
|
||||
* @file_private: drm file private pointer
|
||||
|
@ -277,6 +296,30 @@ static void drm_syncobj_remove_wait(struct drm_syncobj *syncobj,
|
|||
spin_unlock(&syncobj->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
syncobj_eventfd_entry_free(struct syncobj_eventfd_entry *entry)
|
||||
{
|
||||
eventfd_ctx_put(entry->ev_fd_ctx);
|
||||
dma_fence_put(entry->fence);
|
||||
/* This happens either inside the syncobj lock, or after the node has
|
||||
* already been removed from the list.
|
||||
*/
|
||||
list_del(&entry->node);
|
||||
kfree(entry);
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
static void
|
||||
drm_syncobj_add_eventfd(struct drm_syncobj *syncobj,
|
||||
struct syncobj_eventfd_entry *entry)
|
||||
{
|
||||
spin_lock(&syncobj->lock);
|
||||
list_add_tail(&entry->node, &syncobj->ev_fd_list);
|
||||
syncobj_eventfd_entry_func(syncobj, entry);
|
||||
spin_unlock(&syncobj->lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* drm_syncobj_add_point - add new timeline point to the syncobj
|
||||
* @syncobj: sync object to add timeline point do
|
||||
|
@ -291,7 +334,8 @@ void drm_syncobj_add_point(struct drm_syncobj *syncobj,
|
|||
struct dma_fence *fence,
|
||||
uint64_t point)
|
||||
{
|
||||
struct syncobj_wait_entry *cur, *tmp;
|
||||
struct syncobj_wait_entry *wait_cur, *wait_tmp;
|
||||
struct syncobj_eventfd_entry *ev_fd_cur, *ev_fd_tmp;
|
||||
struct dma_fence *prev;
|
||||
|
||||
dma_fence_get(fence);
|
||||
|
@ -305,8 +349,10 @@ void drm_syncobj_add_point(struct drm_syncobj *syncobj,
|
|||
dma_fence_chain_init(chain, prev, fence, point);
|
||||
rcu_assign_pointer(syncobj->fence, &chain->base);
|
||||
|
||||
list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node)
|
||||
syncobj_wait_syncobj_func(syncobj, cur);
|
||||
list_for_each_entry_safe(wait_cur, wait_tmp, &syncobj->cb_list, node)
|
||||
syncobj_wait_syncobj_func(syncobj, wait_cur);
|
||||
list_for_each_entry_safe(ev_fd_cur, ev_fd_tmp, &syncobj->ev_fd_list, node)
|
||||
syncobj_eventfd_entry_func(syncobj, ev_fd_cur);
|
||||
spin_unlock(&syncobj->lock);
|
||||
|
||||
/* Walk the chain once to trigger garbage collection */
|
||||
|
@ -326,7 +372,8 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
|
|||
struct dma_fence *fence)
|
||||
{
|
||||
struct dma_fence *old_fence;
|
||||
struct syncobj_wait_entry *cur, *tmp;
|
||||
struct syncobj_wait_entry *wait_cur, *wait_tmp;
|
||||
struct syncobj_eventfd_entry *ev_fd_cur, *ev_fd_tmp;
|
||||
|
||||
if (fence)
|
||||
dma_fence_get(fence);
|
||||
|
@ -338,8 +385,10 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
|
|||
rcu_assign_pointer(syncobj->fence, fence);
|
||||
|
||||
if (fence != old_fence) {
|
||||
list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node)
|
||||
syncobj_wait_syncobj_func(syncobj, cur);
|
||||
list_for_each_entry_safe(wait_cur, wait_tmp, &syncobj->cb_list, node)
|
||||
syncobj_wait_syncobj_func(syncobj, wait_cur);
|
||||
list_for_each_entry_safe(ev_fd_cur, ev_fd_tmp, &syncobj->ev_fd_list, node)
|
||||
syncobj_eventfd_entry_func(syncobj, ev_fd_cur);
|
||||
}
|
||||
|
||||
spin_unlock(&syncobj->lock);
|
||||
|
@ -479,7 +528,13 @@ void drm_syncobj_free(struct kref *kref)
|
|||
struct drm_syncobj *syncobj = container_of(kref,
|
||||
struct drm_syncobj,
|
||||
refcount);
|
||||
struct syncobj_eventfd_entry *ev_fd_cur, *ev_fd_tmp;
|
||||
|
||||
drm_syncobj_replace_fence(syncobj, NULL);
|
||||
|
||||
list_for_each_entry_safe(ev_fd_cur, ev_fd_tmp, &syncobj->ev_fd_list, node)
|
||||
syncobj_eventfd_entry_free(ev_fd_cur);
|
||||
|
||||
kfree(syncobj);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_syncobj_free);
|
||||
|
@ -508,6 +563,7 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags,
|
|||
|
||||
kref_init(&syncobj->refcount);
|
||||
INIT_LIST_HEAD(&syncobj->cb_list);
|
||||
INIT_LIST_HEAD(&syncobj->ev_fd_list);
|
||||
mtx_init(&syncobj->lock, IPL_NONE);
|
||||
|
||||
if (flags & DRM_SYNCOBJ_CREATE_SIGNALED) {
|
||||
|
@ -1368,6 +1424,91 @@ drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void syncobj_eventfd_entry_fence_func(struct dma_fence *fence,
|
||||
struct dma_fence_cb *cb)
|
||||
{
|
||||
struct syncobj_eventfd_entry *entry =
|
||||
container_of(cb, struct syncobj_eventfd_entry, fence_cb);
|
||||
|
||||
eventfd_signal(entry->ev_fd_ctx, 1);
|
||||
syncobj_eventfd_entry_free(entry);
|
||||
}
|
||||
|
||||
static void
|
||||
syncobj_eventfd_entry_func(struct drm_syncobj *syncobj,
|
||||
struct syncobj_eventfd_entry *entry)
|
||||
{
|
||||
int ret;
|
||||
struct dma_fence *fence;
|
||||
|
||||
/* This happens inside the syncobj lock */
|
||||
fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, 1));
|
||||
ret = dma_fence_chain_find_seqno(&fence, entry->point);
|
||||
if (ret != 0 || !fence) {
|
||||
dma_fence_put(fence);
|
||||
return;
|
||||
}
|
||||
|
||||
list_del_init(&entry->node);
|
||||
entry->fence = fence;
|
||||
|
||||
if (entry->flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE) {
|
||||
eventfd_signal(entry->ev_fd_ctx, 1);
|
||||
syncobj_eventfd_entry_free(entry);
|
||||
} else {
|
||||
ret = dma_fence_add_callback(fence, &entry->fence_cb,
|
||||
syncobj_eventfd_entry_fence_func);
|
||||
if (ret == -ENOENT) {
|
||||
eventfd_signal(entry->ev_fd_ctx, 1);
|
||||
syncobj_eventfd_entry_free(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
drm_syncobj_eventfd_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_private)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
#ifdef notyet
|
||||
struct drm_syncobj_eventfd *args = data;
|
||||
struct drm_syncobj *syncobj;
|
||||
struct eventfd_ctx *ev_fd_ctx;
|
||||
struct syncobj_eventfd_entry *entry;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (args->flags & ~DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)
|
||||
return -EINVAL;
|
||||
|
||||
if (args->pad)
|
||||
return -EINVAL;
|
||||
|
||||
syncobj = drm_syncobj_find(file_private, args->handle);
|
||||
if (!syncobj)
|
||||
return -ENOENT;
|
||||
|
||||
ev_fd_ctx = eventfd_ctx_fdget(args->fd);
|
||||
if (IS_ERR(ev_fd_ctx))
|
||||
return PTR_ERR(ev_fd_ctx);
|
||||
|
||||
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
|
||||
if (!entry) {
|
||||
eventfd_ctx_put(ev_fd_ctx);
|
||||
return -ENOMEM;
|
||||
}
|
||||
entry->syncobj = syncobj;
|
||||
entry->ev_fd_ctx = ev_fd_ctx;
|
||||
entry->point = args->point;
|
||||
entry->flags = args->flags;
|
||||
|
||||
drm_syncobj_add_eventfd(syncobj, entry);
|
||||
drm_syncobj_put(syncobj);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue