[PATCHv2] linux-gen: test add termination path for ipc pktio test

Message ID 1469799715-7768-1-git-send-email-maxim.uvarov@linaro.org
State New
Headers show

Commit Message

Maxim Uvarov July 29, 2016, 1:41 p.m.
Add clean termination path for ipc pktio example to destroy
all created resouces including openned shared memory.

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

---
 v2: do not touch shm_free. (Bill's comment)

 platform/linux-generic/pktio/ipc.c                 | 31 +++++++--------
 test/platform/linux-generic/pktio_ipc/ipc_common.c | 15 ++++++--
 test/platform/linux-generic/pktio_ipc/ipc_common.h |  5 ++-
 test/platform/linux-generic/pktio_ipc/pktio_ipc1.c | 45 ++++++++++++++--------
 test/platform/linux-generic/pktio_ipc/pktio_ipc2.c | 33 +++++++++++-----
 .../linux-generic/pktio_ipc/pktio_ipc_run.sh       |  1 +
 6 files changed, 81 insertions(+), 49 deletions(-)

-- 
1.9.1

Comments

Bill Fischofer July 29, 2016, 4:26 p.m. | #1
On Fri, Jul 29, 2016 at 8:41 AM, Maxim Uvarov <maxim.uvarov@linaro.org>
wrote:

> Add clean termination path for ipc pktio example to destroy

> all created resouces including openned shared memory.

>

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

>


Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org>



> ---

>  v2: do not touch shm_free. (Bill's comment)

>

>  platform/linux-generic/pktio/ipc.c                 | 31 +++++++--------

>  test/platform/linux-generic/pktio_ipc/ipc_common.c | 15 ++++++--

>  test/platform/linux-generic/pktio_ipc/ipc_common.h |  5 ++-

>  test/platform/linux-generic/pktio_ipc/pktio_ipc1.c | 45

> ++++++++++++++--------

>  test/platform/linux-generic/pktio_ipc/pktio_ipc2.c | 33 +++++++++++-----

>  .../linux-generic/pktio_ipc/pktio_ipc_run.sh       |  1 +

>  6 files changed, 81 insertions(+), 49 deletions(-)

>

> diff --git a/platform/linux-generic/pktio/ipc.c

> b/platform/linux-generic/pktio/ipc.c

> index f9e7a00..60779df 100644

> --- a/platform/linux-generic/pktio/ipc.c

> +++ b/platform/linux-generic/pktio/ipc.c

> @@ -721,6 +721,8 @@ static int ipc_start(pktio_entry_t *pktio_entry)

>

>  static int ipc_stop(pktio_entry_t *pktio_entry)

>  {

> +       unsigned tx_send, tx_free;

> +

>         odp_atomic_store_u32(&pktio_entry->s.ipc.ready, 0);

>

>         _ipc_free_ring_packets(pktio_entry->s.ipc.tx.send);

> @@ -729,21 +731,28 @@ static int ipc_stop(pktio_entry_t *pktio_entry)

>         sleep(1);

>         _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 (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));

> +       }

> +

>         return 0;

>  }

>

>  static int ipc_close(pktio_entry_t *pktio_entry)

>  {

> -       odp_shm_t shm;

>         char ipc_shm_name[ODP_POOL_NAME_LEN + sizeof("_m_prod")];

>         char *dev = pktio_entry->s.name;

>

>         ipc_stop(pktio_entry);

>

> -       /* unlink this pktio info for both master and slave */

> -       odp_shm_free(pktio_entry->s.ipc.pinfo_shm);

> -

>         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);

> +

>                 /* destroy rings */

>                 snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_cons",

> dev);

>                 _ring_destroy(ipc_shm_name);

> @@ -753,20 +762,6 @@ static int ipc_close(pktio_entry_t *pktio_entry)

>                 _ring_destroy(ipc_shm_name);

>                 snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_prod",

> dev);

>                 _ring_destroy(ipc_shm_name);

> -       } else {

> -               /* unlink rings */

> -               snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_cons",

> dev);

> -               shm = odp_shm_lookup(ipc_shm_name);

> -               odp_shm_free(shm);

> -               snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_prod",

> dev);

> -               shm = odp_shm_lookup(ipc_shm_name);

> -               odp_shm_free(shm);

> -               snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_cons",

> dev);

> -               shm = odp_shm_lookup(ipc_shm_name);

> -               odp_shm_free(shm);

> -               snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_prod",

> dev);

> -               shm = odp_shm_lookup(ipc_shm_name);

> -               odp_shm_free(shm);

>         }

>

>         return 0;

> diff --git a/test/platform/linux-generic/pktio_ipc/ipc_common.c

> b/test/platform/linux-generic/pktio_ipc/ipc_common.c

> index 2ee326e..387c921 100644

> --- a/test/platform/linux-generic/pktio_ipc/ipc_common.c

> +++ b/test/platform/linux-generic/pktio_ipc/ipc_common.c

> @@ -10,8 +10,8 @@

>  int run_time_sec;

>  int ipc_name_space;

>

> -int ipc_odp_packet_sendall(odp_pktio_t pktio,

> -                          odp_packet_t pkt_tbl[], int num)

> +int ipc_odp_packet_send_or_free(odp_pktio_t pktio,

> +                               odp_packet_t pkt_tbl[], int num)

