Merged,
Maxim.

On 12/15/16 00:31, Bill Fischofer wrote:
> For the v3 series:
> 
> Reviewed-and-tested-by: Bill Fischofer <bill.fischo...@linaro.org>
> 
> On Wed, Dec 14, 2016 at 1:57 PM, Maxim Uvarov <maxim.uva...@linaro.org> wrote:
>> Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org>
>> ---
>>  .../linux-generic/include/odp_buffer_internal.h    |  10 +-
>>  platform/linux-generic/include/odp_internal.h      |   1 -
>>  .../linux-generic/include/odp_packet_io_internal.h |   2 +
>>  .../include/odp_packet_io_ipc_internal.h           |  27 +-
>>  platform/linux-generic/odp_init.c                  |   5 +-
>>  platform/linux-generic/pktio/ipc.c                 | 534 
>> +++++++++------------
>>  test/linux-generic/pktio_ipc/pktio_ipc_run.sh      |  35 +-
>>  7 files changed, 289 insertions(+), 325 deletions(-)
>>
>> diff --git a/platform/linux-generic/include/odp_buffer_internal.h 
>> b/platform/linux-generic/include/odp_buffer_internal.h
>> index 2064f7c..903f0a7 100644
>> --- a/platform/linux-generic/include/odp_buffer_internal.h
>> +++ b/platform/linux-generic/include/odp_buffer_internal.h
>> @@ -64,6 +64,11 @@ struct odp_buffer_hdr_t {
>>         struct {
>>                 void     *hdr;
>>                 uint8_t  *data;
>> +#ifdef _ODP_PKTIO_IPC
>> +       /* ipc mapped process can not walk over pointers,
>> +        * offset has to be used */
>> +               uint64_t ipc_data_offset;
>> +#endif
>>                 uint32_t  len;
>>         } seg[CONFIG_PACKET_MAX_SEGS];
>>
>> @@ -94,11 +99,6 @@ struct odp_buffer_hdr_t {
>>         uint32_t                 uarea_size; /* size of user area */
>>         uint32_t                 segcount;   /* segment count */
>>         uint32_t                 segsize;    /* segment size */
>> -#ifdef _ODP_PKTIO_IPC
>> -       /* ipc mapped process can not walk over pointers,
>> -        * offset has to be used */
>> -       uint64_t                 ipc_addr_offset[ODP_CONFIG_PACKET_MAX_SEGS];
>> -#endif
>>
>>         /* Data or next header */
>>         uint8_t data[0];
>> diff --git a/platform/linux-generic/include/odp_internal.h 
>> b/platform/linux-generic/include/odp_internal.h
>> index 6a80d9d..b313b1f 100644
>> --- a/platform/linux-generic/include/odp_internal.h
>> +++ b/platform/linux-generic/include/odp_internal.h
>> @@ -50,7 +50,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 {
>> diff --git a/platform/linux-generic/include/odp_packet_io_internal.h 
>> b/platform/linux-generic/include/odp_packet_io_internal.h
>> index bdf6316..2001c42 100644
>> --- a/platform/linux-generic/include/odp_packet_io_internal.h
>> +++ b/platform/linux-generic/include/odp_packet_io_internal.h
>> @@ -102,6 +102,8 @@ typedef     struct {
>>                                      packet, 0 - not yet ready */
>>         void *pinfo;
>>         odp_shm_t pinfo_shm;
>> +       odp_shm_t remote_pool_shm; /**< shm of remote pool get with
>> +                                       _ipc_map_remote_pool() */
>>  } _ipc_pktio_t;
>>
>>  struct pktio_entry {
>> 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 851114d..7cd2948 100644
>> --- a/platform/linux-generic/include/odp_packet_io_ipc_internal.h
>> +++ b/platform/linux-generic/include/odp_packet_io_ipc_internal.h
>> @@ -26,22 +26,31 @@
>>   */
>>  struct pktio_info {
>>         struct {
>> -               /* number of buffer in remote pool */
>> -               int shm_pool_bufs_num;
>> -               /* size of remote pool */
>> -               size_t shm_pkt_pool_size;
>> +               /* number of buffer*/
>> +               int num;
>>                 /* size of packet/segment in remote pool */
>> -               uint32_t shm_pkt_size;
>> +               uint32_t block_size;
>>                 /* offset from shared memory block start
>> -                * to pool_mdata_addr (odp-linux pool specific) */
>> -               size_t mdata_offset;
>> +                * to pool *base_addr in remote process.
>> +                * (odp-linux pool specific) */
>> +               size_t base_addr_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
>> -                * to pool_mdata_addr in remote process.
>> +                * to pool *base_addr in remote process.
>>                  * (odp-linux pool specific) */
>> -               size_t mdata_offset;
>> +               size_t base_addr_offset;
>> +               void *base_addr;
>> +               uint32_t block_size;
>>                 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;
>> +               int init_done;
>>         } slave;
>>  } ODP_PACKED;
>> diff --git a/platform/linux-generic/odp_init.c 
>> b/platform/linux-generic/odp_init.c
>> index d40a83c..1b0d8f8 100644
>> --- a/platform/linux-generic/odp_init.c
>> +++ b/platform/linux-generic/odp_init.c
>> @@ -67,7 +67,7 @@ static int cleanup_files(const char *dirpath, int odp_pid)
>>
>>  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)
>>  {
>>         char *hpdir;
>>
>> @@ -75,9 +75,6 @@ int odp_init_global(odp_instance_t *instance,
>>         odp_global_data.main_pid = getpid();
>>         cleanup_files(_ODP_TMPDIR, odp_global_data.main_pid);
>>
>> -       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;
>>         odp_global_data.abort_fn = odp_override_abort;
>> diff --git a/platform/linux-generic/pktio/ipc.c 
>> b/platform/linux-generic/pktio/ipc.c
>> index 0e99c6e..5e47a33 100644
>> --- a/platform/linux-generic/pktio/ipc.c
>> +++ b/platform/linux-generic/pktio/ipc.c
>> @@ -3,150 +3,85 @@
>>   *
>>   * SPDX-License-Identifier:     BSD-3-Clause
>>   */
>> -#ifdef _ODP_PKTIO_IPC
>>  #include <odp_packet_io_ipc_internal.h>
>>  #include <odp_debug_internal.h>
>>  #include <odp_packet_io_internal.h>
>>  #include <odp/api/system_info.h>
>>  #include <odp_shm_internal.h>
>> +#include <_ishm_internal.h>
>>
>>  #include <sys/mman.h>
>>  #include <sys/stat.h>
>>  #include <fcntl.h>
>>
>> +#define IPC_ODP_DEBUG_PRINT 0
>> +
>> +#define IPC_ODP_DBG(fmt, ...) \
>> +       do { \
>> +               if (IPC_ODP_DEBUG_PRINT == 1) \
>> +                       ODP_DBG(fmt, ##__VA_ARGS__);\
>> +       } while (0)
>> +
>>  /* MAC address for the "ipc" interface */
>>  static const char pktio_ipc_mac[] = {0x12, 0x12, 0x12, 0x12, 0x12, 0x12};
>>
>> -static void *_ipc_map_remote_pool(const char *name, size_t size);
>> +static odp_shm_t _ipc_map_remote_pool(const char *name, int pid);
>>
>>  static const char *_ipc_odp_buffer_pool_shm_name(odp_pool_t pool_hdl)
>>  {
>> -       pool_entry_t *pool;
>> -       uint32_t pool_id;
>> +       pool_t *pool;
>>         odp_shm_t shm;
>>         odp_shm_info_t info;
>>
>> -       pool_id = pool_handle_to_index(pool_hdl);
>> -       pool    = get_pool_entry(pool_id);
>> -       shm = pool->s.pool_shm;
>> +       pool    = pool_entry_from_hdl(pool_hdl);
>> +       shm = pool->shm;
>>
>>         odp_shm_info(shm, &info);
>>
>>         return info.name;
>>  }
>>
>> -/**
>> -* Look up for shared memory object.
>> -*
>> -* @param name   name of shm object
>> -*
>> -* @return 0 on success, otherwise non-zero
>> -*/
>> -static int _ipc_shm_lookup(const char *name)
>> -{
>> -       int shm;
>> -       char shm_devname[SHM_DEVNAME_MAXLEN];
>> -
>> -       if (!odp_global_data.ipc_ns)
>> -               ODP_ABORT("ipc_ns not set\n");
>> -
>> -       snprintf(shm_devname, SHM_DEVNAME_MAXLEN,
>> -                SHM_DEVNAME_FORMAT,
>> -                odp_global_data.ipc_ns, name);
>> -
>> -       shm = shm_open(shm_devname, O_RDWR, S_IRUSR | S_IWUSR);
>> -       if (shm == -1) {
>> -               if (errno == ENOENT) {
>> -                       ODP_DBG("no file %s\n", shm_devname);
>> -                       return -1;
>> -               }
>> -               ODP_ABORT("shm_open for %s err %s\n",
>> -                         shm_devname, strerror(errno));
>> -       }
>> -       close(shm);
>> -       return 0;
>> -}
>> -
>> -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(name, sizeof(struct pktio_info),
>> -                             ODP_CACHE_LINE_SIZE,
>> -                             flags);
>> -       if (ODP_SHM_INVALID != shm) {
>> -               pinfo = odp_shm_addr(shm);
>> -               pinfo->master.pool_name[0] = 0;
>> -               *slave = 0;
>> -       } else {
>> -               flags = _ODP_SHM_PROC_NOCREAT | _ODP_SHM_O_EXCL;
>> -               shm = odp_shm_reserve(name, sizeof(struct pktio_info),
>> -                                     ODP_CACHE_LINE_SIZE,
>> -                                     flags);
>> -               if (ODP_SHM_INVALID == shm)
>> -                       ODP_ABORT("can not connect to shm\n");
>> -
>> -               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;
>> -       int ret;
>> -       void *ipc_pool_base;
>> +       odp_shm_t shm;
>>
>> -       if (pinfo->slave.mdata_offset == 0)
>> +       if (pinfo->slave.init_done == 0)
>>                 return -1;
>>
>> -       ret = _ipc_shm_lookup(pinfo->slave.pool_name);
>> -       if (ret) {
>> -               ODP_DBG("no pool file %s\n", pinfo->slave.pool_name);
>> +       shm = _ipc_map_remote_pool(pinfo->slave.pool_name,
>> +                                  pinfo->slave.pid);
>> +       if (shm == ODP_SHM_INVALID) {
>> +               ODP_DBG("no pool file %s for pid %d\n",
>> +                       pinfo->slave.pool_name, pinfo->slave.pid);
>>                 return -1;
>>         }
>>
>> -       ipc_pool_base = _ipc_map_remote_pool(pinfo->slave.pool_name,
>> -                                            
>> pinfo->master.shm_pkt_pool_size);
>> -       pktio_entry->s.ipc.pool_mdata_base = (char *)ipc_pool_base +
>> -                                            pinfo->slave.mdata_offset;
>> +       pktio_entry->s.ipc.remote_pool_shm = shm;
>> +       pktio_entry->s.ipc.pool_base = odp_shm_addr(shm);
>> +       pktio_entry->s.ipc.pool_mdata_base = (char *)odp_shm_addr(shm) +
>> +                                            pinfo->slave.base_addr_offset;
>>
>>         odp_atomic_store_u32(&pktio_entry->s.ipc.ready, 1);
>>
>> -       ODP_DBG("%s started.\n",  pktio_entry->s.name);
>> +       IPC_ODP_DBG("%s started.\n",  pktio_entry->s.name);
>>         return 0;
>>  }
>>
>>  static int _ipc_init_master(pktio_entry_t *pktio_entry,
>>                             const char *dev,
>> -                           odp_pool_t pool)
>> +                           odp_pool_t pool_hdl)
>>  {
>>         char ipc_shm_name[ODP_POOL_NAME_LEN + sizeof("_m_prod")];
>> -       pool_entry_t *pool_entry;
>> -       uint32_t pool_id;
>> +       pool_t *pool;
>>         struct pktio_info *pinfo;
>>         const char *pool_name;
>>
>> -       pool_id = pool_handle_to_index(pool);
>> -       pool_entry    = get_pool_entry(pool_id);
>> +       pool = pool_entry_from_hdl(pool_hdl);
>> +       (void)pool;
>>
>>         if (strlen(dev) > (ODP_POOL_NAME_LEN - sizeof("_m_prod"))) {
>> -               ODP_DBG("too big ipc name\n");
>> +               ODP_ERR("too big ipc name\n");
>>                 return -1;
>>         }
>>
>> @@ -158,7 +93,7 @@ static int _ipc_init_master(pktio_entry_t *pktio_entry,
>>                         PKTIO_IPC_ENTRIES,
>>                         _RING_SHM_PROC | _RING_NO_LIST);
>>         if (!pktio_entry->s.ipc.tx.send) {
>> -               ODP_DBG("pid %d unable to create ipc ring %s name\n",
>> +               ODP_ERR("pid %d unable to create ipc ring %s name\n",
>>                         getpid(), ipc_shm_name);
>>                 return -1;
>>         }
>> @@ -174,7 +109,7 @@ static int _ipc_init_master(pktio_entry_t *pktio_entry,
>>                         PKTIO_IPC_ENTRIES,
>>                         _RING_SHM_PROC | _RING_NO_LIST);
>>         if (!pktio_entry->s.ipc.tx.free) {
>> -               ODP_DBG("pid %d unable to create ipc ring %s name\n",
>> +               ODP_ERR("pid %d unable to create ipc ring %s name\n",
>>                         getpid(), ipc_shm_name);
>>                 goto free_m_prod;
>>         }
>> @@ -187,7 +122,7 @@ static int _ipc_init_master(pktio_entry_t *pktio_entry,
>>                         PKTIO_IPC_ENTRIES,
>>                         _RING_SHM_PROC | _RING_NO_LIST);
>>         if (!pktio_entry->s.ipc.rx.recv) {
>> -               ODP_DBG("pid %d unable to create ipc ring %s name\n",
>> +               ODP_ERR("pid %d unable to create ipc ring %s name\n",
>>                         getpid(), ipc_shm_name);
>>                 goto free_m_cons;
>>         }
>> @@ -200,7 +135,7 @@ static int _ipc_init_master(pktio_entry_t *pktio_entry,
>>                         PKTIO_IPC_ENTRIES,
>>                         _RING_SHM_PROC | _RING_NO_LIST);
>>         if (!pktio_entry->s.ipc.rx.free) {
>> -               ODP_DBG("pid %d unable to create ipc ring %s name\n",
>> +               ODP_ERR("pid %d unable to create ipc ring %s name\n",
>>                         getpid(), ipc_shm_name);
>>                 goto free_s_prod;
>>         }
>> @@ -210,24 +145,23 @@ static int _ipc_init_master(pktio_entry_t *pktio_entry,
>>
>>         /* Set up pool name for remote info */
>>         pinfo = pktio_entry->s.ipc.pinfo;
>> -       pool_name = _ipc_odp_buffer_pool_shm_name(pool);
>> +       pool_name = _ipc_odp_buffer_pool_shm_name(pool_hdl);
>>         if (strlen(pool_name) > ODP_POOL_NAME_LEN) {
>> -               ODP_DBG("pid %d ipc pool name %s is too big %d\n",
>> +               ODP_ERR("pid %d ipc pool name %s is too big %d\n",
>>                         getpid(), pool_name, strlen(pool_name));
>>                 goto free_s_prod;
>>         }
>>
>>         memcpy(pinfo->master.pool_name, pool_name, strlen(pool_name));
>> -       pinfo->master.shm_pkt_pool_size = pool_entry->s.pool_size;
>> -       pinfo->master.shm_pool_bufs_num = pool_entry->s.buf_num;
>> -       pinfo->master.shm_pkt_size = pool_entry->s.seg_size;
>> -       pinfo->master.mdata_offset =  pool_entry->s.pool_mdata_addr -
>> -                              pool_entry->s.pool_base_addr;
>> -       pinfo->slave.mdata_offset = 0;
>> +       pinfo->slave.base_addr_offset = 0;
>> +       pinfo->slave.base_addr = 0;
>> +       pinfo->slave.pid = 0;
>> +       pinfo->slave.init_done = 0;
>>
>> -       pktio_entry->s.ipc.pool = pool;
>> +       pktio_entry->s.ipc.pool = pool_hdl;
>>
>>         ODP_DBG("Pre init... DONE.\n");
>> +       pinfo->master.init_done = 1;
>>
>>         _ipc_master_start(pktio_entry);
>>
>> @@ -246,55 +180,42 @@ free_m_prod:
>>  }
>>
>>  static void _ipc_export_pool(struct pktio_info *pinfo,
>> -                            odp_pool_t pool)
>> +                            odp_pool_t pool_hdl)
>>  {
>> -       pool_entry_t *pool_entry;
>> -
>> -       pool_entry = odp_pool_to_entry(pool);
>> -       if (pool_entry->s.blk_size != pinfo->master.shm_pkt_size)
>> -               ODP_ABORT("pktio for same name should have the same pool 
>> size\n");
>> -       if (pool_entry->s.buf_num != 
>> (unsigned)pinfo->master.shm_pool_bufs_num)
>> -               ODP_ABORT("pktio for same name should have the same pool 
>> size\n");
>> +       pool_t *pool = pool_entry_from_hdl(pool_hdl);
>>
>>         snprintf(pinfo->slave.pool_name, ODP_POOL_NAME_LEN, "%s",
>> -                pool_entry->s.name);
>> -       pinfo->slave.mdata_offset = pool_entry->s.pool_mdata_addr -
>> -                                   pool_entry->s.pool_base_addr;
>> +                _ipc_odp_buffer_pool_shm_name(pool_hdl));
>> +       pinfo->slave.pid = odp_global_data.main_pid;
>> +       pinfo->slave.block_size = pool->block_size;
>> +       pinfo->slave.base_addr = pool->base_addr;
>>  }
>>
>> -static void *_ipc_map_remote_pool(const char *name, size_t size)
>> +static odp_shm_t _ipc_map_remote_pool(const char *name, int pid)
>>  {
>>         odp_shm_t shm;
>> -       void *addr;
>> +       char rname[ODP_SHM_NAME_LEN];
>>
>> -       ODP_DBG("Mapping remote pool %s, size %ld\n", name, size);
>> -       shm = odp_shm_reserve(name,
>> -                             size,
>> -                             ODP_CACHE_LINE_SIZE,
>> -                             _ODP_SHM_PROC_NOCREAT);
>> -       if (shm == ODP_SHM_INVALID)
>> -               ODP_ABORT("unable map %s\n", name);
>> +       snprintf(rname, ODP_SHM_NAME_LEN, "remote-%s", name);
>> +       shm = odp_shm_import(name, pid, rname);
>> +       if (shm == ODP_SHM_INVALID) {
>> +               ODP_ERR("unable map %s\n", name);
>> +               return ODP_SHM_INVALID;
>> +       }
>>
>> -       addr = odp_shm_addr(shm);
>> -       ODP_DBG("MAP master: %p - %p size %ld, pool %s\n",
>> -               addr, (char *)addr + size, size, name);
>> -       return addr;
>> +       IPC_ODP_DBG("Mapped remote pool %s to local %s\n", name, rname);
>> +       return shm;
>>  }
>>
>> -static void *_ipc_shm_map(char *name, size_t size)
>> +static void *_ipc_shm_map(char *name, int pid)
>>  {
>>         odp_shm_t shm;
>> -       int ret;
>>
>> -       ret = _ipc_shm_lookup(name);
>> -       if (ret == -1)
>> +       shm = odp_shm_import(name, pid, name);
>> +       if (ODP_SHM_INVALID == shm) {
>> +               ODP_ERR("unable to map: %s\n", name);
>>                 return NULL;
>> -
>> -       shm = odp_shm_reserve(name, size,
>> -                             ODP_CACHE_LINE_SIZE,
>> -                             _ODP_SHM_PROC_NOCREAT);
>> -       if (ODP_SHM_INVALID == shm)
>> -               ODP_ABORT("unable to map: %s\n", name);
>> +       }
>>
>>         return odp_shm_addr(shm);
>>  }
>> @@ -313,15 +234,21 @@ 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);
>> @@ -333,9 +260,9 @@ 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",
>> +               ODP_ERR("pid %d unable to find ipc ring %s name\n",
>>                         getpid(), dev);
>>                 goto free_m_prod;
>>         }
>> @@ -344,9 +271,9 @@ 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",
>> +               ODP_ERR("pid %d unable to find ipc ring %s name\n",
>>                         getpid(), dev);
>>                 goto free_m_cons;
>>         }
>> @@ -355,9 +282,9 @@ 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",
>> +               ODP_ERR("pid %d unable to find ipc ring %s name\n",
>>                         getpid(), dev);
>>                 goto free_s_prod;
>>         }
>> @@ -367,15 +294,17 @@ static int _ipc_slave_start(pktio_entry_t *pktio_entry)
>>
>>         /* Get info about remote pool */
>>         pinfo = pktio_entry->s.ipc.pinfo;
>> -       ipc_pool_base = _ipc_map_remote_pool(pinfo->master.pool_name,
>> -                                            
>> pinfo->master.shm_pkt_pool_size);
>> -       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;
>> +       shm = _ipc_map_remote_pool(pinfo->master.pool_name,
>> +                                  pid);
>> +       pktio_entry->s.ipc.remote_pool_shm = shm;
>> +       pktio_entry->s.ipc.pool_mdata_base = (char *)odp_shm_addr(shm) +
>> +                                            pinfo->master.base_addr_offset;
>> +       pktio_entry->s.ipc.pkt_size = pinfo->master.block_size;
>>
>>         _ipc_export_pool(pinfo, pktio_entry->s.ipc.pool);
>>
>>         odp_atomic_store_u32(&pktio_entry->s.ipc.ready, 1);
>> +       pinfo->slave.init_done = 1;
>>
>>         ODP_DBG("%s started.\n",  pktio_entry->s.name);
>>         return 0;
>> @@ -401,7 +330,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");
>> @@ -411,65 +344,59 @@ 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);
>> +               IPC_ODP_DBG("lookup for name %s for pid %d\n", name, pid);
>> +               shm = odp_shm_import(name, pid, name);
>> +               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());
>> +               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_ISHM_EXPORT | _ODP_ISHM_LOCK);
>> +               if (ODP_SHM_INVALID == shm) {
>> +                       ODP_ERR("can not create shm %s\n", name);
>> +                       return -1;
>> +               }
>> +
>> +               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;
>>                 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;
>>  }
>>
>> -static inline void *_ipc_buffer_map(odp_buffer_hdr_t *buf,
>> -                                   uint32_t offset,
>> -                                   uint32_t *seglen,
>> -                                   uint32_t limit)
>> +static void _ipc_free_ring_packets(pktio_entry_t *pktio_entry, _ring_t *r)
>>  {
>> -       int seg_index  = offset / buf->segsize;
>> -       int seg_offset = offset % buf->segsize;
>> -#ifdef _ODP_PKTIO_IPC
>> -       void *addr = (char *)buf - buf->ipc_addr_offset[seg_index];
>> -#else
>> -       /** buf_hdr.ipc_addr_offset defined only when ipc is
>> -        *  enabled. */
>> -       void *addr = NULL;
>> -
>> -       (void)seg_index;
>> -#endif
>> -       if (seglen) {
>> -               uint32_t buf_left = limit - offset;
>> -               *seglen = seg_offset + buf_left <= buf->segsize ?
>> -                       buf_left : buf->segsize - seg_offset;
>> -       }
>> -
>> -       return (void *)(seg_offset + (uint8_t *)addr);
>> -}
>> -
>> -static inline void *_ipc_packet_map(odp_packet_hdr_t *pkt_hdr,
>> -                                   uint32_t offset, uint32_t *seglen)
>> -{
>> -       if (offset > pkt_hdr->frame_len)
>> -               return NULL;
>> -
>> -       return _ipc_buffer_map(&pkt_hdr->buf_hdr,
>> -                         pkt_hdr->headroom + offset, seglen,
>> -                         pkt_hdr->headroom + pkt_hdr->frame_len);
>> -}
>> -
>> -static void _ipc_free_ring_packets(_ring_t *r)
>> -{
>> -       odp_packet_t r_p_pkts[PKTIO_IPC_ENTRIES];
>> +       uintptr_t offsets[PKTIO_IPC_ENTRIES];
>>         int ret;
>>         void **rbuf_p;
>>         int i;
>>
>> -       rbuf_p = (void *)&r_p_pkts;
>> +       if (!r)
>> +               return;
>> +
>> +       rbuf_p = (void *)&offsets;
>>
>>         while (1) {
>>                 ret = _ring_mc_dequeue_burst(r, rbuf_p,
>> @@ -477,8 +404,13 @@ static void _ipc_free_ring_packets(_ring_t *r)
>>                 if (0 == ret)
>>                         break;
>>                 for (i = 0; i < ret; i++) {
>> -                       if (r_p_pkts[i] != ODP_PACKET_INVALID)
>> -                               odp_packet_free(r_p_pkts[i]);
>> +                       odp_packet_hdr_t *phdr;
>> +                       odp_packet_t pkt;
>> +                       void *mbase = pktio_entry->s.ipc.pool_mdata_base;
>> +
>> +                       phdr = (void *)((uint8_t *)mbase + offsets[i]);
>> +                       pkt = (odp_packet_t)phdr->buf_hdr.handle.handle;
>> +                       odp_packet_free(pkt);
>>                 }
>>         }
>>  }
>> @@ -490,22 +422,23 @@ static int ipc_pktio_recv_lockless(pktio_entry_t 
>> *pktio_entry,
>>         int i;
>>         _ring_t *r;
>>         _ring_t *r_p;
>> +       uintptr_t offsets[PKTIO_IPC_ENTRIES];
>> +       void **ipcbufs_p = (void *)&offsets;
>> +       uint32_t ready;
>> +       int pkts_ring;
>>
>> -       odp_packet_t remote_pkts[PKTIO_IPC_ENTRIES];
>> -       void **ipcbufs_p = (void *)&remote_pkts;
>> -       uint32_t ready = odp_atomic_load_u32(&pktio_entry->s.ipc.ready);
>> -
>> +       ready = odp_atomic_load_u32(&pktio_entry->s.ipc.ready);
>>         if (odp_unlikely(!ready)) {
>> -               ODP_DBG("start pktio is missing before usage?\n");
>> -               return -1;
>> +               IPC_ODP_DBG("start pktio is missing before usage?\n");
>> +               return 0;
>>         }
>>
>> -       _ipc_free_ring_packets(pktio_entry->s.ipc.tx.free);
>> +       _ipc_free_ring_packets(pktio_entry, pktio_entry->s.ipc.tx.free);
>>
>>         r = pktio_entry->s.ipc.rx.recv;
>>         pkts = _ring_mc_dequeue_burst(r, ipcbufs_p, len);
>>         if (odp_unlikely(pkts < 0))
>> -               ODP_ABORT("error to dequeue no packets\n");
>> +               ODP_ABORT("internal error dequeue\n");
>>
>>         /* fast path */
>>         if (odp_likely(0 == pkts))
>> @@ -514,36 +447,21 @@ static int ipc_pktio_recv_lockless(pktio_entry_t 
>> *pktio_entry,
>>         for (i = 0; i < pkts; i++) {
>>                 odp_pool_t pool;
>>                 odp_packet_t pkt;
>> -               odp_packet_hdr_t phdr;
>> -               void *ptr;
>> -               odp_buffer_bits_t handle;
>> -               int idx; /* Remote packet has coded pool and index.
>> -                         * We need only index.*/
>> +               odp_packet_hdr_t *phdr;
>>                 void *pkt_data;
>> -               void *remote_pkt_data;
>> +               uint64_t data_pool_off;
>> +               void *rmt_data_ptr;
>>
>> -               if (remote_pkts[i] == ODP_PACKET_INVALID)
>> -                       continue;
>> +               phdr = (void *)((uint8_t 
>> *)pktio_entry->s.ipc.pool_mdata_base +
>> +                      offsets[i]);
>>
>> -               handle.handle = _odp_packet_to_buffer(remote_pkts[i]);
>> -               idx = handle.index;
>> -
>> -               /* Link to packed data. To this line we have Zero-Copy 
>> between
>> -                * processes, to simplify use packet copy in that version 
>> which
>> -                * can be removed later with more advance buffer management
>> -                * (ref counters).
>> -                */
>> -               /* reverse odp_buf_to_hdr() */
>> -               ptr = (char *)pktio_entry->s.ipc.pool_mdata_base +
>> -                     (idx * ODP_CACHE_LINE_SIZE);
>> -               memcpy(&phdr, ptr, sizeof(odp_packet_hdr_t));
>> -
>> -               /* Allocate new packet. Select*/
>>                 pool = pktio_entry->s.ipc.pool;
>>                 if (odp_unlikely(pool == ODP_POOL_INVALID))
>>                         ODP_ABORT("invalid pool");
>>
>> -               pkt = odp_packet_alloc(pool, phdr.frame_len);
>> +               data_pool_off = phdr->buf_hdr.seg[0].ipc_data_offset;
>> +
>> +               pkt = odp_packet_alloc(pool, phdr->frame_len);
>>                 if (odp_unlikely(pkt == ODP_PACKET_INVALID)) {
>>                         /* Original pool might be smaller then
>>                         *  PKTIO_IPC_ENTRIES. If packet can not be
>> @@ -562,30 +480,40 @@ static int ipc_pktio_recv_lockless(pktio_entry_t 
>> *pktio_entry,
>>                                   (PKTIO_TYPE_IPC_SLAVE ==
>>                                         pktio_entry->s.ipc.type));
>>
>> -               remote_pkt_data = _ipc_packet_map(ptr, 0, NULL);
>> -               if (odp_unlikely(!remote_pkt_data))
>> -                       ODP_ABORT("unable to map remote_pkt_data, ipc_slave 
>> %d\n",
>> -                                 (PKTIO_TYPE_IPC_SLAVE ==
>> -                                       pktio_entry->s.ipc.type));
>> -
>>                 /* Copy packet data from shared pool to local pool. */
>> -               memcpy(pkt_data, remote_pkt_data, phdr.frame_len);
>> +               rmt_data_ptr = (uint8_t *)pktio_entry->s.ipc.pool_mdata_base 
>> +
>> +                              data_pool_off;
>> +               memcpy(pkt_data, rmt_data_ptr, phdr->frame_len);
>>
>>                 /* Copy packets L2, L3 parsed offsets and size */
>> -               copy_packet_cls_metadata(&phdr, odp_packet_hdr(pkt));
>> +               copy_packet_cls_metadata(phdr, odp_packet_hdr(pkt));
>> +
>> +               odp_packet_hdr(pkt)->frame_len = phdr->frame_len;
>> +               odp_packet_hdr(pkt)->headroom = phdr->headroom;
>> +               odp_packet_hdr(pkt)->tailroom = phdr->tailroom;
>> +
>> +               /* Take classification fields */
>> +               odp_packet_hdr(pkt)->p = phdr->p;
>>
>> -               odp_packet_hdr(pkt)->frame_len = phdr.frame_len;
>> -               odp_packet_hdr(pkt)->headroom = phdr.headroom;
>> -               odp_packet_hdr(pkt)->tailroom = phdr.tailroom;
>> -               odp_packet_hdr(pkt)->input = pktio_entry->s.handle;
>>                 pkt_table[i] = pkt;
>>         }
>>
>>         /* Now tell other process that we no longer need that buffers.*/
>>         r_p = pktio_entry->s.ipc.rx.free;
>> -       pkts = _ring_mp_enqueue_burst(r_p, ipcbufs_p, i);
>> +
>> +repeat:
>> +       pkts_ring = _ring_mp_enqueue_burst(r_p, ipcbufs_p, pkts);
>>         if (odp_unlikely(pkts < 0))
>>                 ODP_ABORT("ipc: odp_ring_mp_enqueue_bulk r_p fail\n");
>> +       if (odp_unlikely(pkts != pkts_ring)) {
>> +               IPC_ODP_DBG("odp_ring_full: %d, odp_ring_count %d,"
>> +                           " _ring_free_count %d\n",
>> +                           _ring_full(r_p), _ring_count(r_p),
>> +                           _ring_free_count(r_p));
>> +               ipcbufs_p = (void *)&offsets[pkts_ring - 1];
>> +               pkts = pkts - pkts_ring;
>> +               goto repeat;
>> +       }
>>
>>         return pkts;
>>  }
>> @@ -614,26 +542,23 @@ static int ipc_pktio_send_lockless(pktio_entry_t 
>> *pktio_entry,
>>         uint32_t ready = odp_atomic_load_u32(&pktio_entry->s.ipc.ready);
>>         odp_packet_t pkt_table_mapped[len]; /**< Ready to send packet has to 
>> be
>>                                               * in memory mapped pool. */
>> +       uintptr_t offsets[len];
>>
>>         if (odp_unlikely(!ready))
>>                 return 0;
>>
>> -       _ipc_free_ring_packets(pktio_entry->s.ipc.tx.free);
>> +       _ipc_free_ring_packets(pktio_entry, pktio_entry->s.ipc.tx.free);
>>
>> -       /* Prepare packets: calculate offset from address. */
>> +       /* Copy packets to shm shared pool if they are in different */
>>         for (i = 0; i < len; i++) {
>> -               int j;
>>                 odp_packet_t pkt =  pkt_table[i];
>> -               odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>> +               pool_t *ipc_pool = 
>> pool_entry_from_hdl(pktio_entry->s.ipc.pool);
>>                 odp_buffer_bits_t handle;
>> -               uint32_t cur_mapped_pool_id =
>> -                        pool_handle_to_index(pktio_entry->s.ipc.pool);
>> -               uint32_t pool_id;
>> +               uint32_t pkt_pool_id;
>>
>> -               /* do copy if packet was allocated from not mapped pool */
>>                 handle.handle = _odp_packet_to_buffer(pkt);
>> -               pool_id = handle.pool_id;
>> -               if (pool_id != cur_mapped_pool_id) {
>> +               pkt_pool_id = handle.pool_id;
>> +               if (pkt_pool_id != ipc_pool->pool_idx) {
>>                         odp_packet_t newpkt;
>>
>>                         newpkt = odp_packet_copy(pkt, 
>> pktio_entry->s.ipc.pool);
>> @@ -645,24 +570,30 @@ static int ipc_pktio_send_lockless(pktio_entry_t 
>> *pktio_entry,
>>                 } else {
>>                         pkt_table_mapped[i] = pkt;
>>                 }
>> +       }
>>
>> -               /* buf_hdr.addr can not be used directly in remote process,
>> -                * convert it to offset
>> -                */
>> -               for (j = 0; j < ODP_BUFFER_MAX_SEG; j++) {
>> -#ifdef _ODP_PKTIO_IPC
>> -                       pkt_hdr->buf_hdr.ipc_addr_offset[j] = (char 
>> *)pkt_hdr -
>> -                               (char *)pkt_hdr->buf_hdr.addr[j];
>> -#else
>> -                       /** buf_hdr.ipc_addr_offset defined only when ipc is
>> -                        *  enabled. */
>> -                       (void)pkt_hdr;
>> -#endif
>> -               }
>> +       /* Set offset to phdr for outgoing packets */
>> +       for (i = 0; i < len; i++) {
>> +               uint64_t data_pool_off;
>> +               odp_packet_t pkt = pkt_table_mapped[i];
>> +               odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>> +               odp_pool_t pool_hdl = odp_packet_pool(pkt);
>> +               pool_t *pool = pool_entry_from_hdl(pool_hdl);
>> +
>> +               offsets[i] = (uint8_t *)pkt_hdr -
>> +                            (uint8_t *)odp_shm_addr(pool->shm);
>> +               data_pool_off = (uint8_t *)pkt_hdr->buf_hdr.seg[0].data -
>> +                               (uint8_t *)odp_shm_addr(pool->shm);
>> +               pkt_hdr->buf_hdr.seg[0].ipc_data_offset = data_pool_off;
>> +               IPC_ODP_DBG("%d/%d send packet %llx, pool %llx,"
>> +                           "phdr = %p, offset %x\n",
>> +                           i, len,
>> +                           odp_packet_to_u64(pkt), 
>> odp_pool_to_u64(pool_hdl),
>> +                           pkt_hdr, 
>> pkt_hdr->buf_hdr.seg[0].ipc_data_offset);
>>         }
>>
>>         /* Put packets to ring to be processed by other process. */
>> -       rbuf_p = (void *)&pkt_table_mapped[0];
>> +       rbuf_p = (void *)&offsets[0];
>>         r = pktio_entry->s.ipc.tx.send;
>>         ret = _ring_mp_enqueue_burst(r, rbuf_p, len);
>>         if (odp_unlikely(ret < 0)) {
>> @@ -673,6 +604,7 @@ static int ipc_pktio_send_lockless(pktio_entry_t 
>> *pktio_entry,
>>                 ODP_ERR("odp_ring_full: %d, odp_ring_count %d, 
>> _ring_free_count %d\n",
>>                         _ring_full(r), _ring_count(r),
>>                         _ring_free_count(r));
>> +               ODP_ABORT("Unexpected!\n");
>>         }
>>
>>         return ret;
>> @@ -722,22 +654,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, 
>> 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, 
>> 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;
>> @@ -747,23 +682,31 @@ static int ipc_close(pktio_entry_t *pktio_entry)
>>  {
>>         char ipc_shm_name[ODP_POOL_NAME_LEN + sizeof("_m_prod")];
>>         char *dev = pktio_entry->s.name;
>> +       char name[ODP_POOL_NAME_LEN];
>> +       char tail[ODP_POOL_NAME_LEN];
>> +       int pid = 0;
>>
>>         ipc_stop(pktio_entry);
>>
>> -       if (pktio_entry->s.ipc.type == PKTIO_TYPE_IPC_MASTER) {
>> -               /* unlink this pktio info for both master and slave */
>> -               odp_shm_free(pktio_entry->s.ipc.pinfo_shm);
>> +       odp_shm_free(pktio_entry->s.ipc.remote_pool_shm);
>>
>> -               /* destroy rings */
>> -               snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_cons", 
>> dev);
>> -               _ring_destroy(ipc_shm_name);
>> -               snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_prod", 
>> dev);
>> -               _ring_destroy(ipc_shm_name);
>> -               snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_cons", 
>> dev);
>> -               _ring_destroy(ipc_shm_name);
>> -               snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_prod", 
>> dev);
>> -               _ring_destroy(ipc_shm_name);
>> -       }
>> +       if (sscanf(dev, "ipc:%d:%s", &pid, tail) == 2)
>> +               snprintf(name, sizeof(name), "ipc:%s", tail);
>> +       else
>> +               snprintf(name, sizeof(name), "%s", dev);
>> +
>> +       /* unlink this pktio info for both master and slave */
>> +       odp_shm_free(pktio_entry->s.ipc.pinfo_shm);
>> +
>> +       /* destroy rings */
>> +       snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_cons", name);
>> +       _ring_destroy(ipc_shm_name);
>> +       snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_prod", name);
>> +       _ring_destroy(ipc_shm_name);
>> +       snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_cons", name);
>> +       _ring_destroy(ipc_shm_name);
>> +       snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_prod", name);
>> +       _ring_destroy(ipc_shm_name);
>>
>>         return 0;
>>  }
>> @@ -795,4 +738,3 @@ const pktio_if_ops_t ipc_pktio_ops = {
>>         .pktin_ts_from_ns = NULL,
>>         .config = NULL
>>  };
>> -#endif
>> diff --git a/test/linux-generic/pktio_ipc/pktio_ipc_run.sh 
>> b/test/linux-generic/pktio_ipc/pktio_ipc_run.sh
>> index 3cd28f5..52e8d42 100755
>> --- a/test/linux-generic/pktio_ipc/pktio_ipc_run.sh
>> +++ b/test/linux-generic/pktio_ipc/pktio_ipc_run.sh
>> @@ -25,19 +25,23 @@ run()
>>         rm -rf /tmp/odp-* 2>&1 > /dev/null
>>
>>         echo "==== run pktio_ipc1 then pktio_ipc2 ===="
>> -       pktio_ipc1${EXEEXT} -t 30 &
>> +       pktio_ipc1${EXEEXT} -t 10 &
>>         IPC_PID=$!
>>
>> -       pktio_ipc2${EXEEXT} -p ${IPC_PID} -t 10
>> +       pktio_ipc2${EXEEXT} -p ${IPC_PID} -t 5
>>         ret=$?
>>         # pktio_ipc1 should do clean up and exit just
>>         # after pktio_ipc2 exited. If it does not happen
>>         # kill him in test.
>> -       sleep 1
>> -       kill ${IPC_PID} 2>&1 > /dev/null
>> +       sleep 13
>> +       (kill ${IPC_PID} 2>&1 > /dev/null ) > /dev/null
>>         if [ $? -eq 0 ]; then
>> -               ls -l /tmp/odp*
>> +               echo "pktio_ipc1${EXEEXT} was killed"
>> +               ls -l /tmp/odp* 2> /dev/null
>>                 rm -rf /tmp/odp-${IPC_PID}* 2>&1 > /dev/null
>> +       else
>> +               echo "normal exit of 2 application"
>> +               ls -l /tmp/odp* 2> /dev/null
>>         fi
>>
>>         if [ $ret -ne 0 ]; then
>> @@ -47,21 +51,32 @@ run()
>>                 echo "First stage PASSED"
>>         fi
>>
>> -
>>         echo "==== run pktio_ipc2 then pktio_ipc1 ===="
>> -       pktio_ipc2${EXEEXT} -t 20 &
>> +       pktio_ipc2${EXEEXT} -t 10 &
>>         IPC_PID=$!
>>
>> -       pktio_ipc1${EXEEXT} -p ${IPC_PID} -t 10
>> +       pktio_ipc1${EXEEXT} -p ${IPC_PID} -t 5
>>         ret=$?
>> -       (kill ${IPC_PID} 2>&1 > /dev/null) > /dev/null || true
>> +       # pktio_ipc2 do not exit on pktio_ipc1 disconnect
>> +       # wait until it exits cleanly
>> +       sleep 13
>> +       (kill ${IPC_PID} 2>&1 > /dev/null ) > /dev/null
>> +       if [ $? -eq 0 ]; then
>> +               echo "pktio_ipc2${EXEEXT} was killed"
>> +               ls -l /tmp/odp* 2> /dev/null
>> +               rm -rf /tmp/odp-${IPC_PID}* 2>&1 > /dev/null
>> +       else
>> +               echo "normal exit of 2 application"
>> +               ls -l /tmp/odp* 2> /dev/null
>> +       fi
>>
>>         if [ $ret -ne 0 ]; then
>>                 echo "!!! FAILED !!!"
>> -               ls -l /tmp/odp*
>> +               ls -l /tmp/odp* 2> /dev/null
>>                 rm -rf /tmp/odp-${IPC_PID}* 2>&1 > /dev/null
>>                 exit $ret
>>         else
>> +               ls -l /tmp/odp* 2> /dev/null
>>                 echo "Second stage PASSED"
>>         fi
>>
>> --
>> 2.7.1.250.gff4ea60
>>

Reply via email to