Module Name: src Committed By: riastradh Date: Sun Dec 19 01:15:28 UTC 2021
Modified Files: src/sys/external/bsd/drm2/include/linux: dma-fence.h src/sys/external/bsd/drm2/linux: linux_dma_fence.c Log Message: Add dma_fence_get_rcu_safe. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/external/bsd/drm2/include/linux/dma-fence.h cvs rdiff -u -r1.2 -r1.3 src/sys/external/bsd/drm2/linux/linux_dma_fence.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/include/linux/dma-fence.h diff -u src/sys/external/bsd/drm2/include/linux/dma-fence.h:1.2 src/sys/external/bsd/drm2/include/linux/dma-fence.h:1.3 --- src/sys/external/bsd/drm2/include/linux/dma-fence.h:1.2 Sun Dec 19 00:27:17 2021 +++ src/sys/external/bsd/drm2/include/linux/dma-fence.h Sun Dec 19 01:15:28 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: dma-fence.h,v 1.2 2021/12/19 00:27:17 riastradh Exp $ */ +/* $NetBSD: dma-fence.h,v 1.3 2021/12/19 01:15:28 riastradh Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -112,6 +112,8 @@ struct dma_fence * dma_fence_get(struct dma_fence *); struct dma_fence * dma_fence_get_rcu(struct dma_fence *); +struct dma_fence * + dma_fence_get_rcu_safe(struct dma_fence **); void dma_fence_put(struct dma_fence *); int dma_fence_add_callback(struct dma_fence *, struct dma_fence_cb *, Index: src/sys/external/bsd/drm2/linux/linux_dma_fence.c diff -u src/sys/external/bsd/drm2/linux/linux_dma_fence.c:1.2 src/sys/external/bsd/drm2/linux/linux_dma_fence.c:1.3 --- src/sys/external/bsd/drm2/linux/linux_dma_fence.c:1.2 Sun Dec 19 00:27:17 2021 +++ src/sys/external/bsd/drm2/linux/linux_dma_fence.c Sun Dec 19 01:15:28 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_dma_fence.c,v 1.2 2021/12/19 00:27:17 riastradh Exp $ */ +/* $NetBSD: linux_dma_fence.c,v 1.3 2021/12/19 01:15:28 riastradh Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux_dma_fence.c,v 1.2 2021/12/19 00:27:17 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_dma_fence.c,v 1.3 2021/12/19 01:15:28 riastradh Exp $"); #include <sys/atomic.h> #include <sys/condvar.h> @@ -201,6 +201,52 @@ dma_fence_get_rcu(struct dma_fence *fenc return fence; } +/* + * dma_fence_get_rcu_safe(fencep) + * + * Attempt to acquire a reference to the fence *fencep, which may + * be about to be destroyed, during a read section. If the value + * of *fencep changes after we read *fencep but before we + * increment its reference count, retry. Return *fencep on + * success, or NULL on failure. + */ +struct dma_fence * +dma_fence_get_rcu_safe(struct dma_fence **fencep) +{ + struct dma_fence *fence, *fence0; + +retry: + fence = *fencep; + + /* Load fence only once. */ + __insn_barrier(); + + /* If there's nothing there, give up. */ + if (fence == NULL) + return NULL; + + /* Make sure we don't load stale fence guts. */ + membar_datadep_consumer(); + + /* Try to acquire a reference. If we can't, try again. */ + if (!dma_fence_get_rcu(fence)) + goto retry; + + /* + * Confirm that it's still the same fence. If not, release it + * and retry. + */ + fence0 = *fencep; + __insn_barrier(); + if (fence != fence0) { + dma_fence_put(fence); + goto retry; + } + + /* Success! */ + return fence; +} + static void dma_fence_release(struct kref *refcount) {