Commit 95ccb0f3 authored by Thomas Hellstrom's avatar Thomas Hellstrom Committed by Dave Airlie

drm/ttm: Fix up a theoretical deadlock

A process suspended waiting for a higher sequence or no sequence to unreserve,
a bo may be beaten to the reservation by a process with a lower sequence.
In that case the first process should give up trying to reserve and
return -EAGAIN. In order for that to happen, we must wake waiting processes
when we change sequence, so that they have a chance to detect the new
sequence.
Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 9a03d348
...@@ -224,6 +224,9 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo, ...@@ -224,6 +224,9 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
int ret; int ret;
while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) { while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) {
/**
* Deadlock avoidance for multi-bo reserving.
*/
if (use_sequence && bo->seq_valid && if (use_sequence && bo->seq_valid &&
(sequence - bo->val_seq < (1 << 31))) { (sequence - bo->val_seq < (1 << 31))) {
return -EAGAIN; return -EAGAIN;
...@@ -241,6 +244,14 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo, ...@@ -241,6 +244,14 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
} }
if (use_sequence) { if (use_sequence) {
/**
* Wake up waiters that may need to recheck for deadlock,
* if we decreased the sequence number.
*/
if (unlikely((bo->val_seq - sequence < (1 << 31))
|| !bo->seq_valid))
wake_up_all(&bo->event_queue);
bo->val_seq = sequence; bo->val_seq = sequence;
bo->seq_valid = true; bo->seq_valid = true;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment