diff mbox series

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

Message ID 1608976283-8044-1-git-send-email-wangyunjian@huawei.com
State Changes Requested
Headers show
Series [ovs-dev] upcall: avoid handler block in recv_upcalls | expand

Commit Message

wangyunjian Dec. 26, 2020, 9:51 a.m. UTC
From: Lvmengfan <lvmengfan@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@huawei.com>
---
 ofproto/ofproto-dpif-upcall.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Comments

Eli Britstein March 2, 2021, 10:37 a.m. UTC | #1
On 12/26/2020 11:51 AM, wangyunjian wrote:
> From: Lvmengfan <lvmengfan@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
typo
> happening.
Fixes: cc377352d164 ("ofproto: Reorganize in preparation for direct dpdk 
upcalls.")
> Signed-off-by: Lvmengfan <lvmengfan@huawei.com>
Could you please add a unit-test for this?
> ---
>   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) {

Maybe simpler instead of the below free_dupcall hunk, to do like:

while (n_upcalls + n_errors < UPCALL_MAX_BATCH) {

The downside is that in case of errors we will not fill the entire 
UPCALL_MAX_BATCH, but simpler.

>           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) {
Why UPCALL_MAX_BATCH * 2 ? Please add a comment to explain, also the below.
> +            if (n_upcalls == 0) {
> +                return 1;
> +            } else {
> +                break;
> +            }
> +        }
>       }
>   
>       if (n_upcalls) {
diff mbox series

Patch

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) {