struct handler {
struct udpif *udpif; /* Parent udpif. */
pthread_t thread; /* Thread ID. */
- char *name; /* Thread name. */
uint32_t handler_id; /* Handler id. */
};
* 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. */
};
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;
};
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 *);
/* 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);
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,
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);
}
}
}
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);
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();
}
\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);
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];
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;
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. */
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;
* flow this time. */
ovs_mutex_unlock(&ukey->mutex);
COVERAGE_INC(upcall_duplicate_flow);
- continue;
+ goto next;
}
used = ukey->created;
* another revalidator is processing this flow
* concurrently, so don't bother processing it. */
ukey_delete(NULL, ukey);
- continue;
+ goto next;
}
}
dump_op_init(&ops[n_ops++], key, key_len, ukey);
}
+ next:
may_destroy = dpif_flow_dump_next_may_destroy_keys(&udpif->dump,
state);
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);
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);
}
}