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();