>  {

>         int ret;

>         int sent = 0;

> @@ -19,6 +19,7 @@ int ipc_odp_packet_sendall(odp_pktio_t pktio,

>         odp_time_t end_time;

>         odp_time_t wait;

>         odp_pktout_queue_t pktout;

> +       int i;

>

>         start_time = odp_time_local();

>         wait = odp_time_local_from_ns(ODP_TIME_SEC_IN_NS);

> @@ -31,13 +32,19 @@ int ipc_odp_packet_sendall(odp_pktio_t pktio,

>

>         while (sent != num) {

>                 ret = odp_pktout_send(pktout, &pkt_tbl[sent], num - sent);

> -               if (ret < 0)

> +               if (ret < 0) {

> +                       for (i = sent; i < num; i++)

> +                               odp_packet_free(pkt_tbl[i]);

>                         return -1;

> +               }

>

>                 sent += ret;

>

> -               if (odp_time_cmp(end_time, odp_time_local()) < 0)

> +               if (odp_time_cmp(end_time, odp_time_local()) < 0) {

> +                       for (i = sent; i < num; i++)

> +                               odp_packet_free(pkt_tbl[i]);

>                         return -1;

> +               }

>         }

>

>         return 0;

> diff --git a/test/platform/linux-generic/pktio_ipc/ipc_common.h

> b/test/platform/linux-generic/pktio_ipc/ipc_common.h

> index a6b7c58..99276b5 100644

> --- a/test/platform/linux-generic/pktio_ipc/ipc_common.h

> +++ b/test/platform/linux-generic/pktio_ipc/ipc_common.h

> @@ -87,5 +87,6 @@ odp_pktio_t create_pktio(odp_pool_t pool);

>   * @param pkt_tbl      packets table

>   * @param num          number of packets

>   */

> -int ipc_odp_packet_sendall(odp_pktio_t pktio,

> -                          odp_packet_t pkt_tbl[], int num);

> +int ipc_odp_packet_send_or_free(odp_pktio_t pktio,

> +                               odp_packet_t pkt_tbl[],

> +                               int num);

> diff --git a/test/platform/linux-generic/pktio_ipc/pktio_ipc1.c

> b/test/platform/linux-generic/pktio_ipc/pktio_ipc1.c

> index a4eed88..5c1da23 100644

> --- a/test/platform/linux-generic/pktio_ipc/pktio_ipc1.c

> +++ b/test/platform/linux-generic/pktio_ipc/pktio_ipc1.c

> @@ -34,6 +34,7 @@ static int pktio_run_loop(odp_pool_t pool)

>         uint64_t stat_pkts_alloc = 0;

>         uint64_t stat_pkts_prev = 0;

>         uint64_t stat_errors = 0;

> +       uint64_t stat_free = 0;

>         odp_time_t start_cycle;

>         odp_time_t current_cycle;

>         odp_time_t cycle;

> @@ -118,19 +119,21 @@ static int pktio_run_loop(odp_pool_t pool)

>                                                              &head);

>                                 if (ret) {

>                                         stat_errors++;

> +                                       stat_free++;

>                                         odp_packet_free(pkt);

>                                         EXAMPLE_DBG("error\n");

>                                         continue;

>                                 }

>

>                                 if (head.magic == TEST_ALLOC_MAGIC) {

> -                                       stat_pkts_alloc++;

> +                                       stat_free++;

>                                         odp_packet_free(pkt);

>                                         continue;

>                                 }

>

>                                 if (head.magic != TEST_SEQ_MAGIC_2) {

>                                         stat_errors++;

> +                                       stat_free++;

>                                         odp_packet_free(pkt);

>                                         EXAMPLE_DBG("error\n");

>                                         continue;

> @@ -142,12 +145,14 @@ static int pktio_run_loop(odp_pool_t pool)

>                                                              &tail);

>                                 if (ret) {

>                                         stat_errors++;

> +                                       stat_free++;

>                                         odp_packet_free(pkt);

>                                         continue;

>                                 }

>

>                                 if (tail.magic != TEST_SEQ_MAGIC) {

>                                         stat_errors++;

> +                                       stat_free++;

>                                         odp_packet_free(pkt);

>                                         continue;

>                                 }

> @@ -163,6 +168,8 @@ static int pktio_run_loop(odp_pool_t pool)

>                                                     head.seq, cnt_recv,

>                                                     head.seq - cnt_recv);

>                                         cnt_recv = head.seq;

> +                                       stat_errors++;

> +                                       stat_free++;

>                                         continue;

>                                 }

>

> @@ -182,6 +189,7 @@ static int pktio_run_loop(odp_pool_t pool)

>                         if (pkt == ODP_PACKET_INVALID)

>                                 break;

>

> +                       stat_pkts_alloc++;

>                         odp_packet_l4_offset_set(pkt, 30);

>                         pkt_tbl[i] = pkt;

>                 }

> @@ -224,7 +232,7 @@ static int pktio_run_loop(odp_pool_t pool)

>                 }

>

>                 /* 5. Send packets to ipc_pktio */

> -               ret = ipc_odp_packet_sendall(ipc_pktio, pkt_tbl, pkts);

> +               ret = ipc_odp_packet_send_or_free(ipc_pktio, pkt_tbl,

> pkts);

>                 if (ret < 0) {

>                         EXAMPLE_DBG("unable to sending to ipc pktio\n");

>                         break;

> @@ -236,9 +244,11 @@ static int pktio_run_loop(odp_pool_t pool)

>                                  diff) < 0) {

>                         current_cycle = cycle;

>                         printf("\rpkts:  %" PRIu64 ", alloc  %" PRIu64 ","

> -                              " errors %" PRIu64 ", pps  %" PRIu64 ".",

> +                              " errors %" PRIu64 ", pps  %" PRIu64 ","

> +                              " free %" PRIu64 ".",

>                                stat_pkts, stat_pkts_alloc, stat_errors,

> -                              (stat_pkts + stat_pkts_alloc -

> stat_pkts_prev));

> +                              (stat_pkts + stat_pkts_alloc -

> stat_pkts_prev),

> +                              stat_free);

>                         fflush(stdout);

>                         stat_pkts_prev = stat_pkts + stat_pkts_alloc;

>                 }

> @@ -258,18 +268,6 @@ exit:

>                 return -1;

>         }

>

> -       ret = odp_pool_destroy(pool);

> -       if (ret) {

> -               EXAMPLE_DBG("pool_destroy error %d\n", ret);

> -               /* Remote process can end with reference to our local pool.

> -                * Usully it unmaps it clenealy but some time there are

> some

> -                * pending packets in the pool in case of remote process

> was

> -                * trapped or did not call odp_pktio_close() correctly and

> -                * release buffers and free buffer from shared rings.

> -                * return -1;

> -                */

> -       }

> -

>         return (stat_errors > 10 || stat_pkts < 1000) ? -1 : 0;

>  }

>

> @@ -324,6 +322,21 @@ int main(int argc, char *argv[])

