@@ -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
@@ -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;
@@ -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");
@@ -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");
@@ -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=$?
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