@@ -51,7 +51,6 @@ struct odp_global_data_s {
odp_cpumask_t control_cpus;
odp_cpumask_t worker_cpus;
int num_cpus_installed;
- int ipc_ns;
};
enum init_stage {
@@ -43,6 +43,10 @@ struct pktio_info {
* (odp-linux pool specific) */
size_t mdata_offset;
char pool_name[ODP_POOL_NAME_LEN];
+ /* pid of the slave process written to shm and
+ * used by master to look up memory created by
+ * slave
+ */
int pid;
} slave;
} ODP_PACKED;
@@ -15,12 +15,10 @@ struct odp_global_data_s odp_global_data;
int odp_init_global(odp_instance_t *instance,
const odp_init_t *params,
- const odp_platform_init_t *platform_params)
+ const odp_platform_init_t *platform_params ODP_UNUSED)
{
memset(&odp_global_data, 0, sizeof(struct odp_global_data_s));
odp_global_data.main_pid = getpid();
- if (platform_params)
- odp_global_data.ipc_ns = platform_params->ipc_ns;
enum init_stage stage = NO_INIT;
odp_global_data.log_fn = odp_override_log;
@@ -35,44 +35,6 @@ static const char *_ipc_odp_buffer_pool_shm_name(odp_pool_t pool_hdl)
return info.name;
}
-static int _ipc_map_pktio_info(pktio_entry_t *pktio_entry,
- const char *dev,
- int *slave)
-{
- struct pktio_info *pinfo;
- char name[ODP_POOL_NAME_LEN + sizeof("_info")];
- uint32_t flags;
- odp_shm_t shm;
-
- /* Create info about remote pktio */
- snprintf(name, sizeof(name), "%s_info", dev);
-
- flags = ODP_SHM_PROC | _ODP_SHM_O_EXCL;
-
- shm = odp_shm_reserve_exported(name, odp_global_data.ipc_ns,
- name, 4096, 0);
- if (ODP_SHM_INVALID == shm) {
- flags = ODP_SHM_EXPORT | ODP_SHM_LOCK;
- shm = odp_shm_reserve(name, sizeof(struct pktio_info),
- ODP_CACHE_LINE_SIZE,
- flags);
- if (ODP_SHM_INVALID == shm)
- ODP_ABORT("can not create shm %s\n", name);
-
- pinfo = odp_shm_addr(shm);
- pinfo->master.pool_name[0] = 0;
- *slave = 0;
- } else {
- pinfo = odp_shm_addr(shm);
- *slave = 1;
- }
-
- pktio_entry->s.ipc.pinfo = pinfo;
- pktio_entry->s.ipc.pinfo_shm = shm;
-
- return 0;
-}
-
static int _ipc_master_start(pktio_entry_t *pktio_entry)
{
struct pktio_info *pinfo = pktio_entry->s.ipc.pinfo;
@@ -250,11 +212,11 @@ static void *_ipc_map_remote_pool(const char *name, size_t size, int pid)
return addr;
}
-static void *_ipc_shm_map(char *name, size_t size ODP_UNUSED)
+static void *_ipc_shm_map(char *name, int pid)
{
odp_shm_t shm;
- shm = odp_shm_reserve_exported(name, odp_global_data.ipc_ns,
+ shm = odp_shm_reserve_exported(name, pid,
name, 4096, 0);
if (ODP_SHM_INVALID == shm) {
ODP_ERR("unable to map: %s\n", name);
@@ -278,15 +240,22 @@ static int _ipc_init_slave(const char *dev,
static int _ipc_slave_start(pktio_entry_t *pktio_entry)
{
char ipc_shm_name[ODP_POOL_NAME_LEN + sizeof("_slave_r")];
- size_t ring_size = PKTIO_IPC_ENTRIES * sizeof(void *) +
- sizeof(_ring_t);
struct pktio_info *pinfo;
void *ipc_pool_base;
odp_shm_t shm;
- const char *dev = pktio_entry->s.name;
+ char tail[ODP_POOL_NAME_LEN];
+ char dev[ODP_POOL_NAME_LEN];
+ int pid;
+
+ if (sscanf(pktio_entry->s.name, "ipc:%d:%s", &pid, tail) != 2) {
+ ODP_ERR("wrong pktio name\n");
+ return -1;
+ }
+
+ sprintf(dev, "ipc:%s", tail);
snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_prod", dev);
- pktio_entry->s.ipc.rx.recv = _ipc_shm_map(ipc_shm_name, ring_size);
+ pktio_entry->s.ipc.rx.recv = _ipc_shm_map(ipc_shm_name, pid);
if (!pktio_entry->s.ipc.rx.recv) {
ODP_DBG("pid %d unable to find ipc ring %s name\n",
getpid(), dev);
@@ -298,7 +267,7 @@ static int _ipc_slave_start(pktio_entry_t *pktio_entry)
_ring_free_count(pktio_entry->s.ipc.rx.recv));
snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_cons", dev);
- pktio_entry->s.ipc.rx.free = _ipc_shm_map(ipc_shm_name, ring_size);
+ pktio_entry->s.ipc.rx.free = _ipc_shm_map(ipc_shm_name, pid);
if (!pktio_entry->s.ipc.rx.free) {
ODP_DBG("pid %d unable to find ipc ring %s name\n",
getpid(), dev);
@@ -309,7 +278,7 @@ static int _ipc_slave_start(pktio_entry_t *pktio_entry)
_ring_free_count(pktio_entry->s.ipc.rx.free));
snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_prod", dev);
- pktio_entry->s.ipc.tx.send = _ipc_shm_map(ipc_shm_name, ring_size);
+ pktio_entry->s.ipc.tx.send = _ipc_shm_map(ipc_shm_name, pid);
if (!pktio_entry->s.ipc.tx.send) {
ODP_DBG("pid %d unable to find ipc ring %s name\n",
getpid(), dev);
@@ -320,7 +289,7 @@ static int _ipc_slave_start(pktio_entry_t *pktio_entry)
_ring_free_count(pktio_entry->s.ipc.tx.send));
snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_cons", dev);
- pktio_entry->s.ipc.tx.free = _ipc_shm_map(ipc_shm_name, ring_size);
+ pktio_entry->s.ipc.tx.free = _ipc_shm_map(ipc_shm_name, pid);
if (!pktio_entry->s.ipc.tx.free) {
ODP_DBG("pid %d unable to find ipc ring %s name\n",
getpid(), dev);
@@ -334,7 +303,7 @@ static int _ipc_slave_start(pktio_entry_t *pktio_entry)
pinfo = pktio_entry->s.ipc.pinfo;
ipc_pool_base = _ipc_map_remote_pool(pinfo->master.pool_name,
pinfo->master.shm_pkt_pool_size,
- odp_global_data.ipc_ns);
+ pid);
pktio_entry->s.ipc.pool_mdata_base = (char *)ipc_pool_base +
pinfo->master.mdata_offset;
pktio_entry->s.ipc.pkt_size = pinfo->master.shm_pkt_size;
@@ -372,7 +341,11 @@ static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
odp_pool_t pool)
{
int ret = -1;
- int slave;
+ int pid ODP_UNUSED;
+ struct pktio_info *pinfo;
+ char name[ODP_POOL_NAME_LEN + sizeof("_info")];
+ char tail[ODP_POOL_NAME_LEN];
+ odp_shm_t shm;
ODP_STATIC_ASSERT(ODP_POOL_NAME_LEN == _RING_NAMESIZE,
"mismatch pool and ring name arrays");
@@ -382,16 +355,38 @@ static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
odp_atomic_init_u32(&pktio_entry->s.ipc.ready, 0);
- _ipc_map_pktio_info(pktio_entry, dev, &slave);
- pktio_entry->s.ipc.type = (slave == 0) ? PKTIO_TYPE_IPC_MASTER :
- PKTIO_TYPE_IPC_SLAVE;
+ /* Shared info about remote pktio */
+ if (sscanf(dev, "ipc:%d:%s", &pid, tail) == 2) {
+ pktio_entry->s.ipc.type = PKTIO_TYPE_IPC_SLAVE;
- if (pktio_entry->s.ipc.type == PKTIO_TYPE_IPC_MASTER) {
+ snprintf(name, sizeof(name), "ipc:%s_info", tail);
+ ODP_DBG("lookup for name %s for pid %d\n", name, pid);
+ shm = odp_shm_reserve_exported(name, pid,
+ name, 4096, 0);
+ if (ODP_SHM_INVALID == shm)
+ return -1;
+ pinfo = odp_shm_addr(shm);
+ pktio_entry->s.ipc.pinfo = pinfo;
+ pktio_entry->s.ipc.pinfo_shm = shm;
+ ODP_DBG("process %d is slave\n", getpid());
+ ret = _ipc_init_slave(name, pktio_entry, pool);
+ } else {
+ pktio_entry->s.ipc.type = PKTIO_TYPE_IPC_MASTER;
+ snprintf(name, sizeof(name), "%s_info", dev);
+ shm = odp_shm_reserve(name, sizeof(struct pktio_info),
+ ODP_CACHE_LINE_SIZE,
+ ODP_SHM_EXPORT | ODP_SHM_LOCK);
+ if (ODP_SHM_INVALID == shm) {
+ ODP_ERR("can not create shm %s\n", name);
+ return -1;
+ }
+
+ pinfo = odp_shm_addr(shm);
+ pinfo->master.pool_name[0] = 0;
+ pktio_entry->s.ipc.pinfo = pinfo;
+ pktio_entry->s.ipc.pinfo_shm = shm;
ODP_DBG("process %d is master\n", getpid());
ret = _ipc_init_master(pktio_entry, dev, pool);
- } else {
- ODP_DBG("process %d is slave\n", getpid());
- ret = _ipc_init_slave(dev, pktio_entry, pool);
}
return ret;
@@ -693,22 +688,25 @@ static int ipc_start(pktio_entry_t *pktio_entry)
static int ipc_stop(pktio_entry_t *pktio_entry)
{
- unsigned tx_send, tx_free;
+ unsigned tx_send = 0, tx_free = 0;
odp_atomic_store_u32(&pktio_entry->s.ipc.ready, 0);
- _ipc_free_ring_packets(pktio_entry->s.ipc.tx.send);
+ if (pktio_entry->s.ipc.tx.send)
+ _ipc_free_ring_packets(pktio_entry->s.ipc.tx.send);
/* other process can transfer packets from one ring to
* other, use delay here to free that packets. */
sleep(1);
- _ipc_free_ring_packets(pktio_entry->s.ipc.tx.free);
+ if (pktio_entry->s.ipc.tx.free)
+ _ipc_free_ring_packets(pktio_entry->s.ipc.tx.free);
- tx_send = _ring_count(pktio_entry->s.ipc.tx.send);
- tx_free = _ring_count(pktio_entry->s.ipc.tx.free);
+ if (pktio_entry->s.ipc.tx.send)
+ tx_send = _ring_count(pktio_entry->s.ipc.tx.send);
+ if (pktio_entry->s.ipc.tx.free)
+ tx_free = _ring_count(pktio_entry->s.ipc.tx.free);
if (tx_send | tx_free) {
ODP_DBG("IPC rings: tx send %d tx free %d\n",
- _ring_free_count(pktio_entry->s.ipc.tx.send),
- _ring_free_count(pktio_entry->s.ipc.tx.free));
+ tx_send, tx_free);
}
return 0;
@@ -8,7 +8,8 @@
/** Run time in seconds */
int run_time_sec;
-int ipc_name_space;
+/** Pid of the master process */
+int master_pid;
int ipc_odp_packet_send_or_free(odp_pktio_t pktio,
odp_packet_t pkt_tbl[], int num)
@@ -50,17 +51,25 @@ int ipc_odp_packet_send_or_free(odp_pktio_t pktio,
return 0;
}
-odp_pktio_t create_pktio(odp_pool_t pool)
+odp_pktio_t create_pktio(odp_pool_t pool, int master_pid)
{
odp_pktio_param_t pktio_param;
odp_pktio_t ipc_pktio;
+ char name[30];
odp_pktio_param_init(&pktio_param);
- printf("pid: %d, create IPC pktio\n", getpid());
- ipc_pktio = odp_pktio_open("ipc_pktio", pool, &pktio_param);
- if (ipc_pktio == ODP_PKTIO_INVALID)
- EXAMPLE_ABORT("Error: ipc pktio create failed.\n");
+ if (master_pid)
+ sprintf(name, TEST_IPC_PKTIO_PID_NAME, master_pid);
+ else
+ sprintf(name, TEST_IPC_PKTIO_NAME);
+
+ printf("pid: %d, create IPC pktio %s\n", getpid(), name);
+ ipc_pktio = odp_pktio_open(name, pool, &pktio_param);
+ if (ipc_pktio == ODP_PKTIO_INVALID) {
+ EXAMPLE_ERR("Error: ipc pktio %s create failed.\n", name);
+ return ODP_PKTIO_INVALID;
+ }
if (odp_pktin_queue_config(ipc_pktio, NULL)) {
EXAMPLE_ERR("Input queue config failed\n");
@@ -88,16 +97,16 @@ void parse_args(int argc, char *argv[])
int long_index;
static struct option longopts[] = {
{"time", required_argument, NULL, 't'},
- {"ns", required_argument, NULL, 'n'}, /* ipc name space */
+ {"pid", required_argument, NULL, 'p'}, /* master process pid */
{"help", no_argument, NULL, 'h'}, /* return 'h' */
{NULL, 0, NULL, 0}
};
run_time_sec = 0; /* loop forever if time to run is 0 */
- ipc_name_space = 0;
+ master_pid = 0;
while (1) {
- opt = getopt_long(argc, argv, "+t:n:h",
+ opt = getopt_long(argc, argv, "+t:p:h",
longopts, &long_index);
if (opt == -1)
@@ -107,24 +116,18 @@ void parse_args(int argc, char *argv[])
case 't':
run_time_sec = atoi(optarg);
break;
- case 'n':
- ipc_name_space = atoi(optarg);
+ case 'p':
+ master_pid = atoi(optarg);
break;
case 'h':
+ default:
usage(argv[0]);
exit(EXIT_SUCCESS);
break;
- default:
- break;
}
}
optind = 1; /* reset 'extern optind' from the getopt lib */
-
- if (!ipc_name_space) {
- usage(argv[0]);
- exit(1);
- }
}
/**
@@ -46,6 +46,9 @@
#define TEST_ALLOC_MAGIC 0x1234adcd
+#define TEST_IPC_PKTIO_NAME "ipc:ipktio"
+#define TEST_IPC_PKTIO_PID_NAME "ipc:%d:ipktio"
+
/** magic number and sequence at start of packet payload */
typedef struct ODP_PACKED {
odp_u32be_t magic;
@@ -63,8 +66,8 @@ char *pktio_name;
/** Run time in seconds */
int run_time_sec;
-/** IPC name space id /dev/shm/odp-nsid-objname */
-int ipc_name_space;
+/** PID of the master process */
+int master_pid;
/* helper funcs */
void parse_args(int argc, char *argv[]);
@@ -75,11 +78,12 @@ void usage(char *progname);
* Create a ipc pktio handle.
*
* @param pool Pool to associate with device for packet RX/TX
+ * @param master_pid Pid of master process
*
* @return The handle of the created pktio object.
* @retval ODP_PKTIO_INVALID if the create fails.
*/
-odp_pktio_t create_pktio(odp_pool_t pool);
+odp_pktio_t create_pktio(odp_pool_t pool, int master_pid);
/** Spin and send all packet from table
*
@@ -42,10 +42,16 @@ static int pktio_run_loop(odp_pool_t pool)
odp_time_t wait;
int ret;
odp_pktin_queue_t pktin;
+ char name[30];
thr = odp_thread_id();
- ipc_pktio = odp_pktio_lookup("ipc_pktio");
+ if (master_pid)
+ sprintf(name, TEST_IPC_PKTIO_PID_NAME, master_pid);
+ 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");
@@ -279,17 +285,13 @@ int main(int argc, char *argv[])
odp_pool_t pool;
odp_pool_param_t params;
odp_instance_t instance;
- odp_platform_init_t plat_idata;
int ret;
/* Parse and store the application arguments */
parse_args(argc, argv);
- memset(&plat_idata, 0, sizeof(odp_platform_init_t));
- plat_idata.ipc_ns = ipc_name_space;
-
/* Init ODP before calling anything else */
- if (odp_init_global(&instance, NULL, &plat_idata)) {
+ if (odp_init_global(&instance, NULL, NULL)) {
EXAMPLE_ERR("Error: ODP global init failed.\n");
exit(EXIT_FAILURE);
}
@@ -318,9 +320,12 @@ int main(int argc, char *argv[])
odp_pool_print(pool);
- create_pktio(pool);
-
- ret = pktio_run_loop(pool);
+ if (create_pktio(pool, master_pid) == ODP_PKTIO_INVALID) {
+ ret = -1;
+ /* skip the test */
+ } else {
+ ret = pktio_run_loop(pool);
+ }
if (odp_pool_destroy(pool)) {
EXAMPLE_ERR("Error: odp_pool_destroy() failed.\n");
@@ -16,7 +16,7 @@
#include "ipc_common.h"
-static int ipc_second_process(void)
+static int ipc_second_process(int master_pid)
{
odp_pktio_t ipc_pktio;
odp_pool_param_t params;
@@ -46,12 +46,17 @@ static int ipc_second_process(void)
exit(EXIT_FAILURE);
}
- ipc_pktio = create_pktio(pool);
+ 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();
if (odp_pktin_queue(ipc_pktio, &pktin, 1) != 1) {
+ odp_pool_destroy(pool);
EXAMPLE_ERR("no input queue\n");
return -1;
}
@@ -176,16 +181,12 @@ not_started:
int main(int argc, char *argv[])
{
odp_instance_t instance;
- odp_platform_init_t plat_idata;
int ret;
/* Parse and store the application arguments */
parse_args(argc, argv);
- memset(&plat_idata, 0, sizeof(odp_platform_init_t));
- plat_idata.ipc_ns = ipc_name_space;
-
- if (odp_init_global(&instance, NULL, &plat_idata)) {
+ if (odp_init_global(&instance, NULL, NULL)) {
EXAMPLE_ERR("Error: ODP global init failed.\n");
exit(EXIT_FAILURE);
}
@@ -196,7 +197,7 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
- ret = ipc_second_process();
+ ret = ipc_second_process(master_pid);
if (odp_term_local()) {
EXAMPLE_ERR("Error: odp_term_local() failed.\n");
@@ -20,20 +20,17 @@ PATH=.:$PATH
run()
{
local ret=0
- IPC_NS=`expr $$ + 5000`
- IPC_NS=`expr ${IPC_NS} % 65000`
- IPC_NS=`expr ${IPC_NS} + 2`
- echo "Using ns ${IPC_NS}"
-
#if test was interrupted with CTRL+c than files
#might remain in shm. Needed cleanely delete them.
- rm -rf /dev/shm/odp-${IPC_NS}* 2>&1 > /dev/null
+ rm -rf /tmp/odp-* 2>&1 > /dev/null
echo "==== run pktio_ipc1 then pktio_ipc2 ===="
- pktio_ipc1${EXEEXT} -n ${IPC_NS} -t 30 &
+ pktio_ipc1${EXEEXT} -t 30 &
IPC_PID=$!
+ sleep 1 #prevent race: master has to create objects, no
+ # fight for resources
- pktio_ipc2${EXEEXT} -n ${IPC_NS} -t 10
+ pktio_ipc2${EXEEXT} -p ${IPC_PID} -t 10
ret=$?
# pktio_ipc1 should do clean up and exit just
# after pktio_ipc2 exited. If it does not happen
@@ -41,12 +38,12 @@ run()
sleep 1
kill ${IPC_PID} 2>&1 > /dev/null
if [ $? -eq 0 ]; then
- rm -rf /dev/shm/odp-${IPC_NS}* 2>&1 > /dev/null
+ ls -l /tmp/odp*
+ rm -rf /tmp/odp-${IPC_PID}* 2>&1 > /dev/null
fi
if [ $ret -ne 0 ]; then
echo "!!!First stage FAILED $ret!!!"
- ls -l /dev/shm/
exit $ret
else
echo "First stage PASSED"
@@ -54,19 +51,19 @@ run()
echo "==== run pktio_ipc2 then pktio_ipc1 ===="
- IPC_NS=`expr $IPC_NS - 1`
- echo "Using ns ${IPC_NS}"
-
- pktio_ipc2${EXEEXT} -n ${IPC_NS} -t 10 &
+ pktio_ipc2${EXEEXT} -t 20 &
IPC_PID=$!
+ sleep 1 #prevent race: master has to create objects, no
+ # fight for resources
- pktio_ipc1${EXEEXT} -n ${IPC_NS} -t 20
+ pktio_ipc1${EXEEXT} -p ${IPC_PID} -t 10
ret=$?
(kill ${IPC_PID} 2>&1 > /dev/null) > /dev/null || true
if [ $ret -ne 0 ]; then
echo "!!! FAILED !!!"
- ls -l /dev/shm/
+ ls -l /tmp/odp*
+ rm -rf /tmp/odp-${IPC_PID}* 2>&1 > /dev/null
exit $ret
else
echo "Second stage PASSED"
Remove ipc name space and pass pid of master process to slave. If master does odp_pktio_open("ipc:name"), slave to connect to the same pktio referes to it by pid odp_pktio_open("ipc:<pid>:name"). Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> --- platform/linux-generic/include/odp_internal.h | 1 - .../include/odp_packet_io_ipc_internal.h | 4 + platform/linux-generic/odp_init.c | 4 +- platform/linux-generic/pktio/ipc.c | 124 ++++++++++----------- test/linux-generic/pktio_ipc/ipc_common.c | 39 ++++--- test/linux-generic/pktio_ipc/ipc_common.h | 10 +- test/linux-generic/pktio_ipc/pktio_ipc1.c | 23 ++-- test/linux-generic/pktio_ipc/pktio_ipc2.c | 17 +-- test/linux-generic/pktio_ipc/pktio_ipc_run.sh | 29 +++-- 9 files changed, 130 insertions(+), 121 deletions(-) -- 2.7.1.250.gff4ea60