>

>         ret = pktio_run_loop(pool);

>

> +       if (odp_pool_destroy(pool)) {

> +               EXAMPLE_ERR("Error: odp_pool_destroy() failed.\n");

> +               exit(EXIT_FAILURE);

> +       }

> +

> +       if (odp_term_local()) {

> +               EXAMPLE_ERR("Error: odp_term_local() failed.\n");

> +               exit(EXIT_FAILURE);

> +       }

> +

> +       if (odp_term_global(instance)) {

> +               EXAMPLE_ERR("Error: odp_term_global() failed.\n");

> +               exit(EXIT_FAILURE);

> +       }

> +

>         EXAMPLE_DBG("return %d\n", ret);

>         return ret;

>  }

> diff --git a/test/platform/linux-generic/pktio_ipc/pktio_ipc2.c

> b/test/platform/linux-generic/pktio_ipc/pktio_ipc2.c

> index c0c6ff5..5c1f142 100644

> --- a/test/platform/linux-generic/pktio_ipc/pktio_ipc2.c

> +++ b/test/platform/linux-generic/pktio_ipc/pktio_ipc2.c

> @@ -65,7 +65,7 @@ static int ipc_second_process(void)

>                         if (odp_time_cmp(wait, diff) < 0) {

>                                 printf("timeout exit, run_time_sec %d\n",

>                                        run_time_sec);

> -                               goto exit;

> +                               goto not_started;

>                         }

>                 }

>

> @@ -118,10 +118,11 @@ static int ipc_second_process(void)

>                 }

>

>                 /* send all packets back */

> -               ret = ipc_odp_packet_sendall(ipc_pktio, pkt_tbl, pkts);

> +               ret = ipc_odp_packet_send_or_free(ipc_pktio, pkt_tbl,

> pkts);

>                 if (ret < 0)

>                         EXAMPLE_ABORT("can not send packets\n");

> -               stat_pkts += pkts;

> +

> +               stat_pkts += ret;

>

>                 /* alloc packet from local pool, set magic to ALLOC_MAGIC,

>                  * and send it.*/

> @@ -143,7 +144,8 @@ static int ipc_second_process(void)

>                                 EXAMPLE_ABORT("unable to copy in head

> data");

>

>                         pkt_tbl[0] = alloc_pkt;

> -                       ret = ipc_odp_packet_sendall(ipc_pktio, pkt_tbl,

> 1);

> +                       ret = ipc_odp_packet_send_or_free(ipc_pktio,

> +                                                         pkt_tbl, 1);

>                         if (ret < 0)

>                                 EXAMPLE_ABORT("can not send packets\n");

>                         stat_pkts += 1;

> @@ -153,20 +155,20 @@ static int ipc_second_process(void)

>         /* cleanup and exit */

>         ret = odp_pktio_stop(ipc_pktio);

>         if (ret) {

> -               EXAMPLE_DBG("odp_pktio_stop error %d\n", ret);

> +               EXAMPLE_DBG("ipc2: odp_pktio_stop error %d\n", ret);

>                 return -1;

>         }

>

> -exit:

> +not_started:

>         ret = odp_pktio_close(ipc_pktio);

>         if (ret) {

> -               EXAMPLE_DBG("odp_pktio_close error %d\n", ret);

> +               EXAMPLE_DBG("ipc2: odp_pktio_close error %d\n", ret);

>                 return -1;

>         }

>

>         ret = odp_pool_destroy(pool);

>         if (ret)

> -               EXAMPLE_DBG("pool_destroy error %d\n", ret);

> +               EXAMPLE_DBG("ipc2: pool_destroy error %d\n", ret);

>

>         return stat_pkts > 1000 ? 0 : -1;

>  }

> @@ -175,6 +177,7 @@ 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);

> @@ -193,5 +196,17 @@ int main(int argc, char *argv[])

>                 exit(EXIT_FAILURE);

>         }

>

> -       return ipc_second_process();

> +       ret = ipc_second_process();

> +

> +       if (odp_term_local()) {

> +               EXAMPLE_ERR("Error: odp_term_local() failed.\n");

> +               exit(EXIT_FAILURE);

> +       }

> +

> +       if (odp_term_global(instance)) {

> +               EXAMPLE_ERR("Error: odp_term_global() failed.\n");

> +               exit(EXIT_FAILURE);

> +       }

> +

> +       return ret;

>  }

> diff --git a/test/platform/linux-generic/pktio_ipc/pktio_ipc_run.sh

> b/test/platform/linux-generic/pktio_ipc/pktio_ipc_run.sh

> index 1128002..2f99f32 100755

> --- a/test/platform/linux-generic/pktio_ipc/pktio_ipc_run.sh

> +++ b/test/platform/linux-generic/pktio_ipc/pktio_ipc_run.sh

> @@ -49,6 +49,7 @@ run()

>         fi

>

>         echo "==== run pktio_ipc2 then pktio_ipc1 ===="

> +       IPC_NS=`expr $IPC_NS - 1`

>         pktio_ipc2${EXEEXT} -n ${IPC_NS} -t 10 &

>         IPC_PID=$!

>

> --

> 1.9.1

>

>
Maxim Uvarov July 29, 2016, 4:57 p.m. | #2
Merged,
Maxim.

On 07/29/16 19:26, Bill Fischofer wrote:
>

>

> On Fri, Jul 29, 2016 at 8:41 AM, Maxim Uvarov <maxim.uvarov@linaro.org 

> <mailto:maxim.uvarov@linaro.org>> wrote:

>

>     Add clean termination path for ipc pktio example to destroy

>     all created resouces including openned shared memory.

>

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

>     <mailto:maxim.uvarov@linaro.org>>

>

>

> Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org 

> <mailto:bill.fischofer@linaro.org>>

>

>     ---

