DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
if (bo->fence) {
- if (!drm_fence_object_signaled(bo->fence, bo->fence_flags)) {
+ if (!drm_fence_object_signaled(bo->fence, bo->fence_type)) {
- drm_fence_object_flush(dev, bo->fence, bo->fence_flags);
+ drm_fence_object_flush(dev, bo->fence, bo->fence_type);
list_add_tail(&bo->ddestroy, &bm->ddestroy);
schedule_delayed_work(&bm->wq,
((DRM_HZ / 100) <
fence = entry->fence;
if (fence && drm_fence_object_signaled(fence,
- entry->fence_flags)) {
+ entry->fence_type)) {
drm_fence_usage_deref_locked(dev, fence);
entry->fence = NULL;
}
int drm_fence_buffer_objects(drm_file_t * priv,
struct list_head *list,
+ uint32_t fence_flags,
drm_fence_object_t * fence,
drm_fence_object_t ** used_fence)
{
drm_buffer_manager_t *bm = &dev->bm;
drm_buffer_object_t *entry;
- uint32_t fence_flags = 0;
+ uint32_t fence_type = 0;
int count = 0;
int ret = 0;
struct list_head f_list, *l;
list_for_each_entry(entry, list, head) {
BUG_ON(!(entry->priv_flags & _DRM_BO_FLAG_UNFENCED));
- fence_flags |= entry->fence_flags;
+ fence_type |= entry->fence_type;
if (entry->fence_class != 0) {
DRM_ERROR("Fence class %d is not implemented yet.\n",
entry->fence_class);
list_del_init(list);
if (fence) {
- if ((fence_flags & fence->type) != fence_flags) {
+ if ((fence_type & fence->type) != fence_type) {
DRM_ERROR("Given fence doesn't match buffers "
"on unfenced list.\n");
ret = -EINVAL;
}
} else {
mutex_unlock(&dev->struct_mutex);
- ret = drm_fence_object_create(dev, fence_flags, 1, &fence);
+ ret = drm_fence_object_create(dev, fence_type,
+ fence_flags | DRM_FENCE_FLAG_EMIT,
+ &fence);
mutex_lock(&dev->struct_mutex);
if (ret)
goto out;
if (fence) {
drm_device_t *dev = bo->dev;
- if (drm_fence_object_signaled(fence, bo->fence_flags)) {
+ if (drm_fence_object_signaled(fence, bo->fence_type)) {
drm_fence_usage_deref_unlocked(dev, fence);
bo->fence = NULL;
return 0;
}
ret =
drm_fence_object_wait(dev, fence, lazy, ignore_signals,
- bo->fence_flags);
+ bo->fence_type);
if (ret)
return ret;
BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
if (fence) {
drm_device_t *dev = bo->dev;
- if (drm_fence_object_signaled(fence, bo->fence_flags)) {
+ if (drm_fence_object_signaled(fence, bo->fence_type)) {
drm_fence_usage_deref_unlocked(dev, fence);
bo->fence = NULL;
return 0;
BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
if (fence) {
drm_device_t *dev = bo->dev;
- if (drm_fence_object_signaled(fence, bo->fence_flags)) {
+ if (drm_fence_object_signaled(fence, bo->fence_type)) {
drm_fence_usage_deref_unlocked(dev, fence);
bo->fence = NULL;
return 0;
}
drm_fence_object_flush(dev, fence, DRM_FENCE_TYPE_EXE);
- if (drm_fence_object_signaled(fence, bo->fence_flags)) {
+ if (drm_fence_object_signaled(fence, bo->fence_type)) {
drm_fence_usage_deref_unlocked(dev, fence);
bo->fence = NULL;
return 0;
rep->mask = bo->mask;
rep->buffer_start = bo->buffer_start;
- rep->fence_flags = bo->fence_flags;
+ rep->fence_flags = bo->fence_type;
rep->rep_flags = 0;
if ((bo->priv_flags & _DRM_BO_FLAG_UNFENCED) || drm_bo_quick_busy(bo)) {
}
DRM_DEBUG("New flags 0x%08x, Old flags 0x%08x\n", new_flags, bo->flags);
- ret = driver->fence_type(new_flags, &bo->fence_class, &bo->fence_flags);
+ ret = driver->fence_type(new_flags, &bo->fence_class, &bo->fence_type);
if (ret) {
DRM_ERROR("Driver did not support given buffer permissions\n");
return ret;
#include "drmP.h"
-static void drm_fm_update_pointers(drm_fence_manager_t * fm,
- struct list_head *list, int no_types,
- uint32_t type)
-{
- int i;
- for (i = 0; i < no_types; ++i) {
- if (type & (1 << i)) {
- fm->fence_types[i] = list;
- }
- }
-}
-
/*
* Typically called by the IRQ handler.
*/
void drm_fence_handler(drm_device_t * dev, uint32_t sequence, uint32_t type)
{
- int i;
int wake = 0;
- int largest = 0;
uint32_t diff;
uint32_t relevant;
- int index = 0;
drm_fence_manager_t *fm = &dev->fm;
drm_fence_driver_t *driver = dev->driver->fence_driver;
- struct list_head *list;
- struct list_head *fence_list;
+ struct list_head *list, *prev;
drm_fence_object_t *fence;
- int found = 0;
-
- for (i = 0; i < driver->no_types; ++i) {
- if (!(type & (1 << i)))
- continue;
-
- list = fm->fence_types[i];
- fence_list = list->next;
-
- if (fence_list == &fm->ring)
- continue;
-
- fence = list_entry(fence_list, drm_fence_object_t, ring);
+ list_for_each_entry(fence, &fm->ring, ring) {
diff = (sequence - fence->sequence) & driver->sequence_mask;
-
- if (diff < driver->wrap_diff) {
- if (diff >= largest) {
- largest = diff;
- index = i;
- found = 1;
- }
- }
+ if (diff > driver->wrap_diff)
+ break;
}
- if (!found)
- return;
+ list = fence->ring.prev;
+ prev = list->prev;
- /*
- * Start with the fence object with the lowest sequence number, affected by
- * the type mask of this call. Update signaled fields,
- * Check if we need to wake sleeping processes
- */
-
- list = fm->fence_types[index]->next;
- do {
- if (list == &fm->ring) {
- drm_fm_update_pointers(fm, list->prev,
- driver->no_types, type);
- break;
- }
+ for (; list != &fm->ring; list = prev, prev = list->prev) {
fence = list_entry(list, drm_fence_object_t, ring);
- diff = (sequence - fence->sequence) & driver->sequence_mask;
- if (diff >= driver->wrap_diff) {
- drm_fm_update_pointers(fm, fence->ring.prev,
- driver->no_types, type);
- break;
- }
+
+ type |= fence->native_type;
relevant = type & fence->type;
+
if ((fence->signaled | relevant) != fence->signaled) {
fence->signaled |= relevant;
DRM_DEBUG("Fence 0x%08lx signaled 0x%08x\n",
relevant = fence->flush_mask &
~(fence->signaled | fence->submitted_flush);
+
if (relevant) {
fm->pending_flush |= relevant;
fence->submitted_flush = fence->flush_mask;
}
- list = list->next;
-
- /*
- * Remove a completely signaled fence from the
- * fence manager ring.
- */
-
if (!(fence->type & ~fence->signaled)) {
DRM_DEBUG("Fence completely signaled 0x%08lx\n",
fence->base.hash.key);
- fence_list = &fence->ring;
- for (i = 0; i < driver->no_types; ++i) {
- if (fm->fence_types[i] == fence_list)
- fm->fence_types[i] = fence_list->prev;
- }
- list_del_init(fence_list);
+ list_del_init(&fence->ring);
}
- } while (1);
-
- /*
- * Wake sleeping processes.
- */
-
+ }
+
if (wake) {
DRM_WAKEUP(&fm->fence_queue);
}
static void drm_fence_unring(drm_device_t * dev, struct list_head *ring)
{
drm_fence_manager_t *fm = &dev->fm;
- drm_fence_driver_t *driver = dev->driver->fence_driver;
unsigned long flags;
- int i;
write_lock_irqsave(&fm->lock, flags);
- for (i = 0; i < driver->no_types; ++i) {
- if (fm->fence_types[i] == ring)
- fm->fence_types[i] = ring->prev;
- }
list_del_init(ring);
write_unlock_irqrestore(&fm->lock, flags);
}
* Last_exe_flush is invalid. Find oldest sequence.
*/
- list = fm->fence_types[_DRM_FENCE_TYPE_EXE];
+/* list = fm->fence_types[_DRM_FENCE_TYPE_EXE];*/
+ list = &fm->ring;
if (list->next == &fm->ring) {
return;
} else {
}
int drm_fence_object_emit(drm_device_t * dev, drm_fence_object_t * fence,
- uint32_t type)
+ uint32_t fence_flags, uint32_t type)
{
drm_fence_manager_t *fm = &dev->fm;
drm_fence_driver_t *driver = dev->driver->fence_driver;
unsigned long flags;
uint32_t sequence;
+ uint32_t native_type;
int ret;
drm_fence_unring(dev, &fence->ring);
- ret = driver->emit(dev, &sequence);
+ ret = driver->emit(dev, fence_flags, &sequence, &native_type);
if (ret)
return ret;
fence->submitted_flush = 0x00;
fence->signaled = 0x00;
fence->sequence = sequence;
+ fence->native_type = native_type;
list_add_tail(&fence->ring, &fm->ring);
write_unlock_irqrestore(&fm->lock, flags);
return 0;
}
-int drm_fence_object_init(drm_device_t * dev, uint32_t type, int emit,
- drm_fence_object_t * fence)
+static int drm_fence_object_init(drm_device_t * dev, uint32_t type,
+ uint32_t fence_flags,
+ drm_fence_object_t * fence)
{
int ret = 0;
unsigned long flags;
fence->signaled = 0;
fence->sequence = 0;
write_unlock_irqrestore(&fm->lock, flags);
- if (emit) {
- ret = drm_fence_object_emit(dev, fence, type);
+ if (fence_flags & DRM_FENCE_FLAG_EMIT) {
+ ret = drm_fence_object_emit(dev, fence, fence_flags, type);
}
return ret;
}
-EXPORT_SYMBOL(drm_fence_object_init);
int drm_fence_add_user_object(drm_file_t * priv, drm_fence_object_t * fence,
int shareable)
EXPORT_SYMBOL(drm_fence_add_user_object);
int drm_fence_object_create(drm_device_t * dev, uint32_t type,
- int emit, drm_fence_object_t ** c_fence)
+ unsigned flags, drm_fence_object_t ** c_fence)
{
drm_fence_object_t *fence;
int ret;
fence = kmem_cache_alloc(drm_cache.fence_object, GFP_KERNEL);
if (!fence)
return -ENOMEM;
- ret = drm_fence_object_init(dev, type, emit, fence);
+ ret = drm_fence_object_init(dev, type, flags, fence);
if (ret) {
drm_fence_usage_deref_unlocked(dev, fence);
return ret;
if (arg.flags & DRM_FENCE_FLAG_EMIT)
LOCK_TEST_WITH_RETURN(dev, filp);
ret = drm_fence_object_create(dev, arg.type,
- arg.flags & DRM_FENCE_FLAG_EMIT,
+ arg.flags,
&fence);
if (ret)
return ret;
fence = drm_lookup_fence_object(priv, arg.handle);
if (!fence)
return -EINVAL;
- ret = drm_fence_object_emit(dev, fence, arg.type);
+ ret = drm_fence_object_emit(dev, fence, arg.flags, arg.type);
break;
case drm_fence_buffers:
if (!dev->bm.initialized) {
return -EINVAL;
}
LOCK_TEST_WITH_RETURN(dev, filp);
- ret = drm_fence_buffer_objects(priv, NULL, NULL, &fence);
+ ret = drm_fence_buffer_objects(priv, NULL, arg.flags,
+ NULL, &fence);
if (ret)
return ret;
ret = drm_fence_add_user_object(priv, fence,