diff mbox

[API-NEXT,v4,8/9] queue: handle return value of odp_queue_enq()

Message ID 1435770379-30000-9-git-send-email-zoltan.kiss@linaro.org
State Accepted
Commit 8235c6f0381a9c12fb4befe782b017ab4f2cebcb
Headers show

Commit Message

Zoltan Kiss July 1, 2015, 5:06 p.m. UTC
Unsent packet has to be released. If the event type is obvious from the
context, use directly the relevant release functions, otherwise
odp_event(free).
Wider error handling is attempted, but this patch can't fix all the flaws
in the many calling functions of odp_queue_enq()

Signed-off-by: Zoltan Kiss <zoltan.kiss@linaro.org>
---

v4: abort when scheduling fails.

 example/classifier/odp_classifier.c                       |  7 ++++++-
 example/generator/odp_generator.c                         |  1 +
 example/ipsec/odp_ipsec.c                                 | 11 ++++++++---
 example/ipsec/odp_ipsec_stream.c                          |  6 +++++-
 example/packet/odp_pktio.c                                |  6 +++++-
 platform/linux-generic/include/odp_schedule_internal.h    |  4 ++--
 platform/linux-generic/odp_crypto.c                       |  5 ++++-
 platform/linux-generic/odp_queue.c                        |  8 ++++----
 platform/linux-generic/odp_schedule.c                     | 13 +++++++++----
 platform/linux-generic/odp_timer.c                        |  4 +++-
 test/performance/odp_l2fwd.c                              |  6 +++++-
 test/performance/odp_pktio_perf.c                         | 10 ++++++++--
 test/performance/odp_scheduling.c                         |  7 +++++++
 test/validation/classification/odp_classification_tests.c |  3 ++-
 test/validation/pktio/pktio.c                             |  1 +
 test/validation/queue/queue.c                             |  9 ++++++---
 test/validation/scheduler/scheduler.c                     | 12 ++++++++----
 17 files changed, 84 insertions(+), 29 deletions(-)
diff mbox

Patch

diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c
index 643e16c..7de11c6 100644
--- a/example/classifier/odp_classifier.c
+++ b/example/classifier/odp_classifier.c
@@ -294,7 +294,12 @@  static void *pktio_receive_thread(void *arg)
 		if (appl->appl_mode == APPL_MODE_DROP)
 			odp_packet_free(pkt);
 		else
-			odp_queue_enq(outq_def, ev);
+			if (odp_queue_enq(outq_def, ev)) {
+				EXAMPLE_ERR("  [%i] Queue enqueue failed.\n",
+					    thr);
+				odp_packet_free(pkt);
+				continue;
+			}
 	}
 
 	return NULL;
diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
index 0ff264c..afbac86 100644
--- a/example/generator/odp_generator.c
+++ b/example/generator/odp_generator.c
@@ -410,6 +410,7 @@  static void *gen_send_thread(void *arg)
 		err = odp_queue_enq(outq_def, odp_packet_to_event(pkt));
 		if (err != 0) {
 			EXAMPLE_ERR("  [%02i] send pkt err!\n", thr);
+			odp_packet_free(pkt);
 			return NULL;
 		}
 
diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c
index 4928985..089015f 100644
--- a/example/ipsec/odp_ipsec.c
+++ b/example/ipsec/odp_ipsec.c
@@ -1157,7 +1157,8 @@  void *pktio_thread(void *arg EXAMPLE_UNUSED)
 					ctx->state = PKT_STATE_TRANSMIT;
 				} else {
 					ctx->state = PKT_STATE_IPSEC_OUT_SEQ;
-					odp_queue_enq(seqnumq, ev);
+					if (odp_queue_enq(seqnumq, ev))
+						rc = PKT_DROP;
 				}
 				break;
 
@@ -1175,8 +1176,12 @@  void *pktio_thread(void *arg EXAMPLE_UNUSED)
 
 			case PKT_STATE_TRANSMIT:
 
-				odp_queue_enq(ctx->outq, ev);
-				rc = PKT_DONE;
+				if (odp_queue_enq(ctx->outq, ev)) {
+					odp_event_free(ev);
+					rc = PKT_DROP;
+				} else {
+					rc = PKT_DONE;
+				}
 				break;
 
 			default:
diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec/odp_ipsec_stream.c
index a140d36..f533c40 100644
--- a/example/ipsec/odp_ipsec_stream.c
+++ b/example/ipsec/odp_ipsec_stream.c
@@ -566,7 +566,11 @@  int create_stream_db_inputs(void)
 				break;
 			}
 			stream->created++;
