On 28-Feb-18 1:09 AM, Tan, Jianfeng wrote:
-----Original Message-----
From: Burakov, Anatoly
Sent: Tuesday, February 27, 2018 10:36 PM
To: dev@dpdk.org
Cc: Tan, Jianfeng
Subject: [PATCH v3 2/5] eal: don't process IPC messages before init finished
It is not possible for a primary process to receive any messages
while initializing, because RTE_MAGIC value is not set in the
shared config, and hence no secondary process can ever spin up
during that time.
However, it is possible for a secondary process to receive messages
from the primary during initialization. We can't just drop the
messages as they may be important, and also we might need to process
replies to our own requests (e.g. VFIO) during initialization.
Therefore, add a tailq for incoming messages, and queue them up
until initialization is complete, and process them in order they
arrived.
Signed-off-by: Anatoly Burakov <anatoly.bura...@intel.com>
---
Notes:
v3: check for init_complete after receiving message
v2: no changes
lib/librte_eal/common/eal_common_proc.c | 52
+++++++++++++++++++++++++++++----
1 file changed, 47 insertions(+), 5 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_proc.c
b/lib/librte_eal/common/eal_common_proc.c
index 3a1088e..a6e24e6 100644
--- a/lib/librte_eal/common/eal_common_proc.c
+++ b/lib/librte_eal/common/eal_common_proc.c
@@ -25,6 +25,7 @@
#include <rte_errno.h>
#include <rte_lcore.h>
#include <rte_log.h>
+#include <rte_tailq.h>
#include "eal_private.h"
#include "eal_filesystem.h"
@@ -58,6 +59,18 @@ struct mp_msg_internal {
struct rte_mp_msg msg;
};
+struct message_queue_entry {
+ TAILQ_ENTRY(message_queue_entry) next;
+ struct mp_msg_internal msg;
+ struct sockaddr_un sa;
+};
+
+/** Double linked list of received messages. */
+TAILQ_HEAD(message_queue, message_queue_entry);
+
+static struct message_queue message_queue =
+ TAILQ_HEAD_INITIALIZER(message_queue);
+
struct sync_request {
TAILQ_ENTRY(sync_request) next;
int reply_received;
@@ -276,12 +289,41 @@ process_msg(struct mp_msg_internal *m, struct
sockaddr_un *s)
static void *
mp_handle(void *arg __rte_unused)
{
- struct mp_msg_internal msg;
- struct sockaddr_un sa;
-
+ struct message_queue_entry *cur_msg, *next_msg, *new_msg =
NULL;
while (1) {
- if (read_msg(&msg, &sa) == 0)
- process_msg(&msg, &sa);
+ /* we want to process all messages in order of their arrival,
+ * but status of init_complete may change while we're
iterating
+ * the tailq. so, store it here and check once every iteration.
+ */
+ int init_complete;
+
+ if (new_msg == NULL)
+ new_msg = malloc(sizeof(*new_msg));
+ if (read_msg(&new_msg->msg, &new_msg->sa) == 0) {
Suppose a case that: req and msg received but init not completed, so we enqueue
all of them in the tailq; and from now on, no req/rep/msg comes. Then mp thread
will hang here for reading new message.
In such a case, we might need the master thread to signal mp thread to wake up
when init is completed?
True. Will have to think about how to do that.
--
Thanks,
Anatoly