>      v2: do not touch shm_free. (Bill's comment)

>

>      platform/linux-generic/pktio/ipc.c                 | 31

>     +++++++--------

>      test/platform/linux-generic/pktio_ipc/ipc_common.c | 15 ++++++--

>      test/platform/linux-generic/pktio_ipc/ipc_common.h |  5 ++-

>      test/platform/linux-generic/pktio_ipc/pktio_ipc1.c | 45

>     ++++++++++++++--------

>      test/platform/linux-generic/pktio_ipc/pktio_ipc2.c | 33

>     +++++++++++-----

>      .../linux-generic/pktio_ipc/pktio_ipc_run.sh       |  1 +

>      6 files changed, 81 insertions(+), 49 deletions(-)

>

>     diff --git a/platform/linux-generic/pktio/ipc.c

>     b/platform/linux-generic/pktio/ipc.c

>     index f9e7a00..60779df 100644

>     --- a/platform/linux-generic/pktio/ipc.c

>     +++ b/platform/linux-generic/pktio/ipc.c

>     @@ -721,6 +721,8 @@ static int ipc_start(pktio_entry_t *pktio_entry)

>

>      static int ipc_stop(pktio_entry_t *pktio_entry)

>      {

>     +       unsigned tx_send, tx_free;

>     +

>     odp_atomic_store_u32(&pktio_entry->s.ipc.ready, 0);

>

>     _ipc_free_ring_packets(pktio_entry->s.ipc.tx.send);

>     @@ -729,21 +731,28 @@ static int ipc_stop(pktio_entry_t *pktio_entry)

>             sleep(1);

>     _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 (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));

>     +       }

>     +

>             return 0;

>      }

>

>      static int ipc_close(pktio_entry_t *pktio_entry)

>      {

>     -       odp_shm_t shm;

>             char ipc_shm_name[ODP_POOL_NAME_LEN + sizeof("_m_prod")];

>             char *dev = pktio_entry->s.name <http://s.name>;

>

>             ipc_stop(pktio_entry);

>

>     -       /* unlink this pktio info for both master and slave */

>     -       odp_shm_free(pktio_entry->s.ipc.pinfo_shm);

>     -

>             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);

>     +

>                     /* destroy rings */

>                     snprintf(ipc_shm_name, sizeof(ipc_shm_name),

>     "%s_s_cons", dev);

>                     _ring_destroy(ipc_shm_name);

>     @@ -753,20 +762,6 @@ static int ipc_close(pktio_entry_t *pktio_entry)

>                     _ring_destroy(ipc_shm_name);

>                     snprintf(ipc_shm_name, sizeof(ipc_shm_name),

>     "%s_m_prod", dev);

>                     _ring_destroy(ipc_shm_name);

>     -       } else {

>     -               /* unlink rings */

>     -               snprintf(ipc_shm_name, sizeof(ipc_shm_name),

>     "%s_s_cons", dev);

>     -               shm = odp_shm_lookup(ipc_shm_name);

>     -               odp_shm_free(shm);

>     -               snprintf(ipc_shm_name, sizeof(ipc_shm_name),

>     "%s_s_prod", dev);

>     -               shm = odp_shm_lookup(ipc_shm_name);

>     -               odp_shm_free(shm);

>     -               snprintf(ipc_shm_name, sizeof(ipc_shm_name),

>     "%s_m_cons", dev);

>     -               shm = odp_shm_lookup(ipc_shm_name);

>     -               odp_shm_free(shm);

>     -               snprintf(ipc_shm_name, sizeof(ipc_shm_name),

>     "%s_m_prod", dev);

>     -               shm = odp_shm_lookup(ipc_shm_name);

>     -               odp_shm_free(shm);

>             }

>

>             return 0;

>     diff --git a/test/platform/linux-generic/pktio_ipc/ipc_common.c

>     b/test/platform/linux-generic/pktio_ipc/ipc_common.c

>     index 2ee326e..387c921 100644

>     --- a/test/platform/linux-generic/pktio_ipc/ipc_common.c

>     +++ b/test/platform/linux-generic/pktio_ipc/ipc_common.c

>     @@ -10,8 +10,8 @@

>      int run_time_sec;

>      int ipc_name_space;

>

>     -int ipc_odp_packet_sendall(odp_pktio_t pktio,

>     -                          odp_packet_t pkt_tbl[], int num)

>     +int ipc_odp_packet_send_or_free(odp_pktio_t pktio,

>     +                               odp_packet_t pkt_tbl[], int num)

