summaryrefslogtreecommitdiff
path: root/sys/dev/pci/drm
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2015-09-24 20:52:29 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2015-09-24 20:52:29 +0000
commit113f47c92a4d44b213a54b9fc61523b9f34bdb4b (patch)
tree13a685e80b245a32824c8fa8337ec6fd9b5de29a /sys/dev/pci/drm
parentb0f50edde55d52e5bf7b4d696e04f6e3c4b1d1f3 (diff)
Properly implement waitqueue_active(). Gets rid of spurious
*ERROR* Hangcheck timer elapsed... xxx ring idle messages.
Diffstat (limited to 'sys/dev/pci/drm')
-rw-r--r--sys/dev/pci/drm/drm_linux.h14
-rw-r--r--sys/dev/pci/drm/i915/i915_gem.c5
2 files changed, 15 insertions, 4 deletions
diff --git a/sys/dev/pci/drm/drm_linux.h b/sys/dev/pci/drm/drm_linux.h
index 277814cc72a..124f54ed58e 100644
--- a/sys/dev/pci/drm/drm_linux.h
+++ b/sys/dev/pci/drm/drm_linux.h
@@ -1,6 +1,6 @@
-/* $OpenBSD: drm_linux.h,v 1.34 2015/09/23 23:12:11 kettenis Exp $ */
+/* $OpenBSD: drm_linux.h,v 1.35 2015/09/24 20:52:28 kettenis Exp $ */
/*
- * Copyright (c) 2013, 2014 Mark Kettenis
+ * Copyright (c) 2013, 2014, 2015 Mark Kettenis
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -290,6 +290,7 @@ spin_unlock_irqrestore(struct mutex *mtxp, __unused unsigned long flags)
struct wait_queue_head {
struct mutex lock;
+ unsigned int count;
};
typedef struct wait_queue_head wait_queue_head_t;
@@ -297,6 +298,7 @@ static inline void
init_waitqueue_head(wait_queue_head_t *wq)
{
mtx_init(&wq->lock, IPL_NONE);
+ wq->count = 0;
}
#define wait_event(wq, condition) \
@@ -305,8 +307,10 @@ do { \
\
if (condition) \
break; \
+ atomic_inc_int(&(wq).count); \
sleep_setup(&sls, &wq, 0, "drmwe"); \
sleep_finish(&sls, !(condition)); \
+ atomic_dec_int(&(wq).count); \
} while (!(condition))
#define __wait_event_timeout(wq, condition, ret) \
@@ -314,12 +318,14 @@ do { \
struct sleep_state sls; \
int deadline, __error; \
\
+ atomic_inc_int(&(wq).count); \
sleep_setup(&sls, &wq, 0, "drmwet"); \
sleep_setup_timeout(&sls, ret); \
deadline = ticks + ret; \
sleep_finish(&sls, !(condition)); \
ret = deadline - ticks; \
__error = sleep_finish_timeout(&sls); \
+ atomic_dec_int(&(wq).count); \
if (ret < 0 || __error == EWOULDBLOCK) \
ret = 0; \
if (ret == 0 && (condition)) { \
@@ -341,6 +347,7 @@ do { \
struct sleep_state sls; \
int deadline, __error, __error1; \
\
+ atomic_inc_int(&(wq).count); \
sleep_setup(&sls, &wq, PCATCH, "drmweti"); \
sleep_setup_timeout(&sls, ret); \
sleep_setup_signal(&sls, PCATCH); \
@@ -349,6 +356,7 @@ do { \
ret = deadline - ticks; \
__error1 = sleep_finish_timeout(&sls); \
__error = sleep_finish_signal(&sls); \
+ atomic_dec_int(&(wq).count); \
if (ret < 0 || __error1 == EWOULDBLOCK) \
ret = 0; \
if (__error == ERESTART) \
@@ -373,7 +381,7 @@ do { \
#define wake_up_all(x) wakeup(x)
#define wake_up_all_locked(x) wakeup(x)
-#define waitqueue_active(x) true
+#define waitqueue_active(wq) ((wq)->count > 0)
struct completion {
u_int done;
diff --git a/sys/dev/pci/drm/i915/i915_gem.c b/sys/dev/pci/drm/i915/i915_gem.c
index e83ca7ff8f6..a2ac0e2d06a 100644
--- a/sys/dev/pci/drm/i915/i915_gem.c
+++ b/sys/dev/pci/drm/i915/i915_gem.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i915_gem.c,v 1.100 2015/09/23 23:12:12 kettenis Exp $ */
+/* $OpenBSD: i915_gem.c,v 1.101 2015/09/24 20:52:28 kettenis Exp $ */
/*
* Copyright (c) 2008-2009 Owain G. Ainsworth <oga@openbsd.org>
*
@@ -1228,6 +1228,7 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
trace_i915_gem_request_wait_begin(ring, seqno);
getrawmonotonic(&before);
for (;;) {
+ atomic_inc_int(&ring->irq_queue.count);
sleep_setup(&sls, &ring->irq_queue, interruptible ? PCATCH : 0, "wseq");
/* We need to check whether any gpu reset happened in between
@@ -1272,6 +1273,7 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
sleep_finish(&sls, 1);
sleep_finish_timeout(&sls);
ret = sleep_finish_signal(&sls);
+ atomic_dec_int(&ring->irq_queue.count);
}
getrawmonotonic(&now);
trace_i915_gem_request_wait_end(ring, seqno);
@@ -1282,6 +1284,7 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
sleep_finish(&sls, 0);
sleep_finish_timeout(&sls);
sleep_finish_signal(&sls);
+ atomic_dec_int(&ring->irq_queue.count);
if (timeout) {
struct timespec sleep_time = timespec_sub(now, before);