[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT/LWIP PATCH] uknetdev: Yield receive thread on full stack queue



When a too high rate of network traffic is received, the netdev's receive
thread may never yield and only forwards packets to the lwip stack
thread. This works as expected until the input queue runs full. If the
the stack is never able to process them, the stack becomes completely
unresponsive. Instead of dropping just a few packets all successive
packets are dropped.

This commit introduces a thread yield when this condition is met and
gives the chance to process queued packets.

Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
---
 uknetdev.c | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/uknetdev.c b/uknetdev.c
index 47d2fb1..7047352 100644
--- a/uknetdev.c
+++ b/uknetdev.c
@@ -193,6 +193,7 @@ static void uknetdev_input(struct uk_netdev *dev,
        struct netif *nf = (struct netif *) argp;
        struct uk_netbuf *nb;
        struct pbuf *p;
+       err_t err;
        int ret;
 
        UK_ASSERT(dev);
@@ -243,12 +244,32 @@ static void uknetdev_input(struct uk_netdev *dev,
                p = lwip_netbuf_to_pbuf(nb);
                p->payload = nb->data;
                p->tot_len = p->len = nb->len;
-               if (unlikely(nf->input(p, nf) != ERR_OK)) {
+               err = nf->input(p, nf);
+               if (unlikely(err != ERR_OK)) {
+#if CONFIG_LWIP_THREADS && CONFIG_LIBUKNETDEV_DISPATCHERTHREADS
+                       /* At this point it is possible that lwIP's input queue
+                        * is full or we run out of memory. In this case, we
+                        * return to the scheduler and hope that lwIP's main
+                        * thread is able to process some packets.
+                        * Afterwards, we try it once again.
+                        */
+                       if (err == ERR_MEM) {
+                               LWIP_DEBUGF(NETIF_DEBUG,
+                                           ("%s: %c%c%u: lwIP's input queue 
full: yielding and trying once again...\n",
+                                            __func__, nf->name[0], nf->name[1],
+                                            nf->num));
+                               uk_sched_yield();
+                               err = nf->input(p, nf);
+                               if (likely(err == ERR_OK))
+                                       continue;
+                       }
+#endif
+
                        /*
                         * Drop the packet that we could not send to the stack
                         */
-                       uk_pr_err("%c%c%u: Failed to forward packet to lwIP\n",
-                                 nf->name[0], nf->name[1], nf->num);
+                       uk_pr_err("%c%c%u: Failed to forward packet to lwIP: 
%d\n",
+                                 nf->name[0], nf->name[1], nf->num, err);
                        uk_netbuf_free_single(nb);
                }
        } while (uk_netdev_status_more(ret));
-- 
2.20.1


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.