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

Message ID 1520002815-30682-4-git-send-email-odpbot@yandex.ru
State New
Headers show
Series
  • Scheduler packet input integration optimization
Related show

Commit Message

Github ODP bot March 2, 2018, 3 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: e1c0e4570a45d05dd9f2e8e052ce71164209d112
 ** Merge commit sha: 964132736e0785222be184065d6ac73121cd46ac
 **/
 platform/linux-generic/odp_packet_io.c       | 47 +++++++++++++++++++++++++---
 platform/linux-generic/odp_schedule_basic.c  | 14 +++++++--
 platform/linux-generic/odp_schedule_iquery.c | 13 ++++++--
 3 files changed, 65 insertions(+), 9 deletions(-)

Patch

diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index e76ff8140..f67181576 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -638,8 +638,22 @@  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;
+
+			ODP_DBG("Interface %s dropped %i packets\n",
+				entry->s.name, num - num_enq);
+			buffer_free_multi(&hdr_tbl[num_enq + 1], num - num_enq);
+		}
+	}
+
 	buf_hdr = hdr_tbl[0];
 	return buf_hdr;
 }
@@ -676,8 +690,21 @@  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;
+
+			ODP_DBG("Interface %s dropped %i packets\n",
+				entry->s.name, j - num_enq);
+			buffer_free_multi(&buf_hdr[num_enq], j - num_enq);
+		}
+	}
+
 	return nbr;
 }
 
@@ -763,6 +790,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 +804,16 @@  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;
+
+			ODP_DBG("Interface %s dropped %i packets\n",
+				entry->s.name, num - num_enq);
+			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 b251bdeef..3ea261fae 100644
--- a/platform/linux-generic/odp_schedule_basic.c
+++ b/platform/linux-generic/odp_schedule_basic.c
@@ -581,13 +581,23 @@  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;
+
+			ODP_DBG("Dropped %i packets\n", num - num_enq);
+			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..40f2e9fca 100644
--- a/platform/linux-generic/odp_schedule_iquery.c
+++ b/platform/linux-generic/odp_schedule_iquery.c
@@ -1136,13 +1136,22 @@  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;
+
+			ODP_DBG("Dropped %i packets\n", num - num_enq);
+			buffer_free_multi(&buf_hdr[num_enq], num - num_enq);
+		}
 	}
 	thread_local.ordered.stash_num = 0;
 }