-/* $OpenBSD: drm_linux.c,v 1.93 2022/06/20 01:39:44 visa Exp $ */
+/* $OpenBSD: drm_linux.c,v 1.94 2022/09/16 01:48:07 jsg Exp $ */
/*
* Copyright (c) 2013 Jonathan Gray <jsg@openbsd.org>
* Copyright (c) 2015, 2016 Mark Kettenis <kettenis@openbsd.org>
/* if prev is a chain */
if (to_dma_fence_chain(prev) != NULL) {
- if (seqno > prev->seqno) {
+ if (__dma_fence_is_later(seqno, prev->seqno, prev->ops)) {
chain->prev_seqno = prev->seqno;
context = prev->context;
} else {
.enable_signaling = dma_fence_chain_enable_signaling,
.signaled = dma_fence_chain_signaled,
.release = dma_fence_chain_release,
+ .use_64bit_seqno = true,
};
int
bool (*signaled)(struct dma_fence *);
long (*wait)(struct dma_fence *, bool, long);
void (*release)(struct dma_fence *);
+ bool use_64bit_seqno;
};
struct dma_fence_cb;
free(fence, M_DRM, 0);
}
+/*
+ * is a later than b
+ * if a and b are the same, should return false to avoid unwanted work
+ */
+static inline bool
+__dma_fence_is_later(uint64_t a, uint64_t b, const struct dma_fence_ops *ops)
+{
+ uint32_t al, bl;
+
+ if (ops->use_64bit_seqno)
+ return a > b;
+
+ al = a & 0xffffffff;
+ bl = b & 0xffffffff;
+
+ return (int)(al - bl) > 0;
+}
+
static inline bool
dma_fence_is_later(struct dma_fence *a, struct dma_fence *b)
{
- return (a->seqno > b->seqno);
+ if (a->context != b->context)
+ return false;
+ return __dma_fence_is_later(a->seqno, b->seqno, a->ops);
}
static inline void