Today dpif-netdev has single metadat for given batch, since one batch belongs to one port, but soon packets fro single tunnel ports can belong to different ports, so we need to have per packet metadata.
Signed-off-by: Pravin B Shelar <pshe...@nicira.com> --- lib/dpif-netdev.c | 68 ++++++++++++++++++++------------------------ lib/dpif.c | 7 +++-- lib/odp-execute.c | 28 ++++++++---------- lib/odp-execute.h | 3 +- lib/packet-dpif.c | 3 ++ lib/packet-dpif.h | 1 + ofproto/ofproto-dpif-xlate.c | 3 +- 7 files changed, 54 insertions(+), 59 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 9c61a21..a7c9c92 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -391,12 +391,12 @@ static int dpif_netdev_open(const struct dpif_class *, const char *name, bool create, struct dpif **); static void dp_netdev_execute_actions(struct dp_netdev_pmd_thread *pmd, struct dpif_packet **, int c, - bool may_steal, struct pkt_metadata *, + bool may_steal, const struct nlattr *actions, size_t actions_len); static void dp_netdev_input(struct dp_netdev_pmd_thread *, - struct dpif_packet **, int cnt, - struct pkt_metadata *); + struct dpif_packet **, int cnt); + static void dp_netdev_disable_upcall(struct dp_netdev *); static void dp_netdev_configure_pmd(struct dp_netdev_pmd_thread *pmd, struct dp_netdev *dp, int index, @@ -1860,7 +1860,6 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute) struct dp_netdev *dp = get_dp_netdev(dpif); struct dp_netdev_pmd_thread *pmd; struct dpif_packet packet, *pp; - struct pkt_metadata *md = &execute->md; if (ofpbuf_size(execute->packet) < ETH_HEADER_LEN || ofpbuf_size(execute->packet) > UINT16_MAX) { @@ -1883,7 +1882,7 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute) if (pmd->core_id == NON_PMD_CORE_ID) { ovs_mutex_lock(&dp->non_pmd_mutex); } - dp_netdev_execute_actions(pmd, &pp, 1, false, md, execute->actions, + dp_netdev_execute_actions(pmd, &pp, 1, false, execute->actions, execute->actions_len); if (pmd->core_id == NON_PMD_CORE_ID) { ovs_mutex_unlock(&dp->non_pmd_mutex); @@ -2044,10 +2043,15 @@ dp_netdev_process_rxq_port(struct dp_netdev_pmd_thread *pmd, error = netdev_rxq_recv(rxq, packets, &cnt); if (!error) { - struct pkt_metadata md = PKT_METADATA_INITIALIZER(port->port_no); + int i; *recirc_depth_get() = 0; - dp_netdev_input(pmd, packets, cnt, &md); + + /* XXX: initialize md in netdev implementation. */ + for (i = 0; i < cnt; i++) { + packets[i]->md = PKT_METADATA_INITIALIZER(port->port_no); + } + dp_netdev_input(pmd, packets, cnt); } else if (error != EAGAIN && error != EOPNOTSUPP) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); @@ -2493,7 +2497,6 @@ struct packet_batch { struct dp_netdev_flow *flow; struct dpif_packet *packets[NETDEV_MAX_RX_BATCH]; - struct pkt_metadata md; }; static inline void @@ -2506,11 +2509,9 @@ packet_batch_update(struct packet_batch *batch, struct dpif_packet *packet, } static inline void -packet_batch_init(struct packet_batch *batch, struct dp_netdev_flow *flow, - struct pkt_metadata *md) +packet_batch_init(struct packet_batch *batch, struct dp_netdev_flow *flow) { batch->flow = flow; - batch->md = *md; batch->packet_count = 0; batch->byte_count = 0; @@ -2530,13 +2531,13 @@ packet_batch_execute(struct packet_batch *batch, actions = dp_netdev_flow_get_actions(flow); dp_netdev_execute_actions(pmd, batch->packets, batch->packet_count, true, - &batch->md, actions->actions, actions->size); + actions->actions, actions->size); dp_netdev_count_packet(pmd->dp, DP_STAT_HIT, batch->packet_count); } static inline bool -dp_netdev_queue_batches(struct dpif_packet *pkt, struct pkt_metadata *md, +dp_netdev_queue_batches(struct dpif_packet *pkt, struct dp_netdev_flow *flow, const struct miniflow *mf, struct packet_batch *batches, size_t *n_batches, size_t max_batches) @@ -2565,7 +2566,7 @@ dp_netdev_queue_batches(struct dpif_packet *pkt, struct pkt_metadata *md, } batch = &batches[(*n_batches)++]; - packet_batch_init(batch, flow, md); + packet_batch_init(batch, flow); packet_batch_update(batch, pkt, mf); return true; } @@ -2588,8 +2589,7 @@ dpif_packet_swap(struct dpif_packet **a, struct dpif_packet **b) */ static inline size_t emc_processing(struct dp_netdev_pmd_thread *pmd, struct dpif_packet **packets, - size_t cnt, struct pkt_metadata *md, - struct netdev_flow_key *keys) + size_t cnt, struct netdev_flow_key *keys) { struct netdev_flow_key key; struct packet_batch batches[4]; @@ -2608,12 +2608,12 @@ emc_processing(struct dp_netdev_pmd_thread *pmd, struct dpif_packet **packets, continue; } - miniflow_extract(&packets[i]->ofpbuf, md, &key.flow); + miniflow_extract(&packets[i]->ofpbuf, &packets[i]->md, &key.flow); hash = dpif_netdev_packet_get_dp_hash(packets[i], &key.flow); flow = emc_lookup(flow_cache, &key.flow, hash); - if (OVS_UNLIKELY(!dp_netdev_queue_batches(packets[i], md, + if (OVS_UNLIKELY(!dp_netdev_queue_batches(packets[i], flow, &key.flow, batches, &n_batches, ARRAY_SIZE(batches)))) { @@ -2635,7 +2635,7 @@ emc_processing(struct dp_netdev_pmd_thread *pmd, struct dpif_packet **packets, static inline void fast_path_processing(struct dp_netdev_pmd_thread *pmd, struct dpif_packet **packets, size_t cnt, - struct pkt_metadata *md, struct netdev_flow_key *keys) + struct netdev_flow_key *keys) { #if !defined(__CHECKER__) && !defined(_WIN32) const size_t PKT_ARRAY_SIZE = cnt; @@ -2696,7 +2696,7 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd, /* We can't allow the packet batching in the next loop to execute * the actions. Otherwise, if there are any slow path actions, * we'll send the packet up twice. */ - dp_netdev_execute_actions(pmd, &packets[i], 1, true, md, + dp_netdev_execute_actions(pmd, &packets[i], 1, true, ofpbuf_data(&actions), ofpbuf_size(&actions)); @@ -2747,7 +2747,7 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd, flow = dp_netdev_flow_cast(rules[i]); emc_insert(flow_cache, mfs[i], dpif_packet_get_dp_hash(packet), flow); - dp_netdev_queue_batches(packet, md, flow, mfs[i], batches, &n_batches, + dp_netdev_queue_batches(packet, flow, mfs[i], batches, &n_batches, ARRAY_SIZE(batches)); } @@ -2758,7 +2758,7 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd, static void dp_netdev_input(struct dp_netdev_pmd_thread *pmd, - struct dpif_packet **packets, int cnt, struct pkt_metadata *md) + struct dpif_packet **packets, int cnt) { #if !defined(__CHECKER__) && !defined(_WIN32) const size_t PKT_ARRAY_SIZE = cnt; @@ -2769,9 +2769,9 @@ dp_netdev_input(struct dp_netdev_pmd_thread *pmd, struct netdev_flow_key keys[PKT_ARRAY_SIZE]; size_t newcnt; - newcnt = emc_processing(pmd, packets, cnt, md, keys); + newcnt = emc_processing(pmd, packets, cnt, keys); if (OVS_UNLIKELY(newcnt)) { - fast_path_processing(pmd, packets, newcnt, md, keys); + fast_path_processing(pmd, packets, newcnt, keys); } } @@ -2802,7 +2802,6 @@ dp_netdev_drop_packets(struct dpif_packet ** packets, int cnt, bool may_steal) static void dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt, - struct pkt_metadata *md, const struct nlattr *a, bool may_steal) OVS_NO_THREAD_SAFETY_ANALYSIS { @@ -2837,13 +2836,13 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt, ofpbuf_clear(&actions); - flow_extract(&packets[i]->ofpbuf, md, &flow); + flow_extract(&packets[i]->ofpbuf, &packets[i]->md, &flow); error = dp_netdev_upcall(dp, packets[i], &flow, NULL, DPIF_UC_ACTION, userdata, &actions, NULL); if (!error || error == ENOSPC) { dp_netdev_execute_actions(pmd, &packets[i], 1, may_steal, - md, ofpbuf_data(&actions), + ofpbuf_data(&actions), ofpbuf_size(&actions)); } else if (may_steal) { dpif_packet_delete(packets[i]); @@ -2879,9 +2878,6 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt, hash = 1; /* 0 is not valid */ } - if (i == 0) { - md->dp_hash = hash; - } dpif_packet_set_dp_hash(packets[i], hash); } return; @@ -2893,18 +2889,16 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt, (*depth)++; for (i = 0; i < cnt; i++) { struct dpif_packet *recirc_pkt; - struct pkt_metadata recirc_md = *md; recirc_pkt = (may_steal) ? packets[i] : dpif_packet_clone(packets[i]); - recirc_md.recirc_id = nl_attr_get_u32(a); + recirc_pkt->md.recirc_id = nl_attr_get_u32(a); /* Hash is private to each packet */ - recirc_md.dp_hash = dpif_packet_get_dp_hash(packets[i]); + recirc_pkt->md.dp_hash = dpif_packet_get_dp_hash(packets[i]); - dp_netdev_input(pmd, &recirc_pkt, 1, - &recirc_md); + dp_netdev_input(pmd, &recirc_pkt, 1); } (*depth)--; @@ -2932,12 +2926,12 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt, static void dp_netdev_execute_actions(struct dp_netdev_pmd_thread *pmd, struct dpif_packet **packets, int cnt, - bool may_steal, struct pkt_metadata *md, + bool may_steal, const struct nlattr *actions, size_t actions_len) { struct dp_netdev_execute_aux aux = {pmd}; - odp_execute_actions(&aux, packets, cnt, may_steal, md, actions, + odp_execute_actions(&aux, packets, cnt, may_steal, actions, actions_len, dp_execute_cb); } diff --git a/lib/dpif.c b/lib/dpif.c index 91e9baf..34d8c13 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -991,12 +991,12 @@ struct dpif_execute_helper_aux { * meaningful. */ static void dpif_execute_helper_cb(void *aux_, struct dpif_packet **packets, int cnt, - struct pkt_metadata *md, const struct nlattr *action, bool may_steal OVS_UNUSED) { struct dpif_execute_helper_aux *aux = aux_; int type = nl_attr_type(action); - struct ofpbuf * packet = &packets[0]->ofpbuf; + struct ofpbuf *packet = &packets[0]->ofpbuf; + struct pkt_metadata *md = &packets[0]->md; ovs_assert(cnt == 1); @@ -1064,9 +1064,10 @@ dpif_execute_with_help(struct dpif *dpif, struct dpif_execute *execute) COVERAGE_INC(dpif_execute_with_help); packet.ofpbuf = *execute->packet; + packet.md = execute->md; pp = &packet; - odp_execute_actions(&aux, &pp, 1, false, &execute->md, execute->actions, + odp_execute_actions(&aux, &pp, 1, false, execute->actions, execute->actions_len, dpif_execute_helper_cb); /* Even though may_steal is set to false, some actions could modify or diff --git a/lib/odp-execute.c b/lib/odp-execute.c index e2bc6de..b179cf2 100644 --- a/lib/odp-execute.c +++ b/lib/odp-execute.c @@ -175,8 +175,7 @@ set_arp(struct ofpbuf *packet, const struct ovs_key_arp *key, } static void -odp_execute_set_action(struct dpif_packet *packet, const struct nlattr *a, - struct pkt_metadata *md) +odp_execute_set_action(struct dpif_packet *packet, const struct nlattr *a) { enum ovs_key_attr type = nl_attr_type(a); const struct ovs_key_ipv4 *ipv4_key; @@ -184,6 +183,7 @@ odp_execute_set_action(struct dpif_packet *packet, const struct nlattr *a, const struct ovs_key_tcp *tcp_key; const struct ovs_key_udp *udp_key; const struct ovs_key_sctp *sctp_key; + struct pkt_metadata *md = &packet->md; switch (type) { case OVS_KEY_ATTR_PRIORITY: @@ -271,8 +271,9 @@ odp_execute_set_action(struct dpif_packet *packet, const struct nlattr *a, static void odp_execute_masked_set_action(struct dpif_packet *packet, - const struct nlattr *a, struct pkt_metadata *md) + const struct nlattr *a) { + struct pkt_metadata *md = &packet->md; enum ovs_key_attr type = nl_attr_type(a); struct mpls_hdr *mh; @@ -360,7 +361,7 @@ odp_execute_masked_set_action(struct dpif_packet *packet, static void odp_execute_sample(void *dp, struct dpif_packet *packet, bool steal, - struct pkt_metadata *md, const struct nlattr *action, + const struct nlattr *action, odp_execute_cb dp_execute_action) { const struct nlattr *subactions = NULL; @@ -391,13 +392,12 @@ odp_execute_sample(void *dp, struct dpif_packet *packet, bool steal, } } - odp_execute_actions(dp, &packet, 1, steal, md, nl_attr_get(subactions), + odp_execute_actions(dp, &packet, 1, steal, nl_attr_get(subactions), nl_attr_get_size(subactions), dp_execute_action); } void -odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt, - bool steal, struct pkt_metadata *md, +odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt, bool steal, const struct nlattr *actions, size_t actions_len, odp_execute_cb dp_execute_action) { @@ -419,7 +419,7 @@ odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt, * not need it any more. */ bool may_steal = steal && last_action; - dp_execute_action(dp, packets, cnt, md, a, may_steal); + dp_execute_action(dp, packets, cnt, a, may_steal); if (last_action) { /* We do not need to free the packets. dp_execute_actions() @@ -442,15 +442,11 @@ odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt, for (i = 0; i < cnt; i++) { struct ofpbuf *buf = &packets[i]->ofpbuf; + struct pkt_metadata *md = &packets[i]->md; flow_extract(buf, md, &flow); hash = flow_hash_5tuple(&flow, hash_act->hash_basis); - /* The hash of the first packet is in shared metadata */ - if (i == 0) { - md->dp_hash = hash ? hash : 1; - } - /* We also store the hash value with each packet */ dpif_packet_set_dp_hash(packets[i], hash ? hash : 1); } @@ -501,19 +497,19 @@ odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt, case OVS_ACTION_ATTR_SET: for (i = 0; i < cnt; i++) { - odp_execute_set_action(packets[i], nl_attr_get(a), md); + odp_execute_set_action(packets[i], nl_attr_get(a)); } break; case OVS_ACTION_ATTR_SET_MASKED: for (i = 0; i < cnt; i++) { - odp_execute_masked_set_action(packets[i], nl_attr_get(a), md); + odp_execute_masked_set_action(packets[i], nl_attr_get(a)); } break; case OVS_ACTION_ATTR_SAMPLE: for (i = 0; i < cnt; i++) { - odp_execute_sample(dp, packets[i], steal && last_action, md, a, + odp_execute_sample(dp, packets[i], steal && last_action, a, dp_execute_action); } diff --git a/lib/odp-execute.h b/lib/odp-execute.h index 23dc219..4710bec 100644 --- a/lib/odp-execute.h +++ b/lib/odp-execute.h @@ -28,7 +28,6 @@ struct dpif_packet; struct pkt_metadata; typedef void (*odp_execute_cb)(void *dp, struct dpif_packet **packets, int cnt, - struct pkt_metadata *, const struct nlattr *action, bool may_steal); /* Actions that need to be executed in the context of a datapath are handed @@ -36,7 +35,7 @@ typedef void (*odp_execute_cb)(void *dp, struct dpif_packet **packets, int cnt, * actions OVS_ACTION_ATTR_OUTPUT and OVS_ACTION_ATTR_USERSPACE so * 'dp_execute_action' needs to handle only these. */ void odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt, - bool steal, struct pkt_metadata *, + bool steal, const struct nlattr *actions, size_t actions_len, odp_execute_cb dp_execute_action); #endif diff --git a/lib/packet-dpif.c b/lib/packet-dpif.c index 3a912e1..5b6e1dc 100644 --- a/lib/packet-dpif.c +++ b/lib/packet-dpif.c @@ -27,6 +27,7 @@ dpif_packet_new_with_headroom(size_t size, size_t headroom) ofpbuf_init(b, size + headroom); ofpbuf_reserve(b, headroom); + memset(&p->md, 0, sizeof p->md); return p; } @@ -38,6 +39,7 @@ dpif_packet_clone_from_ofpbuf(const struct ofpbuf *b) size_t headroom = ofpbuf_headroom(b); ofpbuf_init(&p->ofpbuf, ofpbuf_size(b) + headroom); + memset(&p->md, 0, sizeof p->md); ofpbuf_reserve(&p->ofpbuf, headroom); ofpbuf_put(&p->ofpbuf, ofpbuf_data(b), ofpbuf_size(b)); @@ -61,6 +63,7 @@ dpif_packet_clone(struct dpif_packet *p) struct dpif_packet *newp; newp = dpif_packet_clone_from_ofpbuf(&p->ofpbuf); + memcpy(&newp->md, &p->md, sizeof p->md); dpif_packet_set_dp_hash(newp, dpif_packet_get_dp_hash(p)); diff --git a/lib/packet-dpif.h b/lib/packet-dpif.h index 89f048e..1a5efb6 100644 --- a/lib/packet-dpif.h +++ b/lib/packet-dpif.h @@ -30,6 +30,7 @@ struct dpif_packet { #ifndef DPDK_NETDEV uint32_t dp_hash; /* Packet hash. */ #endif + struct pkt_metadata md; }; struct dpif_packet *dpif_packet_new_with_headroom(size_t size, diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 1d46456..880824d 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -3029,7 +3029,8 @@ execute_controller_action(struct xlate_ctx *ctx, int len, &ctx->xout->wc, ctx->xbridge->masked_set_action); - odp_execute_actions(NULL, &packet, 1, false, &md, + packet->md = md; + odp_execute_actions(NULL, &packet, 1, false, ofpbuf_data(ctx->xout->odp_actions), ofpbuf_size(ctx->xout->odp_actions), NULL); -- 1.9.3 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev