[v1,3/3] linux-gen: queue: enqueue may fail

Message ID 1519920009-23406-4-git-send-email-odpbot@yandex.ru
State Superseded
Headers show
Series
  • [v1,1/3] linux-gen: sched: optimize packet input polling
Related show

Commit Message

Github ODP bot March 1, 2018, 4 p.m.
From: Petri Savolainen <petri.savolainen@linaro.org>


Drop events when queue enqueue fails. Enqueue failure is more
likely now when queue has limited size.

Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>

---
/** Email created from pull request 504 (psavol:master-sched-optim-2)
 ** https://github.com/Linaro/odp/pull/504
 ** Patch: https://github.com/Linaro/odp/pull/504.patch
 ** Base sha: 284f52d72ec19df3774c7409780f1f9eea33b8e6
 ** Merge commit sha: 081cdd2f01d5a4e5b5b4d254f689e55d60a489cd
 **/
 platform/linux-generic/odp_packet_io.c       | 41 ++++++++++++++++++++++++----
 platform/linux-generic/odp_schedule_basic.c  | 13 +++++++--
 platform/linux-generic/odp_schedule_iquery.c | 12 ++++++--
 3 files changed, 57 insertions(+), 9 deletions(-)

Patch

diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index 73d43b009..17d48bfdb 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -638,8 +638,20 @@  static odp_buffer_hdr_t *pktin_dequeue(queue_t q_int)
 	if (pkts <= 0)
 		return NULL;
 
-	if (pkts > 1)
-		queue_fn->enq_multi(q_int, &hdr_tbl[1], pkts - 1);
+	if (pkts > 1) {
+		int num_enq;
+		int num = pkts - 1;
+
+		num_enq = queue_fn->enq_multi(q_int, &hdr_tbl[1], num);
+
+		if (odp_unlikely(num_enq < num)) {
+			if (odp_unlikely(num_enq < 0))
+				num_enq = 0;
+
+			buffer_free_multi(&hdr_tbl[num_enq + 1], num - num_enq);
+		}
+	}
+
 	buf_hdr = hdr_tbl[0];
 	return buf_hdr;
 }
@@ -676,8 +688,19 @@  static int pktin_deq_multi(queue_t q_int, odp_buffer_hdr_t *buf_hdr[], int num)
 	for (j = 0; i < pkts; i++, j++)
 		hdr_tbl[j] = hdr_tbl[i];
 
-	if (j)
-		queue_fn->enq_multi(q_int, hdr_tbl, j);
+	if (j) {
+		int num_enq;
+
+		num_enq = queue_fn->enq_multi(q_int, hdr_tbl, j);
+
+		if (odp_unlikely(num_enq < j)) {
+			if (odp_unlikely(num_enq < 0))
+				num_enq = 0;
+
+			buffer_free_multi(&buf_hdr[num_enq], j - num_enq);
+		}
+	}
+
 	return nbr;
 }
 
@@ -763,6 +786,7 @@  int sched_cb_pktin_poll_old(int pktio_index, int num_queue, int index[])
 
 	for (idx = 0; idx < num_queue; idx++) {
 		queue_t q_int;
+		int num_enq;
 
 		num = pktin_recv_buf(entry, index[idx], hdr_tbl,
 				     QUEUE_MULTI_MAX);
@@ -776,7 +800,14 @@  int sched_cb_pktin_poll_old(int pktio_index, int num_queue, int index[])
 		}
 
 		q_int = entry->s.in_queue[index[idx]].queue_int;
-		queue_fn->enq_multi(q_int, hdr_tbl, num);
+		num_enq = queue_fn->enq_multi(q_int, hdr_tbl, num);
+
+		if (odp_unlikely(num_enq < num)) {
+			if (odp_unlikely(num_enq < 0))
+				num_enq = 0;
+
+			buffer_free_multi(&hdr_tbl[num_enq], num - num_enq);
+		}
 	}
 
 	return 0;
diff --git a/platform/linux-generic/odp_schedule_basic.c b/platform/linux-generic/odp_schedule_basic.c
index 1975e3a4b..dc964f387 100644
--- a/platform/linux-generic/odp_schedule_basic.c
+++ b/platform/linux-generic/odp_schedule_basic.c
@@ -581,13 +581,22 @@  static inline void ordered_stash_release(void)
 	for (i = 0; i < sched_local.ordered.stash_num; i++) {
 		queue_entry_t *queue_entry;
 		odp_buffer_hdr_t **buf_hdr;
-		int num;
+		int num, num_enq;
 
 		queue_entry = sched_local.ordered.stash[i].queue_entry;
 		buf_hdr = sched_local.ordered.stash[i].buf_hdr;
 		num = sched_local.ordered.stash[i].num;
 
-		queue_fn->enq_multi(qentry_to_int(queue_entry), buf_hdr, num);
+		num_enq = queue_fn->enq_multi(qentry_to_int(queue_entry),
+					      buf_hdr, num);
+
+		/* Drop packets that were not enqueued */
+		if (odp_unlikely(num_enq < num)) {
+			if (odp_unlikely(num_enq < 0))
+				num_enq = 0;
+
+			buffer_free_multi(&buf_hdr[num_enq], num - num_enq);
+		}
 	}
 	sched_local.ordered.stash_num = 0;
 }
diff --git a/platform/linux-generic/odp_schedule_iquery.c b/platform/linux-generic/odp_schedule_iquery.c
index ddd97bea7..ab99ce789 100644
--- a/platform/linux-generic/odp_schedule_iquery.c
+++ b/platform/linux-generic/odp_schedule_iquery.c
@@ -1136,13 +1136,21 @@  static inline void ordered_stash_release(void)
 	for (i = 0; i < thread_local.ordered.stash_num; i++) {
 		queue_entry_t *queue_entry;
 		odp_buffer_hdr_t **buf_hdr;
-		int num;
+		int num, num_enq;
 
 		queue_entry = thread_local.ordered.stash[i].queue_entry;
 		buf_hdr = thread_local.ordered.stash[i].buf_hdr;
 		num = thread_local.ordered.stash[i].num;
 
-		queue_fn->enq_multi(qentry_to_int(queue_entry), buf_hdr, num);
+		num_enq = queue_fn->enq_multi(qentry_to_int(queue_entry),
+					      buf_hdr, num);
+
+		if (odp_unlikely(num_enq < num)) {
+			if (odp_unlikely(num_enq < 0))
+				num_enq = 0;
+
+			buffer_free_multi(&buf_hdr[num_enq], num - num_enq);
+		}
 	}
 	thread_local.ordered.stash_num = 0;
 }