#include <stdbool.h>
#include <inttypes.h>
+#include "connmgr.h"
#include "coverage.h"
#include "dynamic-string.h"
#include "dpif.h"
#include "ofpbuf.h"
#include "ofproto-dpif-ipfix.h"
#include "ofproto-dpif-sflow.h"
-#include "ofproto-dpif.h"
#include "packets.h"
#include "poll-loop.h"
#include "vlog.h"
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'. */
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_upcall_handler,
{
struct handler *handler = arg;
- set_subprogram_name("upcall_handler");
+ set_subprogram_name("upcall_%u", ovsthread_id_self());
for (;;) {
struct list misses = LIST_INITIALIZER(&misses);
size_t i;
ovs_mutex_unlock(&handler->mutex);
handle_upcalls(handler->udpif, &misses);
+
+ coverage_clear();
}
}
\f
static void
recv_upcalls(struct udpif *udpif)
{
- size_t n_udpif_new_upcalls = 0;
int n;
for (;;) {
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);
for (n = 0; n < udpif->n_handlers; ++n) {
struct handler *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) {
- seq_change(udpif->wait_seq);
- }
}
static struct flow_miss *
* all the packets in each miss. */
fail_open = false;
HMAP_FOR_EACH (miss, hmap_node, &fmb->misses) {
- struct flow_wildcards wc;
- struct rule_dpif *rule;
struct xlate_in xin;
- flow_wildcards_init_catchall(&wc);
- rule_dpif_lookup(miss->ofproto, &miss->flow, &wc, &rule);
- if (rule_dpif_fail_open(rule)) {
- fail_open = true;
- }
- rule_dpif_credit_stats(rule, &miss->stats);
- xlate_in_init(&xin, miss->ofproto, &miss->flow, rule,
+ xlate_in_init(&xin, miss->ofproto, &miss->flow, NULL,
miss->stats.tcp_flags, NULL);
xin.may_learn = true;
xin.resubmit_stats = &miss->stats;
xlate_actions(&xin, &miss->xout);
- flow_wildcards_or(&miss->xout.wc, &miss->xout.wc, &wc);
- rule_dpif_unref(rule);
+ fail_open = fail_open || miss->xout.fail_open;
}
/* Now handle the packets individually in order of arrival. In the common
struct ofpbuf *packet = upcall->dpif_upcall.packet;
if (miss->xout.slow) {
- struct rule_dpif *rule;
struct xlate_in xin;
- rule_dpif_lookup(miss->ofproto, &miss->flow, NULL, &rule);
- xlate_in_init(&xin, miss->ofproto, &miss->flow, rule, 0, packet);
+ xlate_in_init(&xin, miss->ofproto, &miss->flow, NULL, 0, packet);
xlate_actions_for_side_effects(&xin);
- rule_dpif_unref(rule);
}
if (miss->xout.odp_actions.size) {
op->u.execute.packet = packet;
op->u.execute.actions = miss->xout.odp_actions.data;
op->u.execute.actions_len = miss->xout.odp_actions.size;
+ op->u.execute.needs_help = (miss->xout.slow & SLOW_ACTION) != 0;
}
}
LIST_FOR_EACH (upcall, list_node, upcalls) {
struct flow_miss *miss = upcall->flow_miss;
struct ofpbuf *packet = upcall->dpif_upcall.packet;
- struct ofputil_packet_in *pin;
+ struct ofproto_packet_in *pin;
pin = xmalloc(sizeof *pin);
- pin->packet = xmemdup(packet->data, packet->size);
- pin->packet_len = packet->size;
- pin->reason = OFPR_NO_MATCH;
- pin->controller_id = 0;
- pin->table_id = 0;
- pin->cookie = 0;
+ pin->up.packet = xmemdup(packet->data, packet->size);
+ pin->up.packet_len = packet->size;
+ pin->up.reason = OFPR_NO_MATCH;
+ pin->up.table_id = 0;
+ pin->up.cookie = OVS_BE64_MAX;
+ flow_get_metadata(&miss->flow, &pin->up.fmd);
pin->send_len = 0; /* Not used for flow table misses. */
- flow_get_metadata(&miss->flow, &pin->fmd);
+ pin->generated_by_table_miss = false;
ofproto_dpif_send_packet_in(miss->ofproto, pin);
}
}