Some fencing cleanup.
parent
a253de2fcf
commit
2b7a9afa09
|
@ -152,6 +152,13 @@ static __inline__ void *kcalloc(size_t nmemb, size_t size, int flags)
|
|||
(tmp);})
|
||||
#endif
|
||||
|
||||
#ifndef list_for_each_entry_safe_reverse
|
||||
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
|
||||
for (pos = list_entry((head)->prev, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.prev, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
|
||||
#endif
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <asm/page.h>
|
||||
|
|
|
@ -43,9 +43,28 @@ void drm_fence_handler(drm_device_t * dev, uint32_t class,
|
|||
drm_fence_manager_t *fm = &dev->fm;
|
||||
drm_fence_class_manager_t *fc = &fm->class[class];
|
||||
drm_fence_driver_t *driver = dev->driver->fence_driver;
|
||||
struct list_head *list, *prev;
|
||||
drm_fence_object_t *fence;
|
||||
struct list_head *head;
|
||||
drm_fence_object_t *fence, *next;
|
||||
int found = 0;
|
||||
int is_exe = (type & DRM_FENCE_TYPE_EXE);
|
||||
int ge_last_exe;
|
||||
|
||||
|
||||
|
||||
diff = (sequence - fc->exe_flush_sequence) & driver->sequence_mask;
|
||||
|
||||
if (fc->pending_exe_flush && is_exe && diff < driver->wrap_diff)
|
||||
fc->pending_exe_flush = 0;
|
||||
|
||||
diff = (sequence - fc->last_exe_flush) & driver->sequence_mask;
|
||||
ge_last_exe = diff < driver->wrap_diff;
|
||||
|
||||
if (ge_last_exe)
|
||||
fc->pending_flush &= ~type;
|
||||
|
||||
if (is_exe && ge_last_exe) {
|
||||
fc->last_exe_flush = sequence;
|
||||
}
|
||||
|
||||
if (list_empty(&fc->ring))
|
||||
return;
|
||||
|
@ -58,11 +77,11 @@ void drm_fence_handler(drm_device_t * dev, uint32_t class,
|
|||
}
|
||||
}
|
||||
|
||||
list = (found) ? fence->ring.prev : fc->ring.prev;
|
||||
prev = list->prev;
|
||||
head = (found) ? &fence->ring : &fc->ring;
|
||||
|
||||
for (; list != &fc->ring; list = prev, prev = list->prev) {
|
||||
fence = list_entry(list, drm_fence_object_t, ring);
|
||||
list_for_each_entry_safe_reverse(fence, next, head, ring) {
|
||||
if (&fence->ring == &fc->ring)
|
||||
break;
|
||||
|
||||
type |= fence->native_type;
|
||||
relevant = type & fence->type;
|
||||
|
@ -91,11 +110,6 @@ void drm_fence_handler(drm_device_t * dev, uint32_t class,
|
|||
|
||||
}
|
||||
|
||||
fc->pending_flush &= ~type;
|
||||
if (fc->pending_exe_flush && (type & DRM_FENCE_TYPE_EXE) &&
|
||||
((sequence - fc->exe_flush_sequence) < driver->wrap_diff))
|
||||
fc->pending_exe_flush = 0;
|
||||
|
||||
if (wake) {
|
||||
DRM_WAKEUP(&fc->fence_queue);
|
||||
}
|
||||
|
@ -178,24 +192,6 @@ static void drm_fence_flush_exe(drm_fence_class_manager_t * fc,
|
|||
uint32_t diff;
|
||||
|
||||
if (!fc->pending_exe_flush) {
|
||||
struct list_head *list;
|
||||
|
||||
/*
|
||||
* Last_exe_flush is invalid. Find oldest sequence.
|
||||
*/
|
||||
|
||||
list = &fc->ring;
|
||||
if (list_empty(list)) {
|
||||
return;
|
||||
} else {
|
||||
drm_fence_object_t *fence =
|
||||
list_entry(list->next, drm_fence_object_t, ring);
|
||||
fc->last_exe_flush = (fence->sequence - 1) &
|
||||
driver->sequence_mask;
|
||||
}
|
||||
diff = (sequence - fc->last_exe_flush) & driver->sequence_mask;
|
||||
if (diff >= driver->wrap_diff)
|
||||
return;
|
||||
fc->exe_flush_sequence = sequence;
|
||||
fc->pending_exe_flush = 1;
|
||||
} else {
|
||||
|
@ -261,14 +257,24 @@ void drm_fence_flush_old(drm_device_t * dev, uint32_t class, uint32_t sequence)
|
|||
drm_fence_object_t *fence;
|
||||
uint32_t diff;
|
||||
|
||||
write_lock_irqsave(&fm->lock, flags);
|
||||
old_sequence = (sequence - driver->flush_diff) & driver->sequence_mask;
|
||||
diff = (old_sequence - fc->last_exe_flush) & driver->sequence_mask;
|
||||
|
||||
if ((diff < driver->wrap_diff) && !fc->pending_exe_flush) {
|
||||
fc->pending_exe_flush = 1;
|
||||
fc->exe_flush_sequence = sequence - (driver->flush_diff / 2);
|
||||
}
|
||||
write_unlock_irqrestore(&fm->lock, flags);
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
read_lock_irqsave(&fm->lock, flags);
|
||||
if (fc->ring.next == &fc->ring) {
|
||||
|
||||
if (list_empty(&fc->ring)) {
|
||||
read_unlock_irqrestore(&fm->lock, flags);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return;
|
||||
}
|
||||
old_sequence = (sequence - driver->flush_diff) & driver->sequence_mask;
|
||||
fence = list_entry(fc->ring.next, drm_fence_object_t, ring);
|
||||
atomic_inc(&fence->usage);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
@ -384,6 +390,7 @@ int drm_fence_object_emit(drm_device_t * dev, drm_fence_object_t * fence,
|
|||
{
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
drm_fence_driver_t *driver = dev->driver->fence_driver;
|
||||
drm_fence_class_manager_t *fc = &fm->class[fence->class];
|
||||
unsigned long flags;
|
||||
uint32_t sequence;
|
||||
uint32_t native_type;
|
||||
|
@ -402,7 +409,9 @@ int drm_fence_object_emit(drm_device_t * dev, drm_fence_object_t * fence,
|
|||
fence->signaled = 0x00;
|
||||
fence->sequence = sequence;
|
||||
fence->native_type = native_type;
|
||||
list_add_tail(&fence->ring, &fm->class[class].ring);
|
||||
if (list_empty(&fc->ring))
|
||||
fc->last_exe_flush = sequence - 1;
|
||||
list_add_tail(&fence->ring, &fc->ring);
|
||||
write_unlock_irqrestore(&fm->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ static void i915_perform_flush(drm_device_t * dev)
|
|||
uint32_t i_status;
|
||||
uint32_t diff;
|
||||
uint32_t sequence;
|
||||
int rwflush;
|
||||
|
||||
if (!dev_priv)
|
||||
return;
|
||||
|
@ -65,14 +66,10 @@ static void i915_perform_flush(drm_device_t * dev)
|
|||
drm_fence_handler(dev, 0, sequence, DRM_FENCE_TYPE_EXE);
|
||||
}
|
||||
|
||||
diff = sequence - fc->exe_flush_sequence;
|
||||
if (diff < driver->wrap_diff) {
|
||||
fc->pending_exe_flush = 0;
|
||||
if (dev_priv->fence_irq_on) {
|
||||
if (dev_priv->fence_irq_on && !fc->pending_exe_flush) {
|
||||
i915_user_irq_off(dev_priv);
|
||||
dev_priv->fence_irq_on = 0;
|
||||
}
|
||||
} else if (!dev_priv->fence_irq_on) {
|
||||
} else if (!dev_priv->fence_irq_on && fc->pending_exe_flush) {
|
||||
i915_user_irq_on(dev_priv);
|
||||
dev_priv->fence_irq_on = 1;
|
||||
}
|
||||
|
@ -89,13 +86,14 @@ static void i915_perform_flush(drm_device_t * dev)
|
|||
}
|
||||
}
|
||||
|
||||
if (fc->pending_flush && !dev_priv->flush_pending) {
|
||||
rwflush = fc->pending_flush & DRM_I915_FENCE_TYPE_RW;
|
||||
if (rwflush && !dev_priv->flush_pending) {
|
||||
dev_priv->flush_sequence = (uint32_t) READ_BREADCRUMB(dev_priv);
|
||||
dev_priv->flush_flags = fc->pending_flush;
|
||||
dev_priv->saved_flush_status = READ_HWSP(dev_priv, 0);
|
||||
I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21));
|
||||
dev_priv->flush_pending = 1;
|
||||
fc->pending_flush = 0;
|
||||
fc->pending_flush &= ~DRM_I915_FENCE_TYPE_RW;
|
||||
}
|
||||
|
||||
if (dev_priv->flush_pending) {
|
||||
|
|
Loading…
Reference in New Issue