[ovs-dev] [PATCH] upcall: avoid handler block in recv_upcalls

wangyunjian wangyunjian at huawei.com
Sat Dec 26 09:51:23 UTC 2020


From: Lvmengfan <lvmengfan at huawei.com>

When upcall_receive or process_upcall returns error in recv_upcalls, the
n_upcalls count would not increased. If this situation continues, the
loop may failed to exit, then the handler block occurs. Add a n_errors
to count the errors and jump out of the loop, cloud avoid block
happening.

Signed-off-by: Lvmengfan <lvmengfan at huawei.com>
---
 ofproto/ofproto-dpif-upcall.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 27924fa..6b32b18 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -776,9 +776,10 @@ recv_upcalls(struct handler *handler)
     struct dpif_upcall dupcalls[UPCALL_MAX_BATCH];
     struct upcall upcalls[UPCALL_MAX_BATCH];
     struct flow flows[UPCALL_MAX_BATCH];
-    size_t n_upcalls, i;
+    size_t n_upcalls, i, n_errors;
 
     n_upcalls = 0;
+    n_errors = 0;
     while (n_upcalls < UPCALL_MAX_BATCH) {
         struct ofpbuf *recv_buf = &recv_bufs[n_upcalls];
         struct dpif_upcall *dupcall = &dupcalls[n_upcalls];
@@ -810,6 +811,7 @@ recv_upcalls(struct handler *handler)
                                dupcall->type, dupcall->userdata, flow, mru,
                                &dupcall->ufid, PMD_ID_NULL);
         if (error) {
+            n_errors++;
             if (error == ENODEV) {
                 /* Received packet on datapath port for which we couldn't
                  * associate an ofproto.  This can happen if a port is removed
@@ -837,6 +839,7 @@ recv_upcalls(struct handler *handler)
         error = process_upcall(udpif, upcall,
                                &upcall->odp_actions, &upcall->wc);
         if (error) {
+            n_errors++;
             goto cleanup;
         }
 
@@ -848,6 +851,13 @@ cleanup:
 free_dupcall:
         dp_packet_uninit(&dupcall->packet);
         ofpbuf_uninit(recv_buf);
+        if (n_errors >= UPCALL_MAX_BATCH * 2) {
+            if (n_upcalls == 0) {
+                return 1;
+            } else {
+                break;
+            }
+        }
     }
 
     if (n_upcalls) {
-- 
1.8.3.1



More information about the dev mailing list