|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH] Made ukmpi and uklock interrupt-context-safe
From: Cristian Vijelie <cristianvijelie@xxxxxxxxx>
For semaphore and mutex, the only change needed for now was to create some
aliases to some inlined functions, that can be called in an interupt context,
in 'uk/isr/mutex.h' and 'uk/isr/semaphore.h'.
For mbox, I moved the functions that can be called in an interupt context to
a separate sorce file, 'mbox_isr.c', and I also moved some static inlined
functions needed by both mbox and mbox_isr in the mbox.h header, along with
th definition of struct uk_mbox.
Signed-off-by: Cristian Vijelie <cristianvijelie@xxxxxxxxx>
---
include/uk/isr/mbox.h | 13 +++++++++
include/uk/isr/mutex.h | 8 ++++++
include/uk/isr/semaphore.h | 8 ++++++
lib/ukmpi/Makefile.uk | 1 +
lib/ukmpi/include/uk/mbox.h | 54 ++++++++++++++++++++++++++++++++++++-
lib/ukmpi/mbox.c | 54 -------------------------------------
lib/ukmpi/mbox_isr.c | 39 +++++++++++++++++++++++++++
7 files changed, 122 insertions(+), 55 deletions(-)
create mode 100644 include/uk/isr/mbox.h
create mode 100644 include/uk/isr/mutex.h
create mode 100644 include/uk/isr/semaphore.h
create mode 100644 lib/ukmpi/mbox_isr.c
diff --git a/include/uk/isr/mbox.h b/include/uk/isr/mbox.h
new file mode 100644
index 0000000..ef70939
--- /dev/null
+++ b/include/uk/isr/mbox.h
@@ -0,0 +1,13 @@
+#ifndef __MBOX_ISR_H__
+#define __MBOX_ISR_H__
+
+#include <uk/mbox.h>
+
+#if CONFIG_LIBUKMPI_MBOX
+
+int uk_mbox_post_try_isr(struct uk_mbox *m, void *msg);
+int uk_mbox_recv_try_isr(struct uk_mbox *m, void **msg);
+
+#endif /* CONFIG_LIBUKMPI_MBOX */
+
+#endif /* __MBOX_ISR_H__ */
\ No newline at end of file
diff --git a/include/uk/isr/mutex.h b/include/uk/isr/mutex.h
new file mode 100644
index 0000000..06d51f8
--- /dev/null
+++ b/include/uk/isr/mutex.h
@@ -0,0 +1,8 @@
+#ifndef __UK_ISR_MUTEX_H__
+#define __UK_ISR_MUTEX_H__
+
+#include <uk/mutex.h>
+
+#define uk_mutex_trylock_isr(x) uk_mutex_trylock(x)
+
+#endif /* __UK_ISR_MUTEX_H__ */
\ No newline at end of file
diff --git a/include/uk/isr/semaphore.h b/include/uk/isr/semaphore.h
new file mode 100644
index 0000000..b187f1f
--- /dev/null
+++ b/include/uk/isr/semaphore.h
@@ -0,0 +1,8 @@
+#ifndef __UK_ISR_SEMAPHORE_H__
+#define __UK_ISR_SEMAPHORE_H__
+
+#include <uk/semaphore.h>
+
+#define uk_semaphore_down_try_isr(x) uk_semaphore_down_try(x)
+
+#endif /* __UK_ISR_SEMAPHORE_H__ */
\ No newline at end of file
diff --git a/lib/ukmpi/Makefile.uk b/lib/ukmpi/Makefile.uk
index fc8a360..49df296 100644
--- a/lib/ukmpi/Makefile.uk
+++ b/lib/ukmpi/Makefile.uk
@@ -4,3 +4,4 @@ CINCLUDES-$(CONFIG_LIBUKMPI) += -I$(LIBUKMPI_BASE)/include
CXXINCLUDES-$(CONFIG_LIBUKMPI) += -I$(LIBUKMPI_BASE)/include
LIBUKMPI_SRCS-$(CONFIG_LIBUKMPI_MBOX) += $(LIBUKMPI_BASE)/mbox.c
+LIBUKMPI_SRCS-$(CONFIG_LIBUKMPI_MBOX) += $(LIBUKMPI_BASE)/mbox_isr.c|isr
diff --git a/lib/ukmpi/include/uk/mbox.h b/lib/ukmpi/include/uk/mbox.h
index 19b1ecc..37146d6 100644
--- a/lib/ukmpi/include/uk/mbox.h
+++ b/lib/ukmpi/include/uk/mbox.h
@@ -47,7 +47,15 @@
extern "C" {
#endif /* __cplusplus */
-struct uk_mbox;
+struct uk_mbox {
+ size_t len;
+ struct uk_semaphore readsem;
+ long readpos;
+ struct uk_semaphore writesem;
+ long writepos;
+
+ void *msgs[];
+};
struct uk_mbox *uk_mbox_create(struct uk_alloc *a, size_t size);
void uk_mbox_free(struct uk_alloc *a, struct uk_mbox *m);
@@ -60,6 +68,50 @@ void uk_mbox_recv(struct uk_mbox *m, void **msg);
int uk_mbox_recv_try(struct uk_mbox *m, void **msg);
__nsec uk_mbox_recv_to(struct uk_mbox *m, void **msg, __nsec timeout);
+/* Posts the "msg" to the mailbox, internal version that actually does the
+ * post.
+ */
+static inline void _do_mbox_post(struct uk_mbox *m, void *msg)
+{
+ /* The caller got a semaphore token, so we are now allowed to increment
+ * writer, but we still need to prevent concurrency between writers
+ * (interrupt handler vs main)
+ */
+ unsigned long irqf;
+
+ UK_ASSERT(m);
+
+ irqf = ukplat_lcpu_save_irqf();
+ m->msgs[m->writepos] = msg;
+ m->writepos = (m->writepos + 1) % m->len;
+ UK_ASSERT(m->readpos != m->writepos);
+ ukplat_lcpu_restore_irqf(irqf);
+ uk_pr_debug("Posted message %p to mailbox %p\n", msg, m);
+
+ uk_semaphore_up(&m->readsem);
+}
+
+/*
+ * Fetch a message from a mailbox. Internal version that actually does the
+ * fetch.
+ */
+static inline void *_do_mbox_recv(struct uk_mbox *m)
+{
+ unsigned long irqf;
+ void *ret;
+
+ uk_pr_debug("Receive message from mailbox %p\n", m);
+ irqf = ukplat_lcpu_save_irqf();
+ UK_ASSERT(m->readpos != m->writepos);
+ ret = m->msgs[m->readpos];
+ m->readpos = (m->readpos + 1) % m->len;
+ ukplat_lcpu_restore_irqf(irqf);
+
+ uk_semaphore_up(&m->writesem);
+
+ return ret;
+}
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/lib/ukmpi/mbox.c b/lib/ukmpi/mbox.c
index 149a667..b223ced 100644
--- a/lib/ukmpi/mbox.c
+++ b/lib/ukmpi/mbox.c
@@ -2,16 +2,6 @@
#include <uk/assert.h>
#include <uk/arch/limits.h>
-struct uk_mbox {
- size_t len;
- struct uk_semaphore readsem;
- long readpos;
- struct uk_semaphore writesem;
- long writepos;
-
- void *msgs[];
-};
-
struct uk_mbox *uk_mbox_create(struct uk_alloc *a, size_t size)
{
struct uk_mbox *m;
@@ -49,29 +39,6 @@ void uk_mbox_free(struct uk_alloc *a, struct uk_mbox *m)
uk_free(a, m);
}
-/* Posts the "msg" to the mailbox, internal version that actually does the
- * post.
- */
-static inline void _do_mbox_post(struct uk_mbox *m, void *msg)
-{
- /* The caller got a semaphore token, so we are now allowed to increment
- * writer, but we still need to prevent concurrency between writers
- * (interrupt handler vs main)
- */
- unsigned long irqf;
-
- UK_ASSERT(m);
-
- irqf = ukplat_lcpu_save_irqf();
- m->msgs[m->writepos] = msg;
- m->writepos = (m->writepos + 1) % m->len;
- UK_ASSERT(m->readpos != m->writepos);
- ukplat_lcpu_restore_irqf(irqf);
- uk_pr_debug("Posted message %p to mailbox %p\n", msg, m);
-
- uk_semaphore_up(&m->readsem);
-}
-
void uk_mbox_post(struct uk_mbox *m, void *msg)
{
/* The caller got a semaphore token, so we are now allowed to increment
@@ -106,27 +73,6 @@ __nsec uk_mbox_post_to(struct uk_mbox *m, void *msg, __nsec
timeout)
return ret;
}
-/*
- * Fetch a message from a mailbox. Internal version that actually does the
- * fetch.
- */
-static inline void *_do_mbox_recv(struct uk_mbox *m)
-{
- unsigned long irqf;
- void *ret;
-
- uk_pr_debug("Receive message from mailbox %p\n", m);
- irqf = ukplat_lcpu_save_irqf();
- UK_ASSERT(m->readpos != m->writepos);
- ret = m->msgs[m->readpos];
- m->readpos = (m->readpos + 1) % m->len;
- ukplat_lcpu_restore_irqf(irqf);
-
- uk_semaphore_up(&m->writesem);
-
- return ret;
-}
-
/* Blocks the thread until a message arrives in the mailbox.
* The `*msg` argument will point to the received message.
* If the `msg` parameter was set to NULL, the received message is dropped.
diff --git a/lib/ukmpi/mbox_isr.c b/lib/ukmpi/mbox_isr.c
new file mode 100644
index 0000000..43cd516
--- /dev/null
+++ b/lib/ukmpi/mbox_isr.c
@@ -0,0 +1,39 @@
+#include <uk/isr/mbox.h>
+#include <uk/assert.h>
+
+int uk_mbox_post_try_isr(struct uk_mbox *m, void *msg)
+{
+ UK_ASSERT(m);
+
+ if (!uk_semaphore_down_try(&m->writesem))
+ return -ENOBUFS;
+ _do_mbox_post(m, msg);
+ return 0;
+}
+
+/* This is similar to uk_mbox_fetch, however if a message is not
+ * present in the mailbox, it immediately returns with the code
+ * SYS_MBOX_EMPTY. On success 0 is returned.
+ *
+ * To allow for efficient implementations, this can be defined as a
+ * function-like macro in sys_arch.h instead of a normal function. For
+ * example, a naive implementation could be:
+ * #define uk_mbox_tryfetch(mbox,msg) \
+ * uk_mbox_fetch(mbox,msg,1)
+ * although this would introduce unnecessary delays.
+ */
+
+int uk_mbox_recv_try_isr(struct uk_mbox *m, void **msg)
+{
+ void *rmsg;
+
+ UK_ASSERT(m);
+
+ if (!uk_semaphore_down_try(&m->readsem))
+ return -ENOMSG;
+
+ rmsg = _do_mbox_recv(m);
+ if (msg)
+ *msg = rmsg;
+ return 0;
+}
\ No newline at end of file
--
2.25.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |