ofproto-dpif-upcall: Use atomic_long in struct udpif
[cascardo/ovs.git] / ofproto / ofproto-dpif-upcall.c
index 717563a..193f4cd 100644 (file)
@@ -52,7 +52,6 @@ COVERAGE_DEFINE(upcall_duplicate_flow);
 struct handler {
     struct udpif *udpif;               /* Parent udpif. */
     pthread_t thread;                  /* Thread ID. */
-    char *name;                        /* Thread name. */
     uint32_t handler_id;               /* Handler id. */
 };
 
@@ -60,9 +59,8 @@ struct handler {
  * updates or removes them if necessary. */
 struct revalidator {
     struct udpif *udpif;               /* Parent udpif. */
-    char *name;                        /* Thread name. */
-
     pthread_t thread;                  /* Thread ID. */
+    unsigned int id;                   /* ovsthread_id_self(). */
     struct hmap *ukeys;                /* Points into udpif->ukeys for this
                                           revalidator. Used for GC phase. */
 };
@@ -127,7 +125,7 @@ struct udpif {
     atomic_uint flow_limit;            /* Datapath flow hard limit. */
 
     /* n_flows_mutex prevents multiple threads updating these concurrently. */
-    atomic_uint64_t n_flows;           /* Number of flows in the datapath. */
+    atomic_ulong n_flows;           /* Number of flows in the datapath. */
     atomic_llong n_flows_timestamp;    /* Last time n_flows was updated. */
     struct ovs_mutex n_flows_mutex;
 };
@@ -219,7 +217,7 @@ static void udpif_start_threads(struct udpif *, size_t n_handlers,
                                 size_t n_revalidators);
 static void *udpif_upcall_handler(void *);
 static void *udpif_revalidator(void *);
-static uint64_t udpif_get_n_flows(struct udpif *);
+static unsigned long udpif_get_n_flows(struct udpif *);
 static void revalidate(struct revalidator *);
 static void revalidator_sweep(struct revalidator *);
 static void revalidator_purge(struct revalidator *);
@@ -310,15 +308,11 @@ udpif_stop_threads(struct udpif *udpif)
             /* Delete ukeys, and delete all flows from the datapath to prevent
              * double-counting stats. */
             revalidator_purge(revalidator);
-            free(revalidator->name);
 
             hmap_destroy(&udpif->ukeys[i].hmap);
             ovs_mutex_destroy(&udpif->ukeys[i].mutex);
         }
 
-        for (i = 0; i < udpif->n_handlers; i++) {
-            free(udpif->handlers[i].name);
-        }
         latch_poll(&udpif->exit_latch);
 
         xpthread_barrier_destroy(&udpif->reval_barrier);
@@ -354,8 +348,8 @@ udpif_start_threads(struct udpif *udpif, size_t n_handlers,
 
             handler->udpif = udpif;
             handler->handler_id = i;
-            xpthread_create(&handler->thread, NULL, udpif_upcall_handler,
-                            handler);
+            handler->thread = ovs_thread_create(
+                "handler", udpif_upcall_handler, handler);
         }
 
         xpthread_barrier_init(&udpif->reval_barrier, NULL,
@@ -371,8 +365,8 @@ udpif_start_threads(struct udpif *udpif, size_t n_handlers,
             hmap_init(&udpif->ukeys[i].hmap);
             ovs_mutex_init(&udpif->ukeys[i].mutex);
             revalidator->ukeys = &udpif->ukeys[i].hmap;
-            xpthread_create(&revalidator->thread, NULL, udpif_revalidator,
-                            revalidator);
+            revalidator->thread = ovs_thread_create(
+                "revalidator", udpif_revalidator, revalidator);
         }
     }
 }
@@ -385,8 +379,6 @@ void
 udpif_set_threads(struct udpif *udpif, size_t n_handlers,
                   size_t n_revalidators)
 {
-    int error;
-
     ovs_assert(udpif);
     ovs_assert(n_handlers && n_revalidators);
 
@@ -396,14 +388,16 @@ udpif_set_threads(struct udpif *udpif, size_t n_handlers,
         udpif_stop_threads(udpif);
     }
 
-    error = dpif_handlers_set(udpif->dpif, n_handlers);
-    if (error) {
-        VLOG_ERR("failed to configure handlers in dpif %s: %s",
-                 dpif_name(udpif->dpif), ovs_strerror(error));
-        return;
-    }
-
     if (!udpif->handlers && !udpif->revalidators) {
+        int error;
+
+        error = dpif_handlers_set(udpif->dpif, n_handlers);
+        if (error) {
+            VLOG_ERR("failed to configure handlers in dpif %s: %s",
+                     dpif_name(udpif->dpif), ovs_strerror(error));
+            return;
+        }
+
         udpif_start_threads(udpif, n_handlers, n_revalidators);
     }
     ovsrcu_quiesce_end();
@@ -490,11 +484,11 @@ udpif_flush_all_datapaths(void)
 }
 
 \f
