From: Pravin B Shelar Date: Sat, 4 Oct 2014 03:23:58 +0000 (-0700) Subject: netdev-dpif: Add metadata to dpif-packet. X-Git-Tag: v2.4.0~1217 X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fovs.git;a=commitdiff_plain;h=41ccaa249c923b623a321a586b640a622cdc2281 netdev-dpif: Add metadata to dpif-packet. 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 Acked-by: Jarno Rajahalme --- diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index a1db620b3..cea7c888f 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -384,12 +384,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, @@ -1853,7 +1853,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) { @@ -1861,6 +1860,7 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute) } packet.ofpbuf = *execute->packet; + packet.md = execute->md; pp = &packet; /* Tries finding the 'pmd'. If NULL is returned, that means @@ -1876,7 +1876,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); @@ -1886,7 +1886,7 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute) * reallocate the ofpbuf memory. We need to pass those changes to the * caller */ *execute->packet = packet.ofpbuf; - + execute->md = packet.md; return 0; } @@ -2037,10 +2037,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); @@ -2486,7 +2491,6 @@ struct packet_batch { struct dp_netdev_flow *flow; struct dpif_packet *packets[NETDEV_MAX_RX_BATCH]; - struct pkt_metadata md; }; static inline void @@ -2499,11 +2503,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; @@ -2523,13 +2525,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) @@ -2558,7 +2560,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; } @@ -2581,8 +2583,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]; @@ -2601,12 +2602,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)))) { @@ -2628,7 +2629,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; @@ -2689,7 +2690,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)); @@ -2740,7 +2741,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)); } @@ -2751,7 +2752,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; @@ -2762,9 +2763,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); } } @@ -2795,7 +2796,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 { @@ -2830,13 +2830,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]); @@ -2872,9 +2872,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; @@ -2886,18 +2883,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)--; @@ -2925,12 +2920,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}; + 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 91e9baf61..d088f6882 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,15 +1064,17 @@ 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 * reallocate the ofpbuf memory. We need to pass those changes to the * caller */ *execute->packet = packet.ofpbuf; + execute->md = packet.md; return aux.error; } diff --git a/lib/odp-execute.c b/lib/odp-execute.c index e2bc6de07..230e6e1b6 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() @@ -441,16 +441,9 @@ odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt, uint32_t hash; for (i = 0; i < cnt; i++) { - struct ofpbuf *buf = &packets[i]->ofpbuf; - - flow_extract(buf, md, &flow); + flow_extract(&packets[i]->ofpbuf, &packets[i]->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 +494,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 23dc219f6..4710bec72 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 3a912e194..db739c55f 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); + p->md = PKT_METADATA_INITIALIZER(0); 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); + p->md = PKT_METADATA_INITIALIZER(0); 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 89f048edc..1a5efb64b 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 a881dfb1a..07a1f29b9 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -3015,7 +3015,6 @@ execute_controller_action(struct xlate_ctx *ctx, int len, { struct ofproto_packet_in *pin; struct dpif_packet *packet; - struct pkt_metadata md = PKT_METADATA_INITIALIZER(0); ctx->xout->slow |= SLOW_CONTROLLER; if (!ctx->xin->packet) { @@ -3029,7 +3028,7 @@ 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, + odp_execute_actions(NULL, &packet, 1, false, ofpbuf_data(ctx->xout->odp_actions), ofpbuf_size(ctx->xout->odp_actions), NULL);