[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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.