diff mbox

[PATCHv4] validation: pktio: test batch receive

Message ID 1452089457-9740-1-git-send-email-stuart.haslam@linaro.org
State Accepted
Commit 129353cb807c8b8b1809200fb829ea3821008281
Headers show

Commit Message

Stuart Haslam Jan. 6, 2016, 2:10 p.m. UTC
Modify the tests that currently transmit packets in batches to also
receive packets in batches. This adds coverage of odp_queue_deq_multi()
and odp_schedule_multi() specifically against a packet input queue,
as this doesn't get tested anywhere else in the validation suite.

Signed-off-by: Stuart Haslam <stuart.haslam@linaro.org>
---
Changes in v4 - rebased and picked up new new time API

Changes in v3 - test odp_queue_[enq|deq]_multi() and odp_schedule_multi()
                APIs with batch length of 1.

Changes in v2 - rebased and picked up new time API

 test/validation/pktio/pktio.c | 184 ++++++++++++++++++++++--------------------
 1 file changed, 98 insertions(+), 86 deletions(-)

Comments

Maxim Uvarov Jan. 13, 2016, 12:50 p.m. UTC | #1
Merged,

Maxim.

On 01/06/2016 17:10, Stuart Haslam wrote:
> Modify the tests that currently transmit packets in batches to also
> receive packets in batches. This adds coverage of odp_queue_deq_multi()
> and odp_schedule_multi() specifically against a packet input queue,
> as this doesn't get tested anywhere else in the validation suite.
>
> Signed-off-by: Stuart Haslam <stuart.haslam@linaro.org>
> ---
> Changes in v4 - rebased and picked up new new time API
>
> Changes in v3 - test odp_queue_[enq|deq]_multi() and odp_schedule_multi()
>                  APIs with batch length of 1.
>
> Changes in v2 - rebased and picked up new time API
>
>   test/validation/pktio/pktio.c | 184 ++++++++++++++++++++++--------------------
>   1 file changed, 98 insertions(+), 86 deletions(-)
>
> diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
> index e473a1d..8f90e0a 100644
> --- a/test/validation/pktio/pktio.c
> +++ b/test/validation/pktio/pktio.c
> @@ -58,8 +58,13 @@ typedef struct ODP_PACKED {
>   typedef enum {
>   	PKT_POOL_UNSEGMENTED,
>   	PKT_POOL_SEGMENTED,
> -} pkt_segmented_e
> -;
> +} pkt_segmented_e;
> +
> +typedef enum {
> +	TXRX_MODE_SINGLE,
> +	TXRX_MODE_MULTI
> +} txrx_mode_e;
> +
>   /** size of transmitted packets */
>   static uint32_t packet_len = PKT_LEN_NORMAL;
>   
> @@ -357,73 +362,84 @@ static int destroy_inq(odp_pktio_t pktio)
>   	return odp_queue_destroy(inq);
>   }
>   
> -static odp_event_t queue_deq_wait_time(odp_queue_t queue, uint64_t ns)
> +static int get_packets(pktio_info_t *pktio_rx, odp_packet_t pkt_tbl[],
> +		       int num, txrx_mode_e mode)
>   {
> -	odp_time_t wait, end;
> -	odp_event_t ev;
> +	odp_event_t evt_tbl[num];
> +	int num_evts = 0;
> +	int num_pkts = 0;
> +	int i;
>   
> -	wait = odp_time_local_from_ns(ns);
> -	end = odp_time_sum(odp_time_local(), wait);
> -	do {
> -		ev = odp_queue_deq(queue);
> -		if (ev != ODP_EVENT_INVALID)
> -			return ev;
> -	} while (odp_time_cmp(end, odp_time_local()) > 0);
> +	if (pktio_rx->in_mode == ODP_PKTIN_MODE_RECV)
> +		return odp_pktio_recv(pktio_rx->id, pkt_tbl, num);
>   
> -	return ODP_EVENT_INVALID;
> +	if (mode == TXRX_MODE_MULTI) {
> +		if (pktio_rx->in_mode == ODP_PKTIN_MODE_POLL)
> +			num_evts = odp_queue_deq_multi(pktio_rx->inq, evt_tbl,
> +						       num);
> +		else
> +			num_evts = odp_schedule_multi(NULL, ODP_SCHED_NO_WAIT,
> +						      evt_tbl, num);
> +	} else {
> +		odp_event_t evt_tmp;
> +
> +		if (pktio_rx->in_mode == ODP_PKTIN_MODE_POLL)
> +			evt_tmp = odp_queue_deq(pktio_rx->inq);
> +		else
> +			evt_tmp = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
> +
> +		if (evt_tmp != ODP_EVENT_INVALID)
> +			evt_tbl[num_evts++] = evt_tmp;
> +	}
> +
> +	/* convert events to packets, discarding any non-packet events */
> +	for (i = 0; i < num_evts; ++i) {
> +		if (odp_event_type(evt_tbl[i]) == ODP_EVENT_PACKET)
> +			pkt_tbl[num_pkts++] = odp_packet_from_event(evt_tbl[i]);
> +		else
> +			odp_event_free(evt_tbl[i]);
> +	}
> +
> +	return num_pkts;
>   }
>   
> -static odp_packet_t wait_for_packet(pktio_info_t *pktio_rx,
> -				    uint32_t seq, uint64_t ns)
> +static int wait_for_packets(pktio_info_t *pktio_rx, odp_packet_t pkt_tbl[],
> +			    uint32_t seq_tbl[], int num, txrx_mode_e mode,
> +			    uint64_t ns)
>   {
>   	odp_time_t wait_time, end;
> -	odp_event_t ev;
> -	odp_packet_t pkt;
> -	uint64_t wait;
> +	int num_rx = 0;
> +	int i;
> +	odp_packet_t pkt_tmp[num];
>   
> -	wait = odp_schedule_wait_time(ns);
>   	wait_time = odp_time_local_from_ns(ns);
>   	end = odp_time_sum(odp_time_local(), wait_time);
> -	do {
> -		pkt = ODP_PACKET_INVALID;
> -
> -		if (pktio_rx->in_mode == ODP_PKTIN_MODE_RECV) {
> -			odp_pktio_recv(pktio_rx->id, &pkt, 1);
> -		} else {
> -			if (pktio_rx->in_mode == ODP_PKTIN_MODE_POLL)
> -				ev = queue_deq_wait_time(pktio_rx->inq, ns);
> -			else
> -				ev = odp_schedule(NULL, wait);
>   
> -			if (ev != ODP_EVENT_INVALID) {
> -				if (odp_event_type(ev) == ODP_EVENT_PACKET)
> -					pkt = odp_packet_from_event(ev);
> -				else
> -					odp_event_free(ev);
> -			}
> -		}
> +	do {
> +		int n = get_packets(pktio_rx, pkt_tmp, num - num_rx, mode);
>   
> -		if (pkt != ODP_PACKET_INVALID) {
> -			if (pktio_pkt_seq(pkt) == seq)
> -				return pkt;
> +		if (n < 0)
> +			break;
>   
> -			odp_packet_free(pkt);
> +		for (i = 0; i < n; ++i) {
> +			if (pktio_pkt_seq(pkt_tmp[i]) == seq_tbl[num_rx])
> +				pkt_tbl[num_rx++] = pkt_tmp[i];
> +			else
> +				odp_packet_free(pkt_tmp[i]);
>   		}
> -	} while (odp_time_cmp(end, odp_time_local()) > 0);
> +	} while (num_rx < num && odp_time_cmp(end, odp_time_local()) > 0);
>   
> -	CU_FAIL("failed to receive transmitted packet");
> -
> -	return ODP_PACKET_INVALID;
> +	return num_rx;
>   }
>   
>   static void pktio_txrx_multi(pktio_info_t *pktio_a, pktio_info_t *pktio_b,
> -			     int num_pkts)
> +			     int num_pkts, txrx_mode_e mode)
>   {
>   	odp_packet_t tx_pkt[num_pkts];
>   	odp_event_t tx_ev[num_pkts];
> -	odp_packet_t rx_pkt;
> +	odp_packet_t rx_pkt[num_pkts];
>   	uint32_t tx_seq[num_pkts];
> -	int i, ret;
> +	int i, ret, num_rx;
>   
>   	/* generate test packets to send */
>   	for (i = 0; i < num_pkts; ++i) {
> @@ -452,12 +468,14 @@ static void pktio_txrx_multi(pktio_info_t *pktio_a, pktio_info_t *pktio_b,
>   	}
>   
>   	/* send packet(s) out */
> -	if (num_pkts == 1) {
> -		ret = odp_queue_enq(pktio_a->outq, tx_ev[0]);
> -		if (ret != 0) {
> -			CU_FAIL("failed to enqueue test packet");
> -			odp_packet_free(tx_pkt[0]);
> -			return;
> +	if (mode == TXRX_MODE_SINGLE) {
> +		for (i = 0; i < num_pkts; ++i) {
> +			ret = odp_queue_enq(pktio_a->outq, tx_ev[i]);
> +			if (ret != 0) {
> +				CU_FAIL("failed to enqueue test packet");
> +				odp_packet_free(tx_pkt[i]);
> +				return;
> +			}
>   		}
>   	} else {
>   		ret = odp_queue_enq_multi(pktio_a->outq, tx_ev, num_pkts);
> @@ -471,21 +489,20 @@ static void pktio_txrx_multi(pktio_info_t *pktio_a, pktio_info_t *pktio_b,
>   	}
>   
>   	/* and wait for them to arrive back */
> -	for (i = 0; i < num_pkts; ++i) {
> -		rx_pkt = wait_for_packet(pktio_b, tx_seq[i],
> -					 ODP_TIME_SEC_IN_NS);
> -
> -		if (rx_pkt == ODP_PACKET_INVALID)
> -			break;
> -		CU_ASSERT(odp_packet_input(rx_pkt) == pktio_b->id);
> -		CU_ASSERT(odp_packet_has_error(rx_pkt) == 0);
> -		odp_packet_free(rx_pkt);
> +	num_rx = wait_for_packets(pktio_b, rx_pkt, tx_seq,
> +				  num_pkts, mode, ODP_TIME_SEC_IN_NS);
> +	CU_ASSERT(num_rx == num_pkts);
> +
> +	for (i = 0; i < num_rx; ++i) {
> +		CU_ASSERT_FATAL(rx_pkt[i] != ODP_PACKET_INVALID);
> +		CU_ASSERT(odp_packet_input(rx_pkt[i]) == pktio_b->id);
> +		CU_ASSERT(odp_packet_has_error(rx_pkt[i]) == 0);
> +		odp_packet_free(rx_pkt[i]);
>   	}
> -
> -	CU_ASSERT(i == num_pkts);
>   }
>   
> -static void test_txrx(odp_pktio_input_mode_t in_mode, int num_pkts)
> +static void test_txrx(odp_pktio_input_mode_t in_mode, int num_pkts,
> +		      txrx_mode_e mode)
>   {
>   	int ret, i, if_b;
>   	pktio_info_t pktios[MAX_NUM_IFACES];
> @@ -519,7 +536,7 @@ static void test_txrx(odp_pktio_input_mode_t in_mode, int num_pkts)
>   	/* if we have two interfaces then send through one and receive on
>   	 * another but if there's only one assume it's a loopback */
>   	if_b = (num_ifaces == 1) ? 0 : 1;
> -	pktio_txrx_multi(&pktios[0], &pktios[if_b], num_pkts);
> +	pktio_txrx_multi(&pktios[0], &pktios[if_b], num_pkts, mode);
>   
>   	for (i = 0; i < num_ifaces; ++i) {
>   		ret = odp_pktio_stop(pktios[i].id);
> @@ -533,32 +550,36 @@ static void test_txrx(odp_pktio_input_mode_t in_mode, int num_pkts)
>   
>   void pktio_test_poll_queue(void)
>   {
> -	test_txrx(ODP_PKTIN_MODE_POLL, 1);
> +	test_txrx(ODP_PKTIN_MODE_POLL, 1, TXRX_MODE_SINGLE);
> +	test_txrx(ODP_PKTIN_MODE_POLL, TX_BATCH_LEN, TXRX_MODE_SINGLE);
>   }
>   
>   void pktio_test_poll_multi(void)
>   {
> -	test_txrx(ODP_PKTIN_MODE_POLL, TX_BATCH_LEN);
> +	test_txrx(ODP_PKTIN_MODE_POLL, TX_BATCH_LEN, TXRX_MODE_MULTI);
> +	test_txrx(ODP_PKTIN_MODE_POLL, 1, TXRX_MODE_MULTI);
>   }
>   
>   void pktio_test_sched_queue(void)
>   {
> -	test_txrx(ODP_PKTIN_MODE_SCHED, 1);
> +	test_txrx(ODP_PKTIN_MODE_SCHED, 1, TXRX_MODE_SINGLE);
> +	test_txrx(ODP_PKTIN_MODE_SCHED, TX_BATCH_LEN, TXRX_MODE_SINGLE);
>   }
>   
>   void pktio_test_sched_multi(void)
>   {
> -	test_txrx(ODP_PKTIN_MODE_SCHED, TX_BATCH_LEN);
> +	test_txrx(ODP_PKTIN_MODE_SCHED, TX_BATCH_LEN, TXRX_MODE_MULTI);
> +	test_txrx(ODP_PKTIN_MODE_SCHED, 1, TXRX_MODE_MULTI);
>   }
>   
>   void pktio_test_recv(void)
>   {
> -	test_txrx(ODP_PKTIN_MODE_RECV, 1);
> +	test_txrx(ODP_PKTIN_MODE_RECV, 1, TXRX_MODE_SINGLE);
>   }
>   
>   void pktio_test_recv_multi(void)
>   {
> -	test_txrx(ODP_PKTIN_MODE_RECV, TX_BATCH_LEN);
> +	test_txrx(ODP_PKTIN_MODE_RECV, TX_BATCH_LEN, TXRX_MODE_MULTI);
>   }
>   
>   void pktio_test_jumbo(void)
> @@ -976,12 +997,8 @@ void pktio_test_send_failure(void)
>   		info_rx.inq  = ODP_QUEUE_INVALID;
>   		info_rx.in_mode = ODP_PKTIN_MODE_RECV;
>   
> -		for (i = 0; i < ret; ++i) {
> -			pkt_tbl[i] = wait_for_packet(&info_rx, pkt_seq[i],
> -						     ODP_TIME_SEC_IN_NS);
> -			if (pkt_tbl[i] == ODP_PACKET_INVALID)
> -				break;
> -		}
> +		i = wait_for_packets(&info_rx, pkt_tbl, pkt_seq, ret,
> +				     TXRX_MODE_MULTI, ODP_TIME_SEC_IN_NS);
>   
>   		if (i == ret) {
>   			/* now try to send starting with the too-long packet
> @@ -1012,14 +1029,9 @@ void pktio_test_send_failure(void)
>   		ret = odp_pktio_send(pktio_tx, &pkt_tbl[i], TX_BATCH_LEN - i);
>   		CU_ASSERT_FATAL(ret == (TX_BATCH_LEN - i));
>   
> -		for (; i < TX_BATCH_LEN; ++i) {
> -			pkt_tbl[i] = wait_for_packet(&info_rx,
> -						     pkt_seq[i],
> -						     ODP_TIME_SEC_IN_NS);
> -			if (pkt_tbl[i] == ODP_PACKET_INVALID)
> -				break;
> -		}
> -		CU_ASSERT(i == TX_BATCH_LEN);
> +		i = wait_for_packets(&info_rx, &pkt_tbl[i], &pkt_seq[i], ret,
> +				     TXRX_MODE_MULTI, ODP_TIME_SEC_IN_NS);
> +		CU_ASSERT(i == ret);
>   	} else {
>   		CU_FAIL("failed to generate test packets\n");
>   	}
diff mbox

Patch

diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
index e473a1d..8f90e0a 100644
--- a/test/validation/pktio/pktio.c
+++ b/test/validation/pktio/pktio.c
@@ -58,8 +58,13 @@  typedef struct ODP_PACKED {
 typedef enum {
 	PKT_POOL_UNSEGMENTED,
 	PKT_POOL_SEGMENTED,
-} pkt_segmented_e
-;
+} pkt_segmented_e;
+
+typedef enum {
+	TXRX_MODE_SINGLE,
+	TXRX_MODE_MULTI
+} txrx_mode_e;
+
 /** size of transmitted packets */
 static uint32_t packet_len = PKT_LEN_NORMAL;
 
@@ -357,73 +362,84 @@  static int destroy_inq(odp_pktio_t pktio)
 	return odp_queue_destroy(inq);
 }
 
-static odp_event_t queue_deq_wait_time(odp_queue_t queue, uint64_t ns)
+static int get_packets(pktio_info_t *pktio_rx, odp_packet_t pkt_tbl[],
+		       int num, txrx_mode_e mode)
 {
-	odp_time_t wait, end;
-	odp_event_t ev;
+	odp_event_t evt_tbl[num];
+	int num_evts = 0;
+	int num_pkts = 0;
+	int i;
 
-	wait = odp_time_local_from_ns(ns);
-	end = odp_time_sum(odp_time_local(), wait);
-	do {
-		ev = odp_queue_deq(queue);
-		if (ev != ODP_EVENT_INVALID)
-			return ev;
-	} while (odp_time_cmp(end, odp_time_local()) > 0);
+	if (pktio_rx->in_mode == ODP_PKTIN_MODE_RECV)
+		return odp_pktio_recv(pktio_rx->id, pkt_tbl, num);
 
-	return ODP_EVENT_INVALID;
+	if (mode == TXRX_MODE_MULTI) {
+		if (pktio_rx->in_mode == ODP_PKTIN_MODE_POLL)
+			num_evts = odp_queue_deq_multi(pktio_rx->inq, evt_tbl,
+						       num);
+		else
+			num_evts = odp_schedule_multi(NULL, ODP_SCHED_NO_WAIT,
+						      evt_tbl, num);
+	} else {
+		odp_event_t evt_tmp;
+
+		if (pktio_rx->in_mode == ODP_PKTIN_MODE_POLL)
+			evt_tmp = odp_queue_deq(pktio_rx->inq);
+		else
+			evt_tmp = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
+
+		if (evt_tmp != ODP_EVENT_INVALID)
+			evt_tbl[num_evts++] = evt_tmp;
+	}
+
+	/* convert events to packets, discarding any non-packet events */
+	for (i = 0; i < num_evts; ++i) {
+		if (odp_event_type(evt_tbl[i]) == ODP_EVENT_PACKET)
+			pkt_tbl[num_pkts++] = odp_packet_from_event(evt_tbl[i]);
+		else
+			odp_event_free(evt_tbl[i]);
+	}
+
+	return num_pkts;
 }
 
-static odp_packet_t wait_for_packet(pktio_info_t *pktio_rx,
-				    uint32_t seq, uint64_t ns)
+static int wait_for_packets(pktio_info_t *pktio_rx, odp_packet_t pkt_tbl[],
+			    uint32_t seq_tbl[], int num, txrx_mode_e mode,
+			    uint64_t ns)
 {
 	odp_time_t wait_time, end;
-	odp_event_t ev;
-	odp_packet_t pkt;
-	uint64_t wait;
+	int num_rx = 0;
+	int i;
+	odp_packet_t pkt_tmp[num];
 
-	wait = odp_schedule_wait_time(ns);
 	wait_time = odp_time_local_from_ns(ns);
 	end = odp_time_sum(odp_time_local(), wait_time);
-	do {
-		pkt = ODP_PACKET_INVALID;
-
-		if (pktio_rx->in_mode == ODP_PKTIN_MODE_RECV) {
-			odp_pktio_recv(pktio_rx->id, &pkt, 1);
-		} else {
-			if (pktio_rx->in_mode == ODP_PKTIN_MODE_POLL)
-				ev = queue_deq_wait_time(pktio_rx->inq, ns);
-			else
-				ev = odp_schedule(NULL, wait);
 
-			if (ev != ODP_EVENT_INVALID) {
-				if (odp_event_type(ev) == ODP_EVENT_PACKET)
-					pkt = odp_packet_from_event(ev);
-				else
-					odp_event_free(ev);
-			}
-		}
+	do {
+		int n = get_packets(pktio_rx, pkt_tmp, num - num_rx, mode);
 
-		if (pkt != ODP_PACKET_INVALID) {
-			if (pktio_pkt_seq(pkt) == seq)
-				return pkt;
+		if (n < 0)
+			break;
 
-			odp_packet_free(pkt);
+		for (i = 0; i < n; ++i) {
+			if (pktio_pkt_seq(pkt_tmp[i]) == seq_tbl[num_rx])
+				pkt_tbl[num_rx++] = pkt_tmp[i];
+			else
+				odp_packet_free(pkt_tmp[i]);
 		}
-	} while (odp_time_cmp(end, odp_time_local()) > 0);
+	} while (num_rx < num && odp_time_cmp(end, odp_time_local()) > 0);
 
-	CU_FAIL("failed to receive transmitted packet");
-
-	return ODP_PACKET_INVALID;
+	return num_rx;
 }
 
 static void pktio_txrx_multi(pktio_info_t *pktio_a, pktio_info_t *pktio_b,
-			     int num_pkts)
+			     int num_pkts, txrx_mode_e mode)
 {
 	odp_packet_t tx_pkt[num_pkts];
 	odp_event_t tx_ev[num_pkts];
-	odp_packet_t rx_pkt;
+	odp_packet_t rx_pkt[num_pkts];
 	uint32_t tx_seq[num_pkts];
-	int i, ret;
+	int i, ret, num_rx;
 
 	/* generate test packets to send */
 	for (i = 0; i < num_pkts; ++i) {
@@ -452,12 +468,14 @@  static void pktio_txrx_multi(pktio_info_t *pktio_a, pktio_info_t *pktio_b,
 	}
 
 	/* send packet(s) out */
-	if (num_pkts == 1) {
-		ret = odp_queue_enq(pktio_a->outq, tx_ev[0]);
-		if (ret != 0) {
-			CU_FAIL("failed to enqueue test packet");
-			odp_packet_free(tx_pkt[0]);
-			return;
+	if (mode == TXRX_MODE_SINGLE) {
+		for (i = 0; i < num_pkts; ++i) {
+			ret = odp_queue_enq(pktio_a->outq, tx_ev[i]);
+			if (ret != 0) {
+				CU_FAIL("failed to enqueue test packet");
+				odp_packet_free(tx_pkt[i]);
+				return;
+			}
 		}
 	} else {
 		ret = odp_queue_enq_multi(pktio_a->outq, tx_ev, num_pkts);
@@ -471,21 +489,20 @@  static void pktio_txrx_multi(pktio_info_t *pktio_a, pktio_info_t *pktio_b,
 	}
 
 	/* and wait for them to arrive back */
-	for (i = 0; i < num_pkts; ++i) {
-		rx_pkt = wait_for_packet(pktio_b, tx_seq[i],
-					 ODP_TIME_SEC_IN_NS);
-
-		if (rx_pkt == ODP_PACKET_INVALID)
-			break;
-		CU_ASSERT(odp_packet_input(rx_pkt) == pktio_b->id);
-		CU_ASSERT(odp_packet_has_error(rx_pkt) == 0);
-		odp_packet_free(rx_pkt);
+	num_rx = wait_for_packets(pktio_b, rx_pkt, tx_seq,
+				  num_pkts, mode, ODP_TIME_SEC_IN_NS);
+	CU_ASSERT(num_rx == num_pkts);
+
+	for (i = 0; i < num_rx; ++i) {
+		CU_ASSERT_FATAL(rx_pkt[i] != ODP_PACKET_INVALID);
+		CU_ASSERT(odp_packet_input(rx_pkt[i]) == pktio_b->id);
+		CU_ASSERT(odp_packet_has_error(rx_pkt[i]) == 0);
+		odp_packet_free(rx_pkt[i]);
 	}
-
-	CU_ASSERT(i == num_pkts);
 }
 
-static void test_txrx(odp_pktio_input_mode_t in_mode, int num_pkts)
+static void test_txrx(odp_pktio_input_mode_t in_mode, int num_pkts,
+		      txrx_mode_e mode)
 {
 	int ret, i, if_b;
 	pktio_info_t pktios[MAX_NUM_IFACES];
@@ -519,7 +536,7 @@  static void test_txrx(odp_pktio_input_mode_t in_mode, int num_pkts)
 	/* if we have two interfaces then send through one and receive on
 	 * another but if there's only one assume it's a loopback */
 	if_b = (num_ifaces == 1) ? 0 : 1;
-	pktio_txrx_multi(&pktios[0], &pktios[if_b], num_pkts);
+	pktio_txrx_multi(&pktios[0], &pktios[if_b], num_pkts, mode);
 
 	for (i = 0; i < num_ifaces; ++i) {
 		ret = odp_pktio_stop(pktios[i].id);
@@ -533,32 +550,36 @@  static void test_txrx(odp_pktio_input_mode_t in_mode, int num_pkts)
 
 void pktio_test_poll_queue(void)
 {
-	test_txrx(ODP_PKTIN_MODE_POLL, 1);
+	test_txrx(ODP_PKTIN_MODE_POLL, 1, TXRX_MODE_SINGLE);
+	test_txrx(ODP_PKTIN_MODE_POLL, TX_BATCH_LEN, TXRX_MODE_SINGLE);
 }
 
 void pktio_test_poll_multi(void)
 {
-	test_txrx(ODP_PKTIN_MODE_POLL, TX_BATCH_LEN);
+	test_txrx(ODP_PKTIN_MODE_POLL, TX_BATCH_LEN, TXRX_MODE_MULTI);
+	test_txrx(ODP_PKTIN_MODE_POLL, 1, TXRX_MODE_MULTI);
 }
 
 void pktio_test_sched_queue(void)
 {
-	test_txrx(ODP_PKTIN_MODE_SCHED, 1);
+	test_txrx(ODP_PKTIN_MODE_SCHED, 1, TXRX_MODE_SINGLE);
+	test_txrx(ODP_PKTIN_MODE_SCHED, TX_BATCH_LEN, TXRX_MODE_SINGLE);
 }
 
 void pktio_test_sched_multi(void)
 {
-	test_txrx(ODP_PKTIN_MODE_SCHED, TX_BATCH_LEN);
+	test_txrx(ODP_PKTIN_MODE_SCHED, TX_BATCH_LEN, TXRX_MODE_MULTI);
+	test_txrx(ODP_PKTIN_MODE_SCHED, 1, TXRX_MODE_MULTI);
 }
 
 void pktio_test_recv(void)
 {
-	test_txrx(ODP_PKTIN_MODE_RECV, 1);
+	test_txrx(ODP_PKTIN_MODE_RECV, 1, TXRX_MODE_SINGLE);
 }
 
 void pktio_test_recv_multi(void)
 {
-	test_txrx(ODP_PKTIN_MODE_RECV, TX_BATCH_LEN);
+	test_txrx(ODP_PKTIN_MODE_RECV, TX_BATCH_LEN, TXRX_MODE_MULTI);
 }
 
 void pktio_test_jumbo(void)
@@ -976,12 +997,8 @@  void pktio_test_send_failure(void)
 		info_rx.inq  = ODP_QUEUE_INVALID;
 		info_rx.in_mode = ODP_PKTIN_MODE_RECV;
 
-		for (i = 0; i < ret; ++i) {
-			pkt_tbl[i] = wait_for_packet(&info_rx, pkt_seq[i],
-						     ODP_TIME_SEC_IN_NS);
-			if (pkt_tbl[i] == ODP_PACKET_INVALID)
-				break;
-		}
+		i = wait_for_packets(&info_rx, pkt_tbl, pkt_seq, ret,
+				     TXRX_MODE_MULTI, ODP_TIME_SEC_IN_NS);
 
 		if (i == ret) {
 			/* now try to send starting with the too-long packet
@@ -1012,14 +1029,9 @@  void pktio_test_send_failure(void)
 		ret = odp_pktio_send(pktio_tx, &pkt_tbl[i], TX_BATCH_LEN - i);
 		CU_ASSERT_FATAL(ret == (TX_BATCH_LEN - i));
 
-		for (; i < TX_BATCH_LEN; ++i) {
-			pkt_tbl[i] = wait_for_packet(&info_rx,
-						     pkt_seq[i],
-						     ODP_TIME_SEC_IN_NS);
-			if (pkt_tbl[i] == ODP_PACKET_INVALID)
-				break;
-		}
-		CU_ASSERT(i == TX_BATCH_LEN);
+		i = wait_for_packets(&info_rx, &pkt_tbl[i], &pkt_seq[i], ret,
+				     TXRX_MODE_MULTI, ODP_TIME_SEC_IN_NS);
+		CU_ASSERT(i == ret);
 	} else {
 		CU_FAIL("failed to generate test packets\n");
 	}