-			odp_queue_enq(queue, odp_packet_to_event(pkt));
+			if (odp_queue_enq(queue, odp_packet_to_event(pkt))) {
+				odp_packet_free(pkt);
+				printf("Queue enqueue failed\n");
+				break;
+			}
 
 			/* Count this stream when we create first packet */
 			if (1 == stream->created)
diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c
index 0b4a8f1..8004d69 100644
--- a/example/packet/odp_pktio.c
+++ b/example/packet/odp_pktio.c
@@ -233,7 +233,11 @@  static void *pktio_queue_thread(void *arg)
 		swap_pkt_addrs(&pkt, 1);
 
 		/* Enqueue the packet for output */
-		odp_queue_enq(outq_def, ev);
+		if (odp_queue_enq(outq_def, ev)) {
+			EXAMPLE_ERR("  [%i] Queue enqueue failed.\n", thr);
+			odp_packet_free(pkt);
+			continue;
+		}
 
 		/* Print packet counts every once in a while */
 		if (odp_unlikely(pkt_cnt++ % 100000 == 0)) {
diff --git a/platform/linux-generic/include/odp_schedule_internal.h b/platform/linux-generic/include/odp_schedule_internal.h
index 904bfbd..4c6577d 100644
--- a/platform/linux-generic/include/odp_schedule_internal.h
+++ b/platform/linux-generic/include/odp_schedule_internal.h
@@ -23,9 +23,9 @@  extern "C" {
 int schedule_queue_init(queue_entry_t *qe);
 void schedule_queue_destroy(queue_entry_t *qe);
 
-static inline void schedule_queue(const queue_entry_t *qe)
+static inline int schedule_queue(const queue_entry_t *qe)
 {
-	odp_queue_enq(qe->s.pri_queue, qe->s.cmd_ev);
+	return odp_queue_enq(qe->s.pri_queue, qe->s.cmd_ev);
 }
 
 
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
index 515f508..d49e256 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -413,7 +413,10 @@  odp_crypto_operation(odp_crypto_op_params_t *params,
 		op_result = get_op_result_from_event(completion_event);
 		op_result->magic = OP_RESULT_MAGIC;
 		op_result->result = local_result;
-		odp_queue_enq(session->compl_queue, completion_event);
+		if (odp_queue_enq(session->compl_queue, completion_event)) {
+			odp_event_free(completion_event);
+			return -1;
+		}
 
 		/* Indicate to caller operation was async */
 		*posted = 1;
diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c
index 4a0465b..d1c2cfc 100644
--- a/platform/linux-generic/odp_queue.c
+++ b/platform/linux-generic/odp_queue.c
@@ -355,8 +355,8 @@  int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr)
 	UNLOCK(&queue->s.lock);
 
 	/* Add queue to scheduling */
-	if (sched)
-		schedule_queue(queue);
+	if (sched && schedule_queue(queue))
+		ODP_ABORT("schedule_queue failed\n");
 
 	return 0;
 }
@@ -395,8 +395,8 @@  int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)
 	UNLOCK(&queue->s.lock);
 
 	/* Add queue to scheduling */
-	if (sched)
-		schedule_queue(queue);
+	if (sched && schedule_queue(queue))
+		ODP_ABORT("schedule_queue failed\n");
 
 	return num; /* All events enqueued */
 }
diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index 9206d5c..7a61a42 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -355,7 +355,9 @@  int schedule_pktio_start(odp_pktio_t pktio, int prio)
 
 	pri_queue  = pri_set_pktio(pktio, prio);
 
-	odp_queue_enq(pri_queue, odp_buffer_to_event(buf));
+	if (odp_queue_enq(pri_queue, odp_buffer_to_event(buf)))
+		ODP_ABORT("schedule_pktio_start failed\n");
+
 
 	return 0;
 }
@@ -365,7 +367,8 @@  void odp_schedule_release_atomic(void)
 	if (sched_local.pri_queue != ODP_QUEUE_INVALID &&
 	    sched_local.num       == 0) {
 		/* Release current atomic queue */
-		odp_queue_enq(sched_local.pri_queue, sched_local.cmd_ev);
+		if (odp_queue_enq(sched_local.pri_queue, sched_local.cmd_ev))
+			ODP_ABORT("odp_schedule_release_atomic failed\n");
 		sched_local.pri_queue = ODP_QUEUE_INVALID;
 	}
 }