>      {

>             int ret;

>             int sent = 0;

>     @@ -19,6 +19,7 @@ int ipc_odp_packet_sendall(odp_pktio_t pktio,

>             odp_time_t end_time;

>             odp_time_t wait;

>             odp_pktout_queue_t pktout;

>     +       int i;

>

>             start_time = odp_time_local();

>             wait = odp_time_local_from_ns(ODP_TIME_SEC_IN_NS);

>     @@ -31,13 +32,19 @@ int ipc_odp_packet_sendall(odp_pktio_t pktio,

>

>             while (sent != num) {

>                     ret = odp_pktout_send(pktout, &pkt_tbl[sent], num

>     - sent);

>     -               if (ret < 0)

>     +               if (ret < 0) {

>     +                       for (i = sent; i < num; i++)

>     +  odp_packet_free(pkt_tbl[i]);

>                             return -1;

>     +               }

>

>                     sent += ret;

>

>     -               if (odp_time_cmp(end_time, odp_time_local()) < 0)

>     +               if (odp_time_cmp(end_time, odp_time_local()) < 0) {

>     +                       for (i = sent; i < num; i++)

>     +  odp_packet_free(pkt_tbl[i]);

>                             return -1;

>     +               }

>             }

>

>             return 0;

>     diff --git a/test/platform/linux-generic/pktio_ipc/ipc_common.h

>     b/test/platform/linux-generic/pktio_ipc/ipc_common.h

>     index a6b7c58..99276b5 100644

>     --- a/test/platform/linux-generic/pktio_ipc/ipc_common.h

>     +++ b/test/platform/linux-generic/pktio_ipc/ipc_common.h

>     @@ -87,5 +87,6 @@ odp_pktio_t create_pktio(odp_pool_t pool);

>       * @param pkt_tbl      packets table

>       * @param num          number of packets

>       */

>     -int ipc_odp_packet_sendall(odp_pktio_t pktio,

>     -                          odp_packet_t pkt_tbl[], int num);

>     +int ipc_odp_packet_send_or_free(odp_pktio_t pktio,

>     +                               odp_packet_t pkt_tbl[],

>     +                               int num);

>     diff --git a/test/platform/linux-generic/pktio_ipc/pktio_ipc1.c

>     b/test/platform/linux-generic/pktio_ipc/pktio_ipc1.c

>     index a4eed88..5c1da23 100644

>     --- a/test/platform/linux-generic/pktio_ipc/pktio_ipc1.c

>     +++ b/test/platform/linux-generic/pktio_ipc/pktio_ipc1.c

>     @@ -34,6 +34,7 @@ static int pktio_run_loop(odp_pool_t pool)

>             uint64_t stat_pkts_alloc = 0;

>             uint64_t stat_pkts_prev = 0;

>             uint64_t stat_errors = 0;

>     +       uint64_t stat_free = 0;

>             odp_time_t start_cycle;

>             odp_time_t current_cycle;

>             odp_time_t cycle;

>     @@ -118,19 +119,21 @@ static int pktio_run_loop(odp_pool_t pool)

>            &head);

>                                     if (ret) {

>                                             stat_errors++;

>     +                                       stat_free++;

>     odp_packet_free(pkt);

>     EXAMPLE_DBG("error\n");

>                                             continue;

>                                     }

>

>                                     if (head.magic == TEST_ALLOC_MAGIC) {

>     -  stat_pkts_alloc++;

>     +                                       stat_free++;

>     odp_packet_free(pkt);

>                                             continue;

>                                     }

>

>                                     if (head.magic != TEST_SEQ_MAGIC_2) {

>                                             stat_errors++;

>     +                                       stat_free++;

>     odp_packet_free(pkt);

>     EXAMPLE_DBG("error\n");

>                                             continue;

>     @@ -142,12 +145,14 @@ static int pktio_run_loop(odp_pool_t pool)

>            &tail);

>                                     if (ret) {

>                                             stat_errors++;

>     +                                       stat_free++;

>     odp_packet_free(pkt);

>                                             continue;

>                                     }

>

>                                     if (tail.magic != TEST_SEQ_MAGIC) {

>                                             stat_errors++;

>     +                                       stat_free++;

>     odp_packet_free(pkt);

>                                             continue;

>                                     }

>     @@ -163,6 +168,8 @@ static int pktio_run_loop(odp_pool_t pool)

>     head.seq, cnt_recv,

>     head.seq - cnt_recv);

>                                             cnt_recv = head.seq;

>     +                                       stat_errors++;

>     +                                       stat_free++;

>                                             continue;

>                                     }

>

>     @@ -182,6 +189,7 @@ static int pktio_run_loop(odp_pool_t pool)

>                             if (pkt == ODP_PACKET_INVALID)

>                                     break;

>

>     +                       stat_pkts_alloc++;

>                             odp_packet_l4_offset_set(pkt, 30);

>                             pkt_tbl[i] = pkt;

>                     }

>     @@ -224,7 +232,7 @@ static int pktio_run_loop(odp_pool_t pool)

>                     }

>

>                     /* 5. Send packets to ipc_pktio */

>     -               ret = ipc_odp_packet_sendall(ipc_pktio, pkt_tbl,

>     pkts);

>     +               ret = ipc_odp_packet_send_or_free(ipc_pktio,

>     pkt_tbl, pkts);

>                     if (ret < 0) {

>                             EXAMPLE_DBG("unable to sending to ipc

>     pktio\n");

>                             break;

>     @@ -236,9 +244,11 @@ static int pktio_run_loop(odp_pool_t pool)

>                                      diff) < 0) {

>                             current_cycle = cycle;

>                             printf("\rpkts:  %" PRIu64 ", alloc  %"

>     PRIu64 ","

>     -                              " errors %" PRIu64 ", pps  %"

>     PRIu64 ".",

>     +                              " errors %" PRIu64 ", pps  %"

>     PRIu64 ","

>     +                              " free %" PRIu64 ".",

>                                    stat_pkts, stat_pkts_alloc,

>     stat_errors,

>     -                              (stat_pkts + stat_pkts_alloc -

>     stat_pkts_prev));

>     +                              (stat_pkts + stat_pkts_alloc -

>     stat_pkts_prev),

>     +                              stat_free);

>                             fflush(stdout);

>                             stat_pkts_prev = stat_pkts + stat_pkts_alloc;

>                     }

>     @@ -258,18 +268,6 @@ exit:

>                     return -1;

>             }

>

>     -       ret = odp_pool_destroy(pool);

>     -       if (ret) {

>     -               EXAMPLE_DBG("pool_destroy error %d\n", ret);

>     -               /* Remote process can end with reference to our

>     local pool.

>     -                * Usully it unmaps it clenealy but some time

>     there are some

>     -                * pending packets in the pool in case of remote

>     process was

>     -                * trapped or did not call odp_pktio_close()

>     correctly and

>     -                * release buffers and free buffer from shared rings.

>     -                * return -1;

>     -                */

>     -       }

>     -

>             return (stat_errors > 10 || stat_pkts < 1000) ? -1 : 0;

>      }

>

>     @@ -324,6 +322,21 @@ int main(int argc, char *argv[])

>

>             ret = pktio_run_loop(pool);

>

>     +       if (odp_pool_destroy(pool)) {

>     +               EXAMPLE_ERR("Error: odp_pool_destroy() failed.\n");

>     +               exit(EXIT_FAILURE);

>     +       }

>     +

>     +       if (odp_term_local()) {

>     +               EXAMPLE_ERR("Error: odp_term_local() failed.\n");

>     +               exit(EXIT_FAILURE);

>     +       }

>     +

>     +       if (odp_term_global(instance)) {

>     +               EXAMPLE_ERR("Error: odp_term_global() failed.\n");

>     +               exit(EXIT_FAILURE);

>     +       }

>     +

>             EXAMPLE_DBG("return %d\n", ret);

>             return ret;

>      }

>     diff --git a/test/platform/linux-generic/pktio_ipc/pktio_ipc2.c

>     b/test/platform/linux-generic/pktio_ipc/pktio_ipc2.c

>     index c0c6ff5..5c1f142 100644

