[API-NEXT,4/4] linix-gen: pktio ipc: fix race with start 2 process at the same time

Message ID 1476995190-7548-5-git-send-email-maxim.uvarov@linaro.org
State New
Headers show

Commit Message

Maxim Uvarov Oct. 20, 2016, 8:26 p.m.
Fix race when 2 process start at the same time with delay slave until
master will allow to map it's shared rings

Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>

---
 .../include/odp_packet_io_ipc_internal.h           |  2 ++
 platform/linux-generic/pktio/ipc.c                 |  7 ++++
 test/linux-generic/pktio_ipc/pktio_ipc1.c          | 42 +++++++++++++---------
 test/linux-generic/pktio_ipc/pktio_ipc2.c          | 35 ++++++++++++++----
 test/linux-generic/pktio_ipc/pktio_ipc_run.sh      |  4 ---
 5 files changed, 63 insertions(+), 27 deletions(-)

-- 
2.7.1.250.gff4ea60

Patch

diff --git a/platform/linux-generic/include/odp_packet_io_ipc_internal.h b/platform/linux-generic/include/odp_packet_io_ipc_internal.h
index 1190e1e..0f3e6ea 100644
--- a/platform/linux-generic/include/odp_packet_io_ipc_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_ipc_internal.h
@@ -34,6 +34,8 @@  struct pktio_info {
 		 * to pool_mdata_addr (odp-linux pool specific) */
 		size_t mdata_offset;
 		char pool_name[ODP_POOL_NAME_LEN];
+		/* 1 if master finished creation of all shared objects */
+		int init_done;
 	} master;
 	struct {
 		/* offset from shared memory block start
diff --git a/platform/linux-generic/pktio/ipc.c b/platform/linux-generic/pktio/ipc.c
index 490abc5..669737b 100644
--- a/platform/linux-generic/pktio/ipc.c
+++ b/platform/linux-generic/pktio/ipc.c
@@ -155,6 +155,7 @@  static int _ipc_init_master(pktio_entry_t *pktio_entry,
 	pktio_entry->s.ipc.pool = pool;
 
 	ODP_DBG("Pre init... DONE.\n");
+	pinfo->master.init_done = 1;
 
 	_ipc_master_start(pktio_entry);
 
@@ -363,6 +364,11 @@  static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
 		if (ODP_SHM_INVALID == shm)
 			return -1;
 		pinfo = odp_shm_addr(shm);
+
+		if (!pinfo->master.init_done) {
+			odp_shm_free(shm);
+			return -1;
+		}
 		pktio_entry->s.ipc.pinfo = pinfo;
 		pktio_entry->s.ipc.pinfo_shm = shm;
 		ODP_DBG("process %d is slave\n", getpid());
@@ -379,6 +385,7 @@  static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
 		}
 
 		pinfo = odp_shm_addr(shm);
+		pinfo->master.init_done = 0;
 		pinfo->master.pool_name[0] = 0;
 		pktio_entry->s.ipc.pinfo = pinfo;
 		pktio_entry->s.ipc.pinfo_shm = shm;
diff --git a/test/linux-generic/pktio_ipc/pktio_ipc1.c b/test/linux-generic/pktio_ipc/pktio_ipc1.c
index 654b506..4f85b1d 100644
--- a/test/linux-generic/pktio_ipc/pktio_ipc1.c
+++ b/test/linux-generic/pktio_ipc/pktio_ipc1.c
@@ -25,7 +25,7 @@  static int pktio_run_loop(odp_pool_t pool)
 {
 	int thr;
 	int pkts;
-	odp_pktio_t ipc_pktio;
+	odp_pktio_t ipc_pktio = ODP_PKTIO_INVALID;
 	odp_packet_t pkt_tbl[MAX_PKT_BURST];
 	uint64_t cnt = 0; /* increasing counter on each send packet */
 	uint64_t cnt_recv = 0; /* increasing counter to validate
@@ -51,19 +51,34 @@  static int pktio_run_loop(odp_pool_t pool)
 	else
 		sprintf(name, TEST_IPC_PKTIO_NAME);
 
-	ipc_pktio = odp_pktio_lookup(name);
-	if (ipc_pktio == ODP_PKTIO_INVALID) {
-		EXAMPLE_ERR("  [%02i] Error: lookup of pktio %s failed\n",
-			    thr, "ipc_pktio");
-		return -2;
-	}
-	printf("  [%02i] looked up ipc_pktio:%02" PRIu64 ", burst mode\n",
-	       thr, odp_pktio_to_u64(ipc_pktio));
-
 	wait = odp_time_local_from_ns(run_time_sec * ODP_TIME_SEC_IN_NS);
 	start_cycle = odp_time_local();
 	current_cycle = start_cycle;
 
+	/* slave process should always be run after master process to be
+	 * able to create the same pktio.
+	 */
+	for (;;) {
+		if (run_time_sec) {
+			cycle = odp_time_local();
+			diff = odp_time_diff(cycle, start_cycle);
+			if (odp_time_cmp(wait, diff) < 0) {
+				printf("timeout exit, run_time_sec %d\n",
+				       run_time_sec);
+				return -1;
+			}
+		}
+
+		ipc_pktio = create_pktio(pool, master_pid);
+		if (ipc_pktio != ODP_PKTIO_INVALID)
+			break;
+		if (!master_pid)
+			break;
+	}
+
+	if (ipc_pktio == ODP_PKTIO_INVALID)
+		return -1;
+
 	if (odp_pktin_queue(ipc_pktio, &pktin, 1) != 1) {
 		EXAMPLE_ERR("no input queue\n");
 		return -1;
@@ -320,12 +335,7 @@  int main(int argc, char *argv[])
 
 	odp_pool_print(pool);
 
-	if (create_pktio(pool, master_pid) == ODP_PKTIO_INVALID) {
-		ret = -1;
-		/* skip the test */
-	} else {
-		ret = pktio_run_loop(pool);
-	}
+	ret = pktio_run_loop(pool);
 
 	if (odp_pool_destroy(pool)) {
 		EXAMPLE_ERR("Error: odp_pool_destroy() failed.\n");
diff --git a/test/linux-generic/pktio_ipc/pktio_ipc2.c b/test/linux-generic/pktio_ipc/pktio_ipc2.c
index 74cc137..18804c6 100644
--- a/test/linux-generic/pktio_ipc/pktio_ipc2.c
+++ b/test/linux-generic/pktio_ipc/pktio_ipc2.c
@@ -18,7 +18,7 @@ 
 
 static int ipc_second_process(int master_pid)
 {
-	odp_pktio_t ipc_pktio;
+	odp_pktio_t ipc_pktio = ODP_PKTIO_INVALID;
 	odp_pool_param_t params;
 	odp_pool_t pool;
 	odp_packet_t pkt_tbl[MAX_PKT_BURST];
@@ -46,15 +46,36 @@  static int ipc_second_process(int master_pid)
 		exit(EXIT_FAILURE);
 	}
 
-	ipc_pktio = create_pktio(pool, master_pid);
-	if (ipc_pktio == ODP_PKTIO_INVALID) {
-		odp_pool_destroy(pool);
-		return -1;
-	}
-
 	wait = odp_time_local_from_ns(run_time_sec * ODP_TIME_SEC_IN_NS);
 	start_cycle = odp_time_local();
 
+	/* slave process should always be run after master process to be
+	 * able to create the same pktio.
+	 */
+	for (;;) {
+		/*  exit loop if time specified */
+		if (run_time_sec) {
+			cycle = odp_time_local();
+			diff = odp_time_diff(cycle, start_cycle);
+			if (odp_time_cmp(wait, diff) < 0) {
+				printf("timeout exit, run_time_sec %d\n",
+				       run_time_sec);
+				goto not_started;
+			}
+		}
+
+		ipc_pktio = create_pktio(pool, master_pid);
+		if (ipc_pktio != ODP_PKTIO_INVALID)
+			break;
+		if (!master_pid)
+			break;
+	}
+
+	if (ipc_pktio == ODP_PKTIO_INVALID) {
+		odp_pool_destroy(pool);
+		return -1;
+	}
+
 	if (odp_pktin_queue(ipc_pktio, &pktin, 1) != 1) {
 		odp_pool_destroy(pool);
 		EXAMPLE_ERR("no input queue\n");
diff --git a/test/linux-generic/pktio_ipc/pktio_ipc_run.sh b/test/linux-generic/pktio_ipc/pktio_ipc_run.sh
index 433b7c4..3cd28f5 100755
--- a/test/linux-generic/pktio_ipc/pktio_ipc_run.sh
+++ b/test/linux-generic/pktio_ipc/pktio_ipc_run.sh
@@ -27,8 +27,6 @@  run()
 	echo "==== run pktio_ipc1 then pktio_ipc2 ===="
 	pktio_ipc1${EXEEXT} -t 30 &
 	IPC_PID=$!
-	sleep 1 #prevent race: master has to create objects, no
-		# fight for resources
 
 	pktio_ipc2${EXEEXT} -p ${IPC_PID} -t 10
 	ret=$?
@@ -53,8 +51,6 @@  run()
 	echo "==== run pktio_ipc2 then pktio_ipc1 ===="
 	pktio_ipc2${EXEEXT} -t 20 &
 	IPC_PID=$!
-	sleep 1 #prevent race: master has to create objects, no
-		# fight for resources
 
 	pktio_ipc1${EXEEXT} -p ${IPC_PID} -t 10
 	ret=$?