diff options
author | Jarno Rajahalme <jrajahalme@nicira.com> | 2015-08-25 13:55:03 -0700 |
---|---|---|
committer | Jarno Rajahalme <jrajahalme@nicira.com> | 2015-08-26 15:39:35 -0700 |
commit | 597819523ca5b5641653c410c2f13f364352677f (patch) | |
tree | c9ad0a479b0bd1ab165b8e61a6aa95d7b4fb0b66 /ofproto/ofproto-dpif-rid.h | |
parent | a14502a7c529befab29fbe2f16230f3878837f13 (diff) | |
download | openvswitch-597819523ca5b5641653c410c2f13f364352677f.tar.gz |
ofproto-dpif-rid: Make lookups cheaper.
This patch removes a large-ish copy from the recirculation context
lookup, which is performed for each recirculated upcall and
revalidation of a recirculating flow.
Tunnel metadata has grown large since the addition of Geneve options,
and copying that metadata for performing a lookup is not necessary.
Change recirc_metadata to use a pointer to struct flow_tnl, and only
copy the tunnel metadata when needed, and only copy as little of it as
possible.
Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'ofproto/ofproto-dpif-rid.h')
-rw-r--r-- | ofproto/ofproto-dpif-rid.h | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/ofproto/ofproto-dpif-rid.h b/ofproto/ofproto-dpif-rid.h index 11ae4864e..e7d95bf14 100644 --- a/ofproto/ofproto-dpif-rid.h +++ b/ofproto/ofproto-dpif-rid.h @@ -34,40 +34,40 @@ struct rule; * ============= * * Recirculation is a technique to allow a frame to re-enter the datapath - * packet processing path for one or multiple times to achieve more flexible - * packet processing, such modifying header fields after MPLS POP action and - * selecting bond a slave port for bond ports. + * packet processing path to achieve more flexible packet processing, such as + * modifying header fields after MPLS POP action and selecting a slave port for + * bond ports. * * Data path and user space interface * ----------------------------------- * * Recirculation uses two uint32_t fields, recirc_id and dp_hash, and a RECIRC - * action. The value recirc_id is used to select the next packet processing - * steps among multiple instances of recirculation. When a packet initially - * enters the data path it is assigned with recirc_id 0, which indicates no - * recirculation. Recirc_ids are managed by the user space, opaque to the - * data path. + * action. recirc_id is used to select the next packet processing steps among + * multiple instances of recirculation. When a packet initially enters the + * datapath it is assigned with recirc_id 0, which indicates no recirculation. + * Recirc_ids are managed by the user space, opaque to the datapath. * - * On the other hand, dp_hash can only be computed by the data path, opaque to - * the user space. In fact, user space may not able to recompute the hash - * value. The dp_hash value should be wildcarded for a newly received - * packet. HASH action specifies whether the hash is computed, and if - * computed, how many fields are to be included in the hash computation. The - * computed hash value is stored into the dp_hash field prior to recirculation. + * On the other hand, dp_hash can only be computed by the datapath, opaque to + * the user space, as the datapath is free to choose the hashing algorithm + * without informing user space about it. The dp_hash value should be + * wildcarded for newly received packets. HASH action specifies whether the + * hash is computed, and if computed, how many fields are to be included in the + * hash computation. The computed hash value is stored into the dp_hash field + * prior to recirculation. * * The RECIRC action sets the recirc_id field and then reprocesses the packet - * as if it was received on the same input port. RECIRC action works like a - * function call; actions listed behind the RECIRC action will be executed - * after its execution. RECIRC action can be nested, data path implementation - * limits the number of recirculation executed to prevent unreasonable nesting - * depth or infinite loop. + * as if it was received again on the same input port. RECIRC action works + * like a function call; actions listed after the RECIRC action will be + * executed after recirculation. RECIRC action can be nested, but datapath + * implementation limits the number of nested recirculations to prevent + * unreasonable nesting depth or infinite loop. * * User space recirculation context * --------------------------------- * - * Recirculation is hidden from the OpenFlow controllers. Action translation - * code deduces when recirculation is necessary and issues a data path - * recirculation action. All OpenFlow actions to be performed after + * Recirculation is usually hidden from the OpenFlow controllers. Action + * translation code deduces when recirculation is necessary and issues a + * datapath recirculation action. All OpenFlow actions to be performed after * recirculation are derived from the OpenFlow pipeline and are stored with the * recirculation ID. When the OpenFlow tables are changed in a way affecting * the recirculation flows, new recirculation ID with new metadata and actions @@ -76,9 +76,10 @@ struct rule; * Recirculation ID pool * ---------------------- * - * Recirculation ID needs to be unique for all data paths. Recirculation ID - * pool keeps track recirculation ids and stores OpenFlow pipeline translation - * context so that flow processing may continue after recirculation. + * Recirculation ID needs to be unique for all datapaths. Recirculation ID + * pool keeps track of recirculation ids and stores OpenFlow pipeline + * translation context so that flow processing may continue after + * recirculation. * * A Recirculation ID can be any uint32_t value, except for that the value 0 is * reserved for 'no recirculation' case. @@ -96,7 +97,7 @@ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 33); struct recirc_metadata { /* Metadata in struct flow. */ - struct flow_tnl tunnel; /* Encapsulating tunnel parameters. */ + const struct flow_tnl *tunnel; /* Encapsulating tunnel parameters. */ ovs_be64 metadata; /* OpenFlow Metadata. */ uint64_t regs[FLOW_N_XREGS]; /* Registers. */ ofp_port_t in_port; /* Incoming port. */ @@ -108,7 +109,7 @@ recirc_metadata_from_flow(struct recirc_metadata *md, const struct flow *flow) { memset(md, 0, sizeof *md); - md->tunnel = flow->tunnel; + md->tunnel = &flow->tunnel; md->metadata = flow->metadata; memcpy(md->regs, flow->regs, sizeof md->regs); md->in_port = flow->in_port.ofp_port; @@ -119,7 +120,11 @@ static inline void recirc_metadata_to_flow(const struct recirc_metadata *md, struct flow *flow) { - flow->tunnel = md->tunnel; + if (md->tunnel && md->tunnel->ip_dst) { + flow->tunnel = *md->tunnel; + } else { + memset(&flow->tunnel, 0, sizeof flow->tunnel); + } flow->metadata = md->metadata; memcpy(flow->regs, md->regs, sizeof flow->regs); flow->in_port.ofp_port = md->in_port; @@ -161,6 +166,9 @@ struct recirc_id_node { * This state should not be modified after inserting a node in the pool, * hence the 'const' to emphasize that. */ const struct recirc_state state; + + /* Storage for tunnel metadata. */ + struct flow_tnl state_metadata_tunnel; }; void recirc_init(void); |