if a queue length is long (ie. non-0), the consumer thread should
already be busy working on the queue.  there's no need to wake it
up repeatedly.

Signed-off-by: YAMAMOTO Takashi <y...@mwd.biglobe.ne.jp>
---
 ofproto/ofproto-dpif-upcall.c | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 180b87e..afaf79a 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -57,7 +57,7 @@ struct handler {
     struct list upcalls OVS_GUARDED;
     size_t n_upcalls OVS_GUARDED;
 
-    size_t n_new_upcalls;              /* Only changed by the dispatcher. */
+    bool need_signal;                  /* Only changed by the dispatcher. */
 
     pthread_cond_t wake_cond;          /* Wakes 'thread' while holding
                                           'mutex'. */
@@ -208,6 +208,7 @@ udpif_recv_set(struct udpif *udpif, size_t n_handlers, bool 
enable)
 
             handler->udpif = udpif;
             list_init(&handler->upcalls);
+            handler->need_signal = false;
             xpthread_cond_init(&handler->wake_cond, NULL);
             ovs_mutex_init(&handler->mutex);
             xpthread_create(&handler->thread, NULL, udpif_miss_handler, 
handler);
@@ -484,7 +485,9 @@ static void
 recv_upcalls(struct udpif *udpif)
 {
     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(60, 60);
-    size_t n_udpif_new_upcalls = 0;
+    bool udpif_need_signal = false;  /* true if the consumer might went sleep
+                                        without processing requests we put on
+                                        the queue */
     struct handler *handler;
     int n;
 
@@ -533,9 +536,13 @@ recv_upcalls(struct udpif *udpif)
             ovs_mutex_lock(&handler->mutex);
             if (handler->n_upcalls < MAX_QUEUE_LENGTH) {
                 list_push_back(&handler->upcalls, &upcall->list_node);
-                handler->n_new_upcalls = ++handler->n_upcalls;
-
-                if (handler->n_new_upcalls >= FLOW_MISS_MAX_BATCH) {
+                if (handler->n_upcalls == 0) {
+                    handler->need_signal = true;
+                }
+                handler->n_upcalls++;
+                if (handler->need_signal &&
+                    handler->n_upcalls >= FLOW_MISS_MAX_BATCH) {
+                    handler->need_signal = false;
                     xpthread_cond_signal(&handler->wake_cond);
                 }
                 ovs_mutex_unlock(&handler->mutex);
@@ -559,8 +566,10 @@ recv_upcalls(struct udpif *udpif)
             len = guarded_list_push_back(&udpif->upcalls, &upcall->list_node,
                                          MAX_QUEUE_LENGTH);
             if (len > 0) {
-                n_udpif_new_upcalls = len;
-                if (n_udpif_new_upcalls >= FLOW_MISS_MAX_BATCH) {
+                if (len == 1) {
+                    udpif_need_signal = true;
+                }
+                if (udpif_need_signal && len >= FLOW_MISS_MAX_BATCH) {
                     seq_change(udpif->wait_seq);
                 }
             } else {
@@ -571,14 +580,14 @@ recv_upcalls(struct udpif *udpif)
     }
     for (n = 0; n < udpif->n_handlers; ++n) {
         handler = &udpif->handlers[n];
-        if (handler->n_new_upcalls) {
-            handler->n_new_upcalls = 0;
+        if (handler->need_signal) {
+            handler->need_signal = false;
             ovs_mutex_lock(&handler->mutex);
             xpthread_cond_signal(&handler->wake_cond);
             ovs_mutex_unlock(&handler->mutex);
         }
     }
-    if (n_udpif_new_upcalls) {
+    if (udpif_need_signal) {
         seq_change(udpif->wait_seq);
     }
 }
-- 
1.8.3.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to