list_init(&udpif->upcalls);
list_init(&udpif->fmbs);
atomic_init(&udpif->reval_seq, 0);
- ovs_mutex_init(&udpif->drop_key_mutex, PTHREAD_MUTEX_NORMAL);
- ovs_mutex_init(&udpif->upcall_mutex, PTHREAD_MUTEX_NORMAL);
- ovs_mutex_init(&udpif->fmb_mutex, PTHREAD_MUTEX_NORMAL);
+ ovs_mutex_init(&udpif->drop_key_mutex);
+ ovs_mutex_init(&udpif->upcall_mutex);
+ ovs_mutex_init(&udpif->fmb_mutex);
return udpif;
}
handler->udpif = udpif;
list_init(&handler->upcalls);
xpthread_cond_init(&handler->wake_cond, NULL);
- ovs_mutex_init(&handler->mutex, PTHREAD_MUTEX_NORMAL);
+ ovs_mutex_init(&handler->mutex);
xpthread_create(&handler->thread, NULL, udpif_miss_handler, handler);
}
xpthread_create(&udpif->dispatcher, NULL, udpif_dispatcher, udpif);
}
}
}
- hash = mhash_finish(hash, n_bytes);
-
- handler = &udpif->handlers[hash % udpif->n_handlers];
-
- ovs_mutex_lock(&handler->mutex);
- if (handler->n_upcalls < MAX_QUEUE_LENGTH) {
- list_push_back(&handler->upcalls, &upcall->list_node);
- handler->n_upcalls++;
- xpthread_cond_signal(&handler->wake_cond);
- ovs_mutex_unlock(&handler->mutex);
- if (!VLOG_DROP_DBG(&rl)) {
- struct ds ds = DS_EMPTY_INITIALIZER;
-
- odp_flow_key_format(upcall->dpif_upcall.key,
- upcall->dpif_upcall.key_len,
- &ds);
- VLOG_DBG("dispatcher: miss enqueue (%s)", ds_cstr(&ds));
- ds_destroy(&ds);
- }
- } else {
- ovs_mutex_unlock(&handler->mutex);
- COVERAGE_INC(miss_queue_overflow);
- upcall_destroy(upcall);
- }
+ hash = mhash_finish(hash, n_bytes);
+
+ handler = &udpif->handlers[hash % udpif->n_handlers];
+
+ ovs_mutex_lock(&handler->mutex);
+ if (handler->n_upcalls < MAX_QUEUE_LENGTH) {
+ list_push_back(&handler->upcalls, &upcall->list_node);
+ handler->n_upcalls++;
+ xpthread_cond_signal(&handler->wake_cond);
+ ovs_mutex_unlock(&handler->mutex);
+ if (!VLOG_DROP_DBG(&rl)) {
+ struct ds ds = DS_EMPTY_INITIALIZER;
+
+ odp_flow_key_format(upcall->dpif_upcall.key,
+ upcall->dpif_upcall.key_len,
+ &ds);
+ VLOG_DBG("dispatcher: miss enqueue (%s)", ds_cstr(&ds));
+ ds_destroy(&ds);
+ }
+ } else {
+ ovs_mutex_unlock(&handler->mutex);
+ COVERAGE_INC(miss_queue_overflow);
+ upcall_destroy(upcall);
+ }
} else {
ovs_mutex_lock(&udpif->upcall_mutex);
if (udpif->n_upcalls < MAX_QUEUE_LENGTH) {
flow_wildcards_or(&miss->xout.wc, &miss->xout.wc, &wc);
if (rule->up.cr.priority == FAIL_OPEN_PRIORITY) {
- struct ofputil_packet_in pin;
-
- /* Extra-special case for fail-open mode.
- *
- * We are in fail-open mode and the packet matched the fail-open
- * rule, but we are connected to a controller too. We should send
- * the packet up to the controller in the hope that it will try to
- * set up a flow and thereby allow us to exit fail-open.
- *
- * See the top-level comment in fail-open.c for more information. */
- pin.packet = packet->data;
- pin.packet_len = packet->size;
- pin.reason = OFPR_NO_MATCH;
- pin.controller_id = 0;
- pin.table_id = 0;
- pin.cookie = 0;
- pin.send_len = 0; /* Not used for flow table misses. */
- flow_get_metadata(&miss->flow, &pin.fmd);
- ofproto_dpif_send_packet_in(ofproto, &pin);
+ LIST_FOR_EACH (packet, list_node, &miss->packets) {
+ struct ofputil_packet_in *pin;
+
+ /* Extra-special case for fail-open mode.
+ *
+ * We are in fail-open mode and the packet matched the fail-open
+ * rule, but we are connected to a controller too. We should send
+ * the packet up to the controller in the hope that it will try to
+ * set up a flow and thereby allow us to exit fail-open.
+ *
+ * See the top-level comment in fail-open.c for more information. */
+ 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->send_len = 0; /* Not used for flow table misses. */
+ flow_get_metadata(&miss->flow, &pin->fmd);
+ ofproto_dpif_send_packet_in(ofproto, pin);
+ }
}
if (miss->xout.slow) {