@@ -456,7 +459,8 @@  static int schedule(odp_queue_t *out_queue, odp_event_t out_ev[],
 					odp_buffer_free(buf);
 				} else {
 					/* Continue scheduling the pktio */
-					odp_queue_enq(pri_q, ev);
+					if (odp_queue_enq(pri_q, ev))
+						ODP_ABORT("schedule failed\n");
 				}
 
 				continue;
@@ -487,7 +491,8 @@  static int schedule(odp_queue_t *out_queue, odp_event_t out_ev[],
 				sched_local.cmd_ev    = ev;
 			} else {
 				/* Continue scheduling the queue */
-				odp_queue_enq(pri_q, ev);
+				if (odp_queue_enq(pri_q, ev))
+					ODP_ABORT("schedule failed\n");
 			}
 
 			/* Output the source queue handle */
diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c
index d0c1f30..f3de486 100644
--- a/platform/linux-generic/odp_timer.c
+++ b/platform/linux-generic/odp_timer.c
@@ -578,9 +578,11 @@  static unsigned timer_expire(odp_timer_pool *tp, uint32_t idx, uint64_t tick)
 		/* Post the timeout to the destination queue */
 		int rc = odp_queue_enq(tim->queue,
 				       odp_buffer_to_event(tmo_buf));
-		if (odp_unlikely(rc != 0))
+		if (odp_unlikely(rc != 0)) {
+			odp_buffer_free(tmo_buf);
 			ODP_ABORT("Failed to enqueue timeout buffer (%d)\n",
 				  rc);
+		}
 		return 1;
 	} else {
 		/* Else false positive, ignore */
diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index dd0b4b1..9cc201f 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -152,7 +152,11 @@  static void *pktio_queue_thread(void *arg)
 		outq_def = lookup_dest_q(pkt);
 
 		/* Enqueue the packet for output */
-		odp_queue_enq(outq_def, ev);
+		if (odp_queue_enq(outq_def, ev)) {
+			printf("  [%i] Queue enqueue failed.\n", thr);
+			odp_packet_free(pkt);
+			continue;
+		}
 
 		stats->packets += 1;
 	}
diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c
index 686056e..52bddc4 100644
--- a/test/performance/odp_pktio_perf.c
+++ b/test/performance/odp_pktio_perf.c
@@ -272,8 +272,14 @@  static int send_packets(odp_queue_t outq,
 {
 	if (num_pkts == 0)
 		return 0;
-	else if (num_pkts == 1)
-		return odp_queue_enq(outq, event_tbl[0]) == 0 ? 1 : 0;
+	else if (num_pkts == 1) {
+		if (odp_queue_enq(outq, event_tbl[0])) {
+			odp_event_free(event_tbl[0]);
+			return 0;
+		} else {
+			return 1;
+		}
+	}
 
 	return odp_queue_enq_multi(outq, event_tbl, num_pkts);
 }
diff --git a/test/performance/odp_scheduling.c b/test/performance/odp_scheduling.c
index 558fec8..1283986 100644
--- a/test/performance/odp_scheduling.c
+++ b/test/performance/odp_scheduling.c
@@ -114,6 +114,7 @@  static int create_queue(int thr, odp_pool_t msg_pool, int prio)
 
 	if (odp_queue_enq(queue, odp_buffer_to_event(buf))) {
 		LOG_ERR("  [%i] Queue enqueue failed.\n", thr);
+		odp_buffer_free(buf);
 		return -1;
 	}
 
@@ -161,6 +162,7 @@  static int create_queues(int thr, odp_pool_t msg_pool, int prio)
 
 		if (odp_queue_enq(queue, odp_buffer_to_event(buf))) {
 			LOG_ERR("  [%i] Queue enqueue failed.\n", thr);
+			odp_buffer_free(buf);
 			return -1;
 		}
 	}
@@ -294,6 +296,7 @@  static int test_poll_queue(int thr, odp_pool_t msg_pool)
 
 		if (odp_queue_enq(queue, ev)) {
 			LOG_ERR("  [%i] Queue enqueue failed.\n", thr);
+			odp_buffer_free(buf);
 			return -1;
 		}
 
@@ -352,6 +355,7 @@  static int test_schedule_single(const char *str, int thr,
 
 		if (odp_queue_enq(queue, ev)) {
 			LOG_ERR("  [%i] Queue enqueue failed.\n", thr);
+			odp_event_free(ev);
 			return -1;
 		}
 	}
@@ -371,6 +375,7 @@  static int test_schedule_single(const char *str, int thr,
 
 		if (odp_queue_enq(queue, ev)) {
 			LOG_ERR("  [%i] Queue enqueue failed.\n", thr);
+			odp_event_free(ev);
 			return -1;
 		}
 	}