>     --- a/test/platform/linux-generic/pktio_ipc/pktio_ipc2.c

>     +++ b/test/platform/linux-generic/pktio_ipc/pktio_ipc2.c

>     @@ -65,7 +65,7 @@ static int ipc_second_process(void)

>                             if (odp_time_cmp(wait, diff) < 0) {

>                                     printf("timeout exit, run_time_sec

>     %d\n",

>                                            run_time_sec);

>     -                               goto exit;

>     +                               goto not_started;

>                             }

>                     }

>

>     @@ -118,10 +118,11 @@ static int ipc_second_process(void)

>                     }

>

>                     /* send all packets back */

>     -               ret = ipc_odp_packet_sendall(ipc_pktio, pkt_tbl,

>     pkts);

>     +               ret = ipc_odp_packet_send_or_free(ipc_pktio,

>     pkt_tbl, pkts);

>                     if (ret < 0)

>                             EXAMPLE_ABORT("can not send packets\n");

>     -               stat_pkts += pkts;

>     +

>     +               stat_pkts += ret;

>

>                     /* alloc packet from local pool, set magic to

>     ALLOC_MAGIC,

>                      * and send it.*/

>     @@ -143,7 +144,8 @@ static int ipc_second_process(void)

>                                     EXAMPLE_ABORT("unable to copy in

>     head data");

>

>                             pkt_tbl[0] = alloc_pkt;

>     -                       ret = ipc_odp_packet_sendall(ipc_pktio,

>     pkt_tbl, 1);

>     +                       ret = ipc_odp_packet_send_or_free(ipc_pktio,

>     +    pkt_tbl, 1);

>                             if (ret < 0)

>                                     EXAMPLE_ABORT("can not send

>     packets\n");

>                             stat_pkts += 1;

>     @@ -153,20 +155,20 @@ static int ipc_second_process(void)

>             /* cleanup and exit */

>             ret = odp_pktio_stop(ipc_pktio);

>             if (ret) {

>     -               EXAMPLE_DBG("odp_pktio_stop error %d\n", ret);

>     +               EXAMPLE_DBG("ipc2: odp_pktio_stop error %d\n", ret);

>                     return -1;

>             }

>

>     -exit:

>     +not_started:

>             ret = odp_pktio_close(ipc_pktio);

>             if (ret) {

>     -               EXAMPLE_DBG("odp_pktio_close error %d\n", ret);

>     +               EXAMPLE_DBG("ipc2: odp_pktio_close error %d\n", ret);

>                     return -1;

>             }

>

>             ret = odp_pool_destroy(pool);

>             if (ret)

>     -               EXAMPLE_DBG("pool_destroy error %d\n", ret);

>     +               EXAMPLE_DBG("ipc2: pool_destroy error %d\n", ret);

>

>             return stat_pkts > 1000 ? 0 : -1;

>      }

>     @@ -175,6 +177,7 @@ 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);

>     @@ -193,5 +196,17 @@ int main(int argc, char *argv[])

>                     exit(EXIT_FAILURE);

>             }

>

>     -       return ipc_second_process();

>     +       ret = ipc_second_process();

>     +

>     +       if (odp_term_local()) {

>     +               EXAMPLE_ERR("Error: odp_term_local() failed.\n");

>     +               exit(EXIT_FAILURE);

>     +       }

>     +

>     +       if (odp_term_global(instance)) {

>     +               EXAMPLE_ERR("Error: odp_term_global() failed.\n");

>     +               exit(EXIT_FAILURE);

>     +       }

>     +

>     +       return ret;

>      }

>     diff --git

>     a/test/platform/linux-generic/pktio_ipc/pktio_ipc_run.sh

>     b/test/platform/linux-generic/pktio_ipc/pktio_ipc_run.sh

>     index 1128002..2f99f32 100755

>     --- a/test/platform/linux-generic/pktio_ipc/pktio_ipc_run.sh

>     +++ b/test/platform/linux-generic/pktio_ipc/pktio_ipc_run.sh

>     @@ -49,6 +49,7 @@ run()

>             fi

>

>             echo "==== run pktio_ipc2 then pktio_ipc1 ===="

>     +       IPC_NS=`expr $IPC_NS - 1`

>             pktio_ipc2${EXEEXT} -n ${IPC_NS} -t 10 &

>             IPC_PID=$!

>

>     --

>     1.9.1

>

>

Patch

diff --git a/platform/linux-generic/pktio/ipc.c b/platform/linux-generic/pktio/ipc.c
index f9e7a00..60779df 100644
--- a/platform/linux-generic/pktio/ipc.c
+++ b/platform/linux-generic/pktio/ipc.c
@@ -721,6 +721,8 @@  static int ipc_start(pktio_entry_t *pktio_entry)
 
 static int ipc_stop(pktio_entry_t *pktio_entry)
 {
+	unsigned tx_send, tx_free;
+
 	odp_atomic_store_u32(&pktio_entry->s.ipc.ready, 0);
 
 	_ipc_free_ring_packets(pktio_entry->s.ipc.tx.send);
@@ -729,21 +731,28 @@  static int ipc_stop(pktio_entry_t *pktio_entry)
 	sleep(1);
 	_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 (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));
+	}
+
 	return 0;
 }
 
 static int ipc_close(pktio_entry_t *pktio_entry)
 {
-	odp_shm_t shm;
 	char ipc_shm_name[ODP_POOL_NAME_LEN + sizeof("_m_prod")];
 	char *dev = pktio_entry->s.name;
 
 	ipc_stop(pktio_entry);
 
-	/* unlink this pktio info for both master and slave */
-	odp_shm_free(pktio_entry->s.ipc.pinfo_shm);
-
 	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);
+
 		/* destroy rings */
 		snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_cons", dev);
 		_ring_destroy(ipc_shm_name);
@@ -753,20 +762,6 @@  static int ipc_close(pktio_entry_t *pktio_entry)
 		_ring_destroy(ipc_shm_name);
 		snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_prod", dev);
 		_ring_destroy(ipc_shm_name);
