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: 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(-)

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

Reply via email to