@@ -431,6 +436,7 @@  static int test_schedule_many(const char *str, int thr,
 
 		if (odp_queue_enq(queue, ev)) {
 			LOG_ERR("  [%i] Queue enqueue failed.\n", thr);
+			odp_event_free(ev);
 			return -1;
 		}
 	}
@@ -450,6 +456,7 @@  static int test_schedule_many(const char *str, int thr,
 
 		if (odp_queue_enq(queue, ev)) {
 			LOG_ERR("  [%i] Queue enqueue failed.\n", thr);
+			odp_event_free(ev);
 			return -1;
 		}
 	}
diff --git a/test/validation/classification/odp_classification_tests.c b/test/validation/classification/odp_classification_tests.c
index 0aa4998..4382aee 100644
--- a/test/validation/classification/odp_classification_tests.c
+++ b/test/validation/classification/odp_classification_tests.c
@@ -109,7 +109,8 @@  void enqueue_loop_interface(odp_packet_t pkt)
 	odp_queue_t defqueue = odp_pktio_outq_getdef(pktio_loop);
 
 	ev = odp_packet_to_event(pkt);
-	CU_ASSERT(odp_queue_enq(defqueue, ev) == 0);
+	if (!(CU_ASSERT(odp_queue_enq(defqueue, ev) == 0)))
+		odp_packet_free(pkt);
 }
 
 static inline
diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
index ab9a305..9d5af22 100644
--- a/test/validation/pktio/pktio.c
+++ b/test/validation/pktio/pktio.c
@@ -382,6 +382,7 @@  static void pktio_txrx_multi(pktio_info_t *pktio_a, pktio_info_t *pktio_b,
 		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;
 		}
 	} else {
diff --git a/test/validation/queue/queue.c b/test/validation/queue/queue.c
index f686b71..5f05e49 100644
--- a/test/validation/queue/queue.c
+++ b/test/validation/queue/queue.c
@@ -72,9 +72,12 @@  static void queue_test_sunnydays(void)
 	CU_ASSERT_FATAL(buf != ODP_BUFFER_INVALID);
 	ev  = odp_buffer_to_event(buf);
 
-	odp_queue_enq(queue_id, ev);
-	CU_ASSERT_EQUAL(ev, odp_queue_deq(queue_id));
-	odp_buffer_free(buf);
+	if (!(CU_ASSERT(odp_queue_enq(queue_id, ev) == 0))) {
+		odp_buffer_free(buf);
+	} else {
+		CU_ASSERT_EQUAL(ev, odp_queue_deq(queue_id));
+		odp_buffer_free(buf);
+	}
 
 	for (i = 0; i < MAX_BUFFER_QUEUE; i++) {
 		odp_buffer_t buf = odp_buffer_alloc(msg_pool);
diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c
index d7f2ac3..7f1b81a 100644
--- a/test/validation/scheduler/scheduler.c
+++ b/test/validation/scheduler/scheduler.c
@@ -139,7 +139,8 @@  static void scheduler_test_queue_destroy(void)
 		u32[0] = MAGIC;
 
 		ev = odp_buffer_to_event(buf);
-		CU_ASSERT(odp_queue_enq(queue, ev) == 0);
+		if (!(CU_ASSERT(odp_queue_enq(queue, ev) == 0)))
+			odp_buffer_free(buf);
 
 		ev = odp_schedule(&from, ODP_SCHED_WAIT);
 
@@ -289,8 +290,10 @@  static void fill_queues(thread_args_t *args)
 				buf = odp_buffer_alloc(pool);
 				CU_ASSERT_FATAL(buf != ODP_BUFFER_INVALID);
 				ev = odp_buffer_to_event(buf);
-				CU_ASSERT(odp_queue_enq(queue, ev) == 0);
-				buf_count++;
+				if (!(CU_ASSERT(odp_queue_enq(queue, ev) == 0)))
+					odp_buffer_free(buf);
+				else
+					buf_count++;
 			}
 		}
 	}
@@ -572,7 +575,8 @@  static void scheduler_test_pause_resume(void)
 		buf = odp_buffer_alloc(pool);
 		CU_ASSERT_FATAL(buf != ODP_BUFFER_INVALID);
 		ev = odp_buffer_to_event(buf);
-		odp_queue_enq(queue, ev);
+		if (odp_queue_enq(queue, ev))
+			odp_buffer_free(buf);
 	}
 
 	for (i = 0; i < NUM_BUFS_BEFORE_PAUSE; i++) {