-	} else {
-		/* unlink rings */
-		snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_cons", dev);
-		shm = odp_shm_lookup(ipc_shm_name);
-		odp_shm_free(shm);
-		snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_s_prod", dev);
-		shm = odp_shm_lookup(ipc_shm_name);
-		odp_shm_free(shm);
-		snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_cons", dev);
-		shm = odp_shm_lookup(ipc_shm_name);
-		odp_shm_free(shm);
-		snprintf(ipc_shm_name, sizeof(ipc_shm_name), "%s_m_prod", dev);
-		shm = odp_shm_lookup(ipc_shm_name);
-		odp_shm_free(shm);
 	}
 
 	return 0;
diff --git a/test/platform/linux-generic/pktio_ipc/ipc_common.c b/test/platform/linux-generic/pktio_ipc/ipc_common.c
index 2ee326e..387c921 100644
--- a/test/platform/linux-generic/pktio_ipc/ipc_common.c
+++ b/test/platform/linux-generic/pktio_ipc/ipc_common.c
@@ -10,8 +10,8 @@ 
 int run_time_sec;
 int ipc_name_space;
 
-int ipc_odp_packet_sendall(odp_pktio_t pktio,
-			   odp_packet_t pkt_tbl[], int num)
+int ipc_odp_packet_send_or_free(odp_pktio_t pktio,
+				odp_packet_t pkt_tbl[], int num)
 {
 	int ret;
 	int sent = 0;
@@ -19,6 +19,7 @@  int ipc_odp_packet_sendall(odp_pktio_t pktio,
 	odp_time_t end_time;
 	odp_time_t wait;
 	odp_pktout_queue_t pktout;
+	int i;
 
 	start_time = odp_time_local();
 	wait = odp_time_local_from_ns(ODP_TIME_SEC_IN_NS);
@@ -31,13 +32,19 @@  int ipc_odp_packet_sendall(odp_pktio_t pktio,
 
 	while (sent != num) {
 		ret = odp_pktout_send(pktout, &pkt_tbl[sent], num - sent);
-		if (ret < 0)
+		if (ret < 0) {
+			for (i = sent; i < num; i++)
+				odp_packet_free(pkt_tbl[i]);
 			return -1;
+		}
 
 		sent += ret;
 
-		if (odp_time_cmp(end_time, odp_time_local()) < 0)
+		if (odp_time_cmp(end_time, odp_time_local()) < 0) {
+			for (i = sent; i < num; i++)
+				odp_packet_free(pkt_tbl[i]);
 			return -1;
+		}
 	}
 
 	return 0;
diff --git a/test/platform/linux-generic/pktio_ipc/ipc_common.h b/test/platform/linux-generic/pktio_ipc/ipc_common.h
index a6b7c58..99276b5 100644
--- a/test/platform/linux-generic/pktio_ipc/ipc_common.h
+++ b/test/platform/linux-generic/pktio_ipc/ipc_common.h
@@ -87,5 +87,6 @@  odp_pktio_t create_pktio(odp_pool_t pool);
  * @param pkt_tbl	packets table
  * @param num		number of packets
  */
-int ipc_odp_packet_sendall(odp_pktio_t pktio,
-			   odp_packet_t pkt_tbl[], int num);
+int ipc_odp_packet_send_or_free(odp_pktio_t pktio,
+				odp_packet_t pkt_tbl[],
+				int num);
diff --git a/test/platform/linux-generic/pktio_ipc/pktio_ipc1.c b/test/platform/linux-generic/pktio_ipc/pktio_ipc1.c
index a4eed88..5c1da23 100644
--- a/test/platform/linux-generic/pktio_ipc/pktio_ipc1.c
+++ b/test/platform/linux-generic/pktio_ipc/pktio_ipc1.c
@@ -34,6 +34,7 @@  static int pktio_run_loop(odp_pool_t pool)
 	uint64_t stat_pkts_alloc = 0;
 	uint64_t stat_pkts_prev = 0;
 	uint64_t stat_errors = 0;
+	uint64_t stat_free = 0;
 	odp_time_t start_cycle;
 	odp_time_t current_cycle;
 	odp_time_t cycle;
@@ -118,19 +119,21 @@  static int pktio_run_loop(odp_pool_t pool)
 							     &head);
 				if (ret) {
 					stat_errors++;
+					stat_free++;
 					odp_packet_free(pkt);
 					EXAMPLE_DBG("error\n");
 					continue;
 				}
 
 				if (head.magic == TEST_ALLOC_MAGIC) {
-					stat_pkts_alloc++;
+					stat_free++;
 					odp_packet_free(pkt);
 					continue;
 				}
 
 				if (head.magic != TEST_SEQ_MAGIC_2) {
 					stat_errors++;
+					stat_free++;
 					odp_packet_free(pkt);
 					EXAMPLE_DBG("error\n");
 					continue;
@@ -142,12 +145,14 @@  static int pktio_run_loop(odp_pool_t pool)
 							     &tail);
 				if (ret) {
 					stat_errors++;
+					stat_free++;
 					odp_packet_free(pkt);
 					continue;
 				}
 
 				if (tail.magic != TEST_SEQ_MAGIC) {
 					stat_errors++;
+					stat_free++;
 					odp_packet_free(pkt);
 					continue;
 				}
@@ -163,6 +168,8 @@  static int pktio_run_loop(odp_pool_t pool)
 						    head.seq, cnt_recv,
 						    head.seq - cnt_recv);
 					cnt_recv = head.seq;
+					stat_errors++;
+					stat_free++;
 					continue;
 				}
 
@@ -182,6 +189,7 @@  static int pktio_run_loop(odp_pool_t pool)
 			if (pkt == ODP_PACKET_INVALID)
 				break;
 
+			stat_pkts_alloc++;
 			odp_packet_l4_offset_set(pkt, 30);
 			pkt_tbl[i] = pkt;
 		}
@@ -224,7 +232,7 @@  static int pktio_run_loop(odp_pool_t pool)
 		}
 
 		/* 5. Send packets to ipc_pktio */