-static uint64_t
+static unsigned long
 udpif_get_n_flows(struct udpif *udpif)
 {
     long long int time, now;
-    uint64_t flow_count;
+    unsigned long flow_count;
 
     now = time_msec();
     atomic_read(&udpif->n_flows_timestamp, &time);
@@ -522,9 +516,6 @@ udpif_upcall_handler(void *arg)
     struct udpif *udpif = handler->udpif;
     struct hmap misses = HMAP_INITIALIZER(&misses);
 
-    handler->name = xasprintf("handler_%u", ovsthread_id_self());
-    set_subprogram_name("%s", handler->name);
-
     while (!latch_is_set(&handler->udpif->exit_latch)) {
         struct upcall upcalls[FLOW_MISS_MAX_BATCH];
         struct flow_miss miss_buf[FLOW_MISS_MAX_BATCH];
@@ -569,8 +560,7 @@ udpif_revalidator(void *arg)
     unsigned int flow_limit = 0;
     size_t n_flows = 0;
 
-    revalidator->name = xasprintf("revalidator_%u", ovsthread_id_self());
-    set_subprogram_name("%s", revalidator->name);
+    revalidator->id = ovsthread_id_self();
     for (;;) {
         if (leader) {
             uint64_t reval_seq;
@@ -1245,7 +1235,6 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
     push.n_bytes = stats->n_bytes > ukey->stats.n_bytes
         ? stats->n_bytes - ukey->stats.n_bytes
         : 0;
-    ukey->stats = *stats;
 
     if (!ukey->flow_exists) {
         /* Don't bother revalidating if the flow was already deleted. */
@@ -1258,6 +1247,8 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
         goto exit;
     }
 
+    /* We will push the stats, so update the ukey stats cache. */
+    ukey->stats = *stats;
     if (!push.n_packets && !udpif->need_revalidate) {
         ok = true;
         goto exit;
@@ -1479,7 +1470,7 @@ revalidate(struct revalidator *revalidator)
                  * flow this time. */
                 ovs_mutex_unlock(&ukey->mutex);
                 COVERAGE_INC(upcall_duplicate_flow);
-                continue;
+                goto next;
             }
 
             used = ukey->created;
@@ -1502,7 +1493,7 @@ revalidate(struct revalidator *revalidator)
                      * another revalidator is processing this flow
                      * concurrently, so don't bother processing it. */
                     ukey_delete(NULL, ukey);
-                    continue;
+                    goto next;
                 }
             }
 
@@ -1520,6 +1511,7 @@ revalidate(struct revalidator *revalidator)
             dump_op_init(&ops[n_ops++], key, key_len, ukey);
         }
 
+    next:
         may_destroy = dpif_flow_dump_next_may_destroy_keys(&udpif->dump,
                                                            state);
 
@@ -1608,7 +1600,7 @@ upcall_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
         atomic_read(&udpif->flow_limit, &flow_limit);
 
         ds_put_format(&ds, "%s:\n", dpif_name(udpif->dpif));
-        ds_put_format(&ds, "\tflows         : (current %"PRIu64")"
+        ds_put_format(&ds, "\tflows         : (current %lu)"
             " (avg %u) (max %u) (limit %u)\n", udpif_get_n_flows(udpif),
             udpif->avg_n_flows, udpif->max_n_flows, flow_limit);
         ds_put_format(&ds, "\tdump duration : %lldms\n", udpif->dump_duration);
@@ -1618,8 +1610,8 @@ upcall_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
             struct revalidator *revalidator = &udpif->revalidators[i];
 
             ovs_mutex_lock(&udpif->ukeys[i].mutex);
-            ds_put_format(&ds, "\t%s: (keys %"PRIuSIZE")\n", revalidator->name,
-                          hmap_count(&udpif->ukeys[i].hmap));
+            ds_put_format(&ds, "\t%u: (keys %"PRIuSIZE")\n",
+                          revalidator->id, hmap_count(&udpif->ukeys[i].hmap));
             ovs_mutex_unlock(&udpif->ukeys[i].mutex);
         }
     }