summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2018-02-25 10:18:02 +0000
committerhselasky <hselasky@FreeBSD.org>2018-02-25 10:18:02 +0000
commit3aba0a58657077eb5f2be3deee1dfd7d718bf914 (patch)
tree81728d5781665e0b0bf677b481ef60b03d5c0bec
parent7e32a4a5b06a53e8c7f60a7a74ad95c77be3cfe6 (diff)
downloadFreeBSD-src-3aba0a58657077eb5f2be3deee1dfd7d718bf914.zip
FreeBSD-src-3aba0a58657077eb5f2be3deee1dfd7d718bf914.tar.gz
MFC r329376:
Implement tasklet_enable() and tasklet_disable() in the LinuxKPI. Requested by: Johannes Lundberg <johalun0@gmail.com> Sponsored by: Mellanox Technologies
-rw-r--r--sys/compat/linuxkpi/common/include/linux/interrupt.h2
-rw-r--r--sys/compat/linuxkpi/common/src/linux_tasklet.c19
2 files changed, 21 insertions, 0 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/interrupt.h b/sys/compat/linuxkpi/common/include/linux/interrupt.h
index e9bae51..0d9a665 100644
--- a/sys/compat/linuxkpi/common/include/linux/interrupt.h
+++ b/sys/compat/linuxkpi/common/include/linux/interrupt.h
@@ -200,5 +200,7 @@ extern void tasklet_schedule(struct tasklet_struct *);
extern void tasklet_kill(struct tasklet_struct *);
extern void tasklet_init(struct tasklet_struct *, tasklet_func_t *,
unsigned long data);
+extern void tasklet_enable(struct tasklet_struct *);
+extern void tasklet_disable(struct tasklet_struct *);
#endif /* _LINUX_INTERRUPT_H_ */
diff --git a/sys/compat/linuxkpi/common/src/linux_tasklet.c b/sys/compat/linuxkpi/common/src/linux_tasklet.c
index 5fe9455..549af86 100644
--- a/sys/compat/linuxkpi/common/src/linux_tasklet.c
+++ b/sys/compat/linuxkpi/common/src/linux_tasklet.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#define TASKLET_ST_BUSY 1
#define TASKLET_ST_EXEC 2
#define TASKLET_ST_LOOP 3
+#define TASKLET_ST_PAUSED 4
#define TASKLET_ST_CMPSET(ts, old, new) \
atomic_cmpset_ptr((volatile uintptr_t *)&(ts)->entry.tqe_prev, old, new)
@@ -196,3 +197,21 @@ tasklet_kill(struct tasklet_struct *ts)
while (TASKLET_ST_GET(ts) != TASKLET_ST_IDLE)
pause("W", 1);
}
+
+void
+tasklet_enable(struct tasklet_struct *ts)
+{
+ (void) TASKLET_ST_CMPSET(ts, TASKLET_ST_PAUSED, TASKLET_ST_IDLE);
+}
+
+void
+tasklet_disable(struct tasklet_struct *ts)
+{
+ while (1) {
+ if (TASKLET_ST_GET(ts) == TASKLET_ST_PAUSED)
+ break;
+ if (TASKLET_ST_CMPSET(ts, TASKLET_ST_IDLE, TASKLET_ST_PAUSED))
+ break;
+ pause("W", 1);
+ }
+}
OpenPOWER on IntegriCloud