X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto-dpif-upcall.c;h=dde64300a3bdb5586a69db945a9aaab34920252e;hb=5a8cc7859f9f0b2aebbe7f931fc64603136ed22d;hp=4c92db38185bd5d682a9d19b50d5cf71a49f1fab;hpb=10e576406c7444ef198cc2d4b6c4adfe242c085c;p=sliver-openvswitch.git diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 4c92db381..dde64300a 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -19,6 +19,7 @@ #include #include +#include "connmgr.h" #include "coverage.h" #include "dynamic-string.h" #include "dpif.h" @@ -31,7 +32,6 @@ #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" @@ -59,6 +59,7 @@ struct handler { 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'. */ @@ -222,6 +223,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_upcall_handler, @@ -392,7 +394,7 @@ udpif_upcall_handler(void *arg) { 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; @@ -419,6 +421,8 @@ udpif_upcall_handler(void *arg) ovs_mutex_unlock(&handler->mutex); handle_upcalls(handler->udpif, &misses); + + coverage_clear(); } } @@ -458,7 +462,7 @@ classify_upcall(const struct upcall *upcall) userdata_len = nl_attr_get_size(dpif_upcall->userdata); if (userdata_len < sizeof cookie.type || userdata_len > sizeof cookie) { - VLOG_WARN_RL(&rl, "action upcall cookie has unexpected size %zu", + VLOG_WARN_RL(&rl, "action upcall cookie has unexpected size %"PRIuSIZE, userdata_len); return BAD_UPCALL; } @@ -478,7 +482,7 @@ classify_upcall(const struct upcall *upcall) return IPFIX_UPCALL; } else { VLOG_WARN_RL(&rl, "invalid user cookie of type %"PRIu16 - " and size %zu", cookie.type, userdata_len); + " and size %"PRIuSIZE, cookie.type, userdata_len); return BAD_UPCALL; } } @@ -486,7 +490,6 @@ classify_upcall(const struct upcall *upcall) static void recv_upcalls(struct udpif *udpif) { - size_t n_udpif_new_upcalls = 0; int n; for (;;) { @@ -515,7 +518,7 @@ recv_upcalls(struct udpif *udpif) || type == OVS_KEY_ATTR_TCP || type == OVS_KEY_ATTR_UDP) { if (nl_attr_get_size(nla) == 4) { - hash = mhash_add(hash, nl_attr_get_be32(nla)); + hash = mhash_add(hash, nl_attr_get_u32(nla)); n_bytes += 4; } else { VLOG_WARN_RL(&rl, @@ -530,9 +533,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); @@ -555,16 +562,13 @@ recv_upcalls(struct udpif *udpif) 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 * @@ -757,23 +761,14 @@ handle_upcalls(struct udpif *udpif, struct list *upcalls) * 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 @@ -794,13 +789,10 @@ handle_upcalls(struct udpif *udpif, struct list *upcalls) 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) { @@ -826,6 +818,7 @@ handle_upcalls(struct udpif *udpif, struct list *upcalls) 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; } } @@ -846,17 +839,17 @@ handle_upcalls(struct udpif *udpif, struct list *upcalls) 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); } }