Module Name: src Committed By: riastradh Date: Sun Dec 19 11:04:58 UTC 2021
Modified Files: src/sys/external/bsd/common/linux: linux_tasklet.c Log Message: Fix membars in tasklet_disable/enable. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/sys/external/bsd/common/linux/linux_tasklet.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/common/linux/linux_tasklet.c diff -u src/sys/external/bsd/common/linux/linux_tasklet.c:1.5 src/sys/external/bsd/common/linux/linux_tasklet.c:1.6 --- src/sys/external/bsd/common/linux/linux_tasklet.c:1.5 Sun Dec 19 11:03:18 2021 +++ src/sys/external/bsd/common/linux/linux_tasklet.c Sun Dec 19 11:04:58 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_tasklet.c,v 1.5 2021/12/19 11:03:18 riastradh Exp $ */ +/* $NetBSD: linux_tasklet.c,v 1.6 2021/12/19 11:04:58 riastradh Exp $ */ /*- * Copyright (c) 2018, 2020 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux_tasklet.c,v 1.5 2021/12/19 11:03:18 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_tasklet.c,v 1.6 2021/12/19 11:04:58 riastradh Exp $"); #include <sys/types.h> #include <sys/atomic.h> @@ -373,6 +373,11 @@ tasklet_disable(struct tasklet_struct *t KASSERT(disablecount < UINT_MAX); KASSERT(disablecount != 0); + /* Pairs with membar_exit in __tasklet_enable. */ +#ifndef __HAVE_ATOMIC_AS_MEMBAR + membar_enter(); +#endif + /* Wait for it to finish running, if it was running. */ tasklet_unlock_wait(tasklet); } @@ -457,13 +462,17 @@ tasklet_trylock(struct tasklet_struct *t unsigned state; do { - /* Pairs with membar_exit in tasklet_unlock. */ - state = atomic_load_acquire(&tasklet->tl_state); + state = atomic_load_relaxed(&tasklet->tl_state); if (state & TASKLET_RUNNING) return false; } while (atomic_cas_uint(&tasklet->tl_state, state, state | TASKLET_RUNNING) != state); + /* Pairs with membar_exit in tasklet_unlock. */ +#ifndef __HAVE_ATOMIC_AS_MEMBAR + membar_enter(); +#endif + return true; } @@ -481,8 +490,8 @@ tasklet_unlock(struct tasklet_struct *ta KASSERT(atomic_load_relaxed(&tasklet->tl_state) & TASKLET_RUNNING); /* - * Pairs with atomic_load_acquire in tasklet_trylock and - * tasklet_unlock. + * Pairs with membar_enter in tasklet_trylock and with + * atomic_load_acquire in tasklet_unlock_wait. */ #ifndef __HAVE_ATOMIC_AS_MEMBAR membar_exit(); @@ -534,6 +543,11 @@ __tasklet_disable_sync_once(struct taskl KASSERT(disablecount < UINT_MAX); KASSERT(disablecount != 0); + /* Pairs with membar_exit in __tasklet_enable_sync_once. */ +#ifndef __HAVE_ATOMIC_AS_MEMBAR + membar_enter(); +#endif + /* * If it was zero, wait for it to finish running. If it was * not zero, caller must not care whether it was running. @@ -553,6 +567,11 @@ __tasklet_enable_sync_once(struct taskle { unsigned int disablecount; + /* Pairs with membar_enter in __tasklet_disable_sync_once. */ +#ifndef __HAVE_ATOMIC_AS_MEMBAR + membar_exit(); +#endif + /* Decrement the disable count. */ disablecount = atomic_dec_uint_nv(&tasklet->tl_disablecount); KASSERT(disablecount < UINT_MAX); @@ -615,8 +634,8 @@ __tasklet_enable(struct tasklet_struct * * before potentially allowing tasklet to run again by * decrementing the disable count. * - * Pairs with atomic_load_acquire(&tasklet->tl_disablecount) in - * tasklet_softintr. + * Pairs with atomic_load_acquire in tasklet_softintr and with + * membar_enter in tasklet_disable. */ #ifndef __HAVE_ATOMIC_AS_MEMBAR membar_exit();