- This reduces the number of times upcall cookies are processed. - It separate true miss calls from slow-path actions.
The reorganization will also be useful for a future commit. Signed-off-by: Justin Pettit <jpet...@ovn.org> --- ofproto/ofproto-dpif-upcall.c | 91 +++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 02cf5415bc3d..46b75fe35a2b 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -183,6 +183,7 @@ struct udpif { enum upcall_type { BAD_UPCALL, /* Some kind of bug somewhere. */ MISS_UPCALL, /* A flow miss. */ + SLOW_PATH_UPCALL, /* Slow path upcall. */ SFLOW_UPCALL, /* sFlow sample. */ FLOW_SAMPLE_UPCALL, /* Per-flow sampling. */ IPFIX_UPCALL /* Per-bridge sampling. */ @@ -210,8 +211,7 @@ struct upcall { uint16_t mru; /* If !0, Maximum receive unit of fragmented IP packet */ - enum dpif_upcall_type type; /* Datapath type of the upcall. */ - const struct nlattr *userdata; /* Userdata for DPIF_UC_ACTION Upcalls. */ + enum upcall_type type; /* Type of the upcall. */ const struct nlattr *actions; /* Flow actions in DPIF_UC_ACTION Upcalls. */ bool xout_initialized; /* True if 'xout' must be uninitialized. */ @@ -235,6 +235,8 @@ struct upcall { size_t key_len; /* Datapath flow key length. */ const struct nlattr *out_tun_key; /* Datapath output tunnel key. */ + union user_action_cookie cookie; + uint64_t odp_actions_stub[1024 / 8]; /* Stub for odp_actions. */ }; @@ -367,7 +369,8 @@ static int ukey_acquire(struct udpif *, const struct dpif_flow *, static void ukey_delete__(struct udpif_key *); static void ukey_delete(struct umap *, struct udpif_key *); static enum upcall_type classify_upcall(enum dpif_upcall_type type, - const struct nlattr *userdata); + const struct nlattr *userdata, + union user_action_cookie *cookie); static void put_op_init(struct ukey_op *op, struct udpif_key *ukey, enum dpif_flow_put_flags flags); @@ -813,7 +816,6 @@ recv_upcalls(struct handler *handler) upcall->key = dupcall->key; upcall->key_len = dupcall->key_len; - upcall->ufid = &dupcall->ufid; upcall->out_tun_key = dupcall->out_tun_key; upcall->actions = dupcall->actions; @@ -969,11 +971,13 @@ udpif_revalidator(void *arg) } static enum upcall_type -classify_upcall(enum dpif_upcall_type type, const struct nlattr *userdata) +classify_upcall(enum dpif_upcall_type type, const struct nlattr *userdata, + union user_action_cookie *cookie) { - union user_action_cookie cookie; size_t userdata_len; + memset(cookie, 0, sizeof *cookie); + /* First look at the upcall type. */ switch (type) { case DPIF_UC_ACTION: @@ -994,29 +998,30 @@ classify_upcall(enum dpif_upcall_type type, const struct nlattr *userdata) return BAD_UPCALL; } userdata_len = nl_attr_get_size(userdata); - if (userdata_len < sizeof cookie.type - || userdata_len > sizeof cookie) { + if (userdata_len < sizeof cookie->type + || userdata_len > sizeof *cookie) { VLOG_WARN_RL(&rl, "action upcall cookie has unexpected size %"PRIuSIZE, userdata_len); return BAD_UPCALL; } - memset(&cookie, 0, sizeof cookie); - memcpy(&cookie, nl_attr_get(userdata), userdata_len); - if (userdata_len == MAX(8, sizeof cookie.sflow) - && cookie.type == USER_ACTION_COOKIE_SFLOW) { + + memcpy(cookie, nl_attr_get(userdata), userdata_len); + + if (userdata_len == MAX(8, sizeof cookie->sflow) + && cookie->type == USER_ACTION_COOKIE_SFLOW) { return SFLOW_UPCALL; - } else if (userdata_len == MAX(8, sizeof cookie.slow_path) - && cookie.type == USER_ACTION_COOKIE_SLOW_PATH) { - return MISS_UPCALL; - } else if (userdata_len == MAX(8, sizeof cookie.flow_sample) - && cookie.type == USER_ACTION_COOKIE_FLOW_SAMPLE) { + } else if (userdata_len == MAX(8, sizeof cookie->slow_path) + && cookie->type == USER_ACTION_COOKIE_SLOW_PATH) { + return SLOW_PATH_UPCALL; + } else if (userdata_len == MAX(8, sizeof cookie->flow_sample) + && cookie->type == USER_ACTION_COOKIE_FLOW_SAMPLE) { return FLOW_SAMPLE_UPCALL; - } else if (userdata_len == MAX(8, sizeof cookie.ipfix) - && cookie.type == USER_ACTION_COOKIE_IPFIX) { + } else if (userdata_len == MAX(8, sizeof cookie->ipfix) + && cookie->type == USER_ACTION_COOKIE_IPFIX) { return IPFIX_UPCALL; } else { VLOG_WARN_RL(&rl, "invalid user cookie of type %"PRIu16 - " and size %"PRIuSIZE, cookie.type, userdata_len); + " and size %"PRIuSIZE, cookie->type, userdata_len); return BAD_UPCALL; } } @@ -1078,6 +1083,11 @@ upcall_receive(struct upcall *upcall, const struct dpif_backer *backer, { int error; + upcall->type = classify_upcall(type, userdata, &upcall->cookie); + if (upcall->type == BAD_UPCALL) { + return EAGAIN; + } + error = xlate_lookup(backer, flow, &upcall->ofproto, &upcall->ipfix, &upcall->sflow, NULL, &upcall->in_port); if (error) { @@ -1090,8 +1100,6 @@ upcall_receive(struct upcall *upcall, const struct dpif_backer *backer, upcall->packet = packet; upcall->ufid = ufid; upcall->pmd_id = pmd_id; - upcall->type = type; - upcall->userdata = userdata; ofpbuf_use_stub(&upcall->odp_actions, upcall->odp_actions_stub, sizeof upcall->odp_actions_stub); ofpbuf_init(&upcall->put_actions, 0); @@ -1127,7 +1135,7 @@ upcall_xlate(struct udpif *udpif, struct upcall *upcall, upcall->flow, upcall->in_port, NULL, stats.tcp_flags, upcall->packet, wc, odp_actions); - if (upcall->type == DPIF_UC_MISS) { + if (upcall->type == MISS_UPCALL) { xin.resubmit_stats = &stats; if (xin.frozen_state) { @@ -1176,7 +1184,7 @@ upcall_xlate(struct udpif *udpif, struct upcall *upcall, /* This function is also called for slow-pathed flows. As we are only * going to create new datapath flows for actual datapath misses, there is * no point in creating a ukey otherwise. */ - if (upcall->type == DPIF_UC_MISS) { + if (upcall->type == MISS_UPCALL) { upcall->ukey = ukey_create_from_upcall(upcall, wc); } } @@ -1212,7 +1220,7 @@ should_install_flow(struct udpif *udpif, struct upcall *upcall) { unsigned int flow_limit; - if (upcall->type != DPIF_UC_MISS) { + if (upcall->type != MISS_UPCALL) { return false; } else if (upcall->recirc && !upcall->have_recirc_ref) { VLOG_DBG_RL(&rl, "upcall: no reference for recirc flow"); @@ -1325,6 +1333,7 @@ dpif_read_actions(struct udpif *udpif, struct upcall *upcall, break; case BAD_UPCALL: case MISS_UPCALL: + case SLOW_PATH_UPCALL: default: break; } @@ -1336,53 +1345,46 @@ static int process_upcall(struct udpif *udpif, struct upcall *upcall, struct ofpbuf *odp_actions, struct flow_wildcards *wc) { - const struct nlattr *userdata = upcall->userdata; const struct dp_packet *packet = upcall->packet; const struct flow *flow = upcall->flow; size_t actions_len = 0; - enum upcall_type upcall_type = classify_upcall(upcall->type, userdata); - switch (upcall_type) { + switch (upcall->type) { case MISS_UPCALL: + case SLOW_PATH_UPCALL: upcall_xlate(udpif, upcall, odp_actions, wc); return 0; case SFLOW_UPCALL: if (upcall->sflow) { - union user_action_cookie cookie; struct dpif_sflow_actions sflow_actions; memset(&sflow_actions, 0, sizeof sflow_actions); - memset(&cookie, 0, sizeof cookie); - memcpy(&cookie, nl_attr_get(userdata), sizeof cookie.sflow); - actions_len = dpif_read_actions(udpif, upcall, flow, upcall_type, - &sflow_actions); + actions_len = dpif_read_actions(udpif, upcall, flow, + upcall->type, &sflow_actions); dpif_sflow_received(upcall->sflow, packet, flow, - flow->in_port.odp_port, &cookie, + flow->in_port.odp_port, &upcall->cookie, actions_len > 0 ? &sflow_actions : NULL); } break; case IPFIX_UPCALL: if (upcall->ipfix) { - union user_action_cookie cookie; struct flow_tnl output_tunnel_key; struct dpif_ipfix_actions ipfix_actions; - memset(&cookie, 0, sizeof cookie); - memcpy(&cookie, nl_attr_get(userdata), sizeof cookie.ipfix); memset(&ipfix_actions, 0, sizeof ipfix_actions); if (upcall->out_tun_key) { odp_tun_key_from_attr(upcall->out_tun_key, &output_tunnel_key); } - actions_len = dpif_read_actions(udpif, upcall, flow, upcall_type, - &ipfix_actions); + actions_len = dpif_read_actions(udpif, upcall, flow, + upcall->type, &ipfix_actions); dpif_ipfix_bridge_sample(upcall->ipfix, packet, flow, flow->in_port.odp_port, - cookie.ipfix.output_odp_port, + upcall->cookie.ipfix.output_odp_port, upcall->out_tun_key ? &output_tunnel_key : NULL, actions_len > 0 ? &ipfix_actions: NULL); @@ -1391,24 +1393,21 @@ process_upcall(struct udpif *udpif, struct upcall *upcall, case FLOW_SAMPLE_UPCALL: if (upcall->ipfix) { - union user_action_cookie cookie; struct flow_tnl output_tunnel_key; struct dpif_ipfix_actions ipfix_actions; - memset(&cookie, 0, sizeof cookie); - memcpy(&cookie, nl_attr_get(userdata), sizeof cookie.flow_sample); memset(&ipfix_actions, 0, sizeof ipfix_actions); if (upcall->out_tun_key) { odp_tun_key_from_attr(upcall->out_tun_key, &output_tunnel_key); } - actions_len = dpif_read_actions(udpif, upcall, flow, upcall_type, - &ipfix_actions); + actions_len = dpif_read_actions(udpif, upcall, flow, + upcall->type, &ipfix_actions); /* The flow reflects exactly the contents of the packet. * Sample the packet using it. */ dpif_ipfix_flow_sample(upcall->ipfix, packet, flow, - &cookie, flow->in_port.odp_port, + &upcall->cookie, flow->in_port.odp_port, upcall->out_tun_key ? &output_tunnel_key : NULL, actions_len > 0 ? &ipfix_actions: NULL); -- 2.7.4 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev