From: Petri Savolainen <petri.savolai...@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.savolai...@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(-)

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

Reply via email to