-		ret = ipc_odp_packet_sendall(ipc_pktio, pkt_tbl, pkts);
+		ret = ipc_odp_packet_send_or_free(ipc_pktio, pkt_tbl, pkts);
 		if (ret < 0) {
 			EXAMPLE_DBG("unable to sending to ipc pktio\n");
 			break;
@@ -236,9 +244,11 @@  static int pktio_run_loop(odp_pool_t pool)
 				 diff) < 0) {
 			current_cycle = cycle;
 			printf("\rpkts:  %" PRIu64 ", alloc  %" PRIu64 ","
-			       " errors %" PRIu64 ", pps  %" PRIu64 ".",
+			       " errors %" PRIu64 ", pps  %" PRIu64 ","
+			       " free %" PRIu64 ".",
 			       stat_pkts, stat_pkts_alloc, stat_errors,
-			       (stat_pkts + stat_pkts_alloc - stat_pkts_prev));
+			       (stat_pkts + stat_pkts_alloc - stat_pkts_prev),
+			       stat_free);
 			fflush(stdout);
 			stat_pkts_prev = stat_pkts + stat_pkts_alloc;
 		}
@@ -258,18 +268,6 @@  exit:
 		return -1;
 	}
 
-	ret = odp_pool_destroy(pool);
-	if (ret) {
-		EXAMPLE_DBG("pool_destroy error %d\n", ret);
-		/* Remote process can end with reference to our local pool.
-		 * Usully it unmaps it clenealy but some time there are some
-		 * pending packets in the pool in case of remote process was
-		 * trapped or did not call odp_pktio_close() correctly and
-		 * release buffers and free buffer from shared rings.
-		 * return -1;
-		 */
-	}
-
 	return (stat_errors > 10 || stat_pkts < 1000) ? -1 : 0;
 }
 
@@ -324,6 +322,21 @@  int main(int argc, char *argv[])
 
 	ret = pktio_run_loop(pool);
 
+	if (odp_pool_destroy(pool)) {
+		EXAMPLE_ERR("Error: odp_pool_destroy() failed.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	if (odp_term_local()) {
+		EXAMPLE_ERR("Error: odp_term_local() failed.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	if (odp_term_global(instance)) {
+		EXAMPLE_ERR("Error: odp_term_global() failed.\n");
+		exit(EXIT_FAILURE);
+	}
+
 	EXAMPLE_DBG("return %d\n", ret);
 	return ret;
 }
diff --git a/test/platform/linux-generic/pktio_ipc/pktio_ipc2.c b/test/platform/linux-generic/pktio_ipc/pktio_ipc2.c
index c0c6ff5..5c1f142 100644
--- a/test/platform/linux-generic/pktio_ipc/pktio_ipc2.c
+++ b/test/platform/linux-generic/pktio_ipc/pktio_ipc2.c
@@ -65,7 +65,7 @@  static int ipc_second_process(void)
 			if (odp_time_cmp(wait, diff) < 0) {
 				printf("timeout exit, run_time_sec %d\n",
 				       run_time_sec);
-				goto exit;
+				goto not_started;
 			}
 		}
 
@@ -118,10 +118,11 @@  static int ipc_second_process(void)
 		}
 
 		/* send all packets back */
-		ret = ipc_odp_packet_sendall(ipc_pktio, pkt_tbl, pkts);
+		ret = ipc_odp_packet_send_or_free(ipc_pktio, pkt_tbl, pkts);
 		if (ret < 0)
 			EXAMPLE_ABORT("can not send packets\n");
-		stat_pkts += pkts;
+
+		stat_pkts += ret;
 
 		/* alloc packet from local pool, set magic to ALLOC_MAGIC,
 		 * and send it.*/
@@ -143,7 +144,8 @@  static int ipc_second_process(void)
 				EXAMPLE_ABORT("unable to copy in head data");
 
 			pkt_tbl[0] = alloc_pkt;
-			ret = ipc_odp_packet_sendall(ipc_pktio, pkt_tbl, 1);
+			ret = ipc_odp_packet_send_or_free(ipc_pktio,
+							  pkt_tbl, 1);
 			if (ret < 0)
 				EXAMPLE_ABORT("can not send packets\n");
 			stat_pkts += 1;
@@ -153,20 +155,20 @@  static int ipc_second_process(void)
 	/* cleanup and exit */
 	ret = odp_pktio_stop(ipc_pktio);
 	if (ret) {
-		EXAMPLE_DBG("odp_pktio_stop error %d\n", ret);
+		EXAMPLE_DBG("ipc2: odp_pktio_stop error %d\n", ret);
 		return -1;
 	}
 
-exit:
+not_started:
 	ret = odp_pktio_close(ipc_pktio);
 	if (ret) {
-		EXAMPLE_DBG("odp_pktio_close error %d\n", ret);
+		EXAMPLE_DBG("ipc2: odp_pktio_close error %d\n", ret);
 		return -1;
 	}
 
 	ret = odp_pool_destroy(pool);
 	if (ret)
-		EXAMPLE_DBG("pool_destroy error %d\n", ret);
+		EXAMPLE_DBG("ipc2: pool_destroy error %d\n", ret);
 
 	return stat_pkts > 1000 ? 0 : -1;
 }
@@ -175,6 +177,7 @@  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);
@@ -193,5 +196,17 @@  int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 
-	return ipc_second_process();
+	ret = ipc_second_process();
+
+	if (odp_term_local()) {
+		EXAMPLE_ERR("Error: odp_term_local() failed.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	if (odp_term_global(instance)) {
+		EXAMPLE_ERR("Error: odp_term_global() failed.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	return ret;
 }
diff --git a/test/platform/linux-generic/pktio_ipc/pktio_ipc_run.sh b/test/platform/linux-generic/pktio_ipc/pktio_ipc_run.sh
index 1128002..2f99f32 100755
--- a/test/platform/linux-generic/pktio_ipc/pktio_ipc_run.sh
+++ b/test/platform/linux-generic/pktio_ipc/pktio_ipc_run.sh
@@ -49,6 +49,7 @@  run()
 	fi
 
 	echo "==== run pktio_ipc2 then pktio_ipc1 ===="
+	IPC_NS=`expr $IPC_NS - 1`
 	pktio_ipc2${EXEEXT} -n ${IPC_NS} -t 10 &
 	IPC_PID=$!