From bcd4d0b591146f9234d5977ee66a641622733862 Mon Sep 17 00:00:00 2001 From: jsg Date: Fri, 16 Sep 2022 01:48:07 +0000 Subject: [PATCH] mask non-chain fence sequence numbers to 32-bit for comparisons Most of drm uses 32-bit sequence numbers in fences. dma-fence-chain opts into 64-bit comparisons. Wrapping is handled like i915_seqno_passed() except that if the sequence numbers are the same one is not considered later than the other. --- sys/dev/pci/drm/drm_linux.c | 5 +++-- sys/dev/pci/drm/include/linux/dma-fence.h | 23 ++++++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/sys/dev/pci/drm/drm_linux.c b/sys/dev/pci/drm/drm_linux.c index 16ff64f1824..2b975cda9fb 100644 --- a/sys/dev/pci/drm/drm_linux.c +++ b/sys/dev/pci/drm/drm_linux.c @@ -1,4 +1,4 @@ -/* $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 * Copyright (c) 2015, 2016 Mark Kettenis @@ -2084,7 +2084,7 @@ dma_fence_chain_init(struct dma_fence_chain *chain, struct dma_fence *prev, /* 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 { @@ -2240,6 +2240,7 @@ const struct dma_fence_ops dma_fence_chain_ops = { .enable_signaling = dma_fence_chain_enable_signaling, .signaled = dma_fence_chain_signaled, .release = dma_fence_chain_release, + .use_64bit_seqno = true, }; int diff --git a/sys/dev/pci/drm/include/linux/dma-fence.h b/sys/dev/pci/drm/include/linux/dma-fence.h index 39220dc54f5..06d2cb644a3 100644 --- a/sys/dev/pci/drm/include/linux/dma-fence.h +++ b/sys/dev/pci/drm/include/linux/dma-fence.h @@ -41,6 +41,7 @@ struct dma_fence_ops { 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; @@ -84,10 +85,30 @@ dma_fence_free(struct dma_fence *fence) 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 -- 2.20.1