[ovs-dev] [PATCH] ofproto-dpif: Reduce number of get_ofp_port() calls during flow xlate.
Ethan Jackson
ethan at nicira.com
Tue Feb 12 23:44:21 UTC 2013
Acked-by: Ethan Jackson <ethan at nicira.com>
On Mon, Feb 11, 2013 at 2:34 PM, Ben Pfaff <blp at nicira.com> wrote:
> I think you're right.
>
> I changed
> in_port = get_ofp_port(ctx->ofproto, ctx->flow.in_port);
> if (!in_port || stp_forward_in_state(in_port->stp_state)) {
> xlate_table_action(ctx, ctx->flow.in_port, 0, true);
> } else {
> /* Forwarding is disabled by STP. Let OFPP_NORMAL and the learning
> * action look at the packet, then drop it. */
> struct flow old_base_flow = ctx->base_flow;
> size_t old_size = ctx->odp_actions->size;
> xlate_table_action(ctx, ctx->flow.in_port, 0, true);
> ctx->base_flow = old_base_flow;
> ctx->odp_actions->size = old_size;
> }
> to
> in_port = get_ofp_port(ctx->ofproto, ctx->flow.in_port);
> if (!in_port || may_receive(in_port, ctx)) {
> if (!in_port || stp_forward_in_state(in_port->stp_state)) {
> xlate_table_action(ctx, ctx->flow.in_port, 0, true);
> } else {
> /* Forwarding is disabled by STP. Let OFPP_NORMAL and the
> * learning action look at the packet, then drop it. */
> struct flow old_base_flow = ctx->base_flow;
> size_t old_size = ctx->odp_actions->size;
> xlate_table_action(ctx, ctx->flow.in_port, 0, true);
> ctx->base_flow = old_base_flow;
> ctx->odp_actions->size = old_size;
> }
> }
> in compose_output_action__(). I think this takes care of it. I'm
> appending a full revised patch. How does it look?
>
> On Fri, Feb 08, 2013 at 01:29:27PM -0800, Ethan Jackson wrote:
>> The patch pretty much looks good to me. I still don't think we have
>> the patch port code exactly correct though. Suppose we're neither in
>> the forwarding state, nor the learning state. It looks to me like
>> we'll still run through the learning code when sending through the
>> patch port, though we don't do that for a normal port. I think what
>> we really want is something more akin to what we do in xlate_actions
>> where we call may_receive() directly.
>>
>>
>> Ethan
>>
>>
>>
>> On Thu, Feb 7, 2013 at 11:04 AM, Ben Pfaff <blp at nicira.com> wrote:
>> > Until now the flow translation code has done one get_ofp_port() call
>> > initially to check for special processing, then one for each level of
>> > action processing. Only one call is actually necessary, though, because
>> > the in_port of a flow doesn't change in ordinary circumstances, and so this
>> > commit eliminates the unnecessary calls.
>> >
>> > The one case where the in_port can change is when a packet passes through
>> > a patch port. The implementation here was buggy anyway: when the patch
>> > port's peer had forwarding disabled by STP, then the code would drop all
>> > ODP actions, even those that were executed before the packet crossed the
>> > patch port. This commit fixes that case.
>> >
>> > With a complicated flow table involving multiple levels of resubmit, this
>> > increases flow setup performance by 2-3%.
>> >
>> > Signed-off-by: Ben Pfaff <blp at nicira.com>
>
> --8<--------------------------cut here-------------------------->8--
>
> From: Ben Pfaff <blp at nicira.com>
> Date: Mon, 11 Feb 2013 14:32:52 -0800
> Subject: [PATCH] ofproto-dpif: Reduce number of get_ofp_port() calls during flow xlate.
>
> Until now the flow translation code has done one get_ofp_port() call
> initially to check for special processing, then one for each level of
> action processing. Only one call is actually necessary, though, because
> the in_port of a flow doesn't change in ordinary circumstances, and so this
> commit eliminates the unnecessary calls.
>
> The one case where the in_port can change is when a packet passes through
> a patch port. The implementation here was buggy anyway: when the patch
> port's peer had forwarding disabled by STP, then the code would drop all
> ODP actions, even those that were executed before the packet crossed the
> patch port. This commit fixes that case.
>
> With a complicated flow table involving multiple levels of resubmit, this
> increases flow setup performance by 2-3%.
>
> Signed-off-by: Ben Pfaff <blp at nicira.com>
> ---
> ofproto/ofproto-dpif.c | 59 +++++++++++++++++++++++++++++------------------
> 1 files changed, 36 insertions(+), 23 deletions(-)
>
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index 109e57c..f1d88f1 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -3311,15 +3311,11 @@ send_packet_in_miss(struct ofproto_dpif *ofproto, const struct ofpbuf *packet,
>
> static enum slow_path_reason
> process_special(struct ofproto_dpif *ofproto, const struct flow *flow,
> - const struct ofpbuf *packet)
> + const struct ofport_dpif *ofport, const struct ofpbuf *packet)
> {
> - struct ofport_dpif *ofport = get_ofp_port(ofproto, flow->in_port);
> -
> if (!ofport) {
> return 0;
> - }
> -
> - if (ofport->cfm && cfm_should_process_flow(ofport->cfm, flow)) {
> + } else if (ofport->cfm && cfm_should_process_flow(ofport->cfm, flow)) {
> if (packet) {
> cfm_process_heartbeat(ofport->cfm, packet);
> }
> @@ -3335,8 +3331,9 @@ process_special(struct ofproto_dpif *ofproto, const struct flow *flow,
> stp_process_packet(ofport, packet);
> }
> return SLOW_STP;
> + } else {
> + return 0;
> }
> - return 0;
> }
>
> static struct flow_miss *
> @@ -5546,6 +5543,7 @@ send_packet(const struct ofport_dpif *ofport, struct ofpbuf *packet)
>
> /* OpenFlow to datapath action translation. */
>
> +static bool may_receive(const struct ofport_dpif *, struct action_xlate_ctx *);
> static void do_xlate_actions(const struct ofpact *, size_t ofpacts_len,
> struct action_xlate_ctx *);
> static void xlate_normal(struct action_xlate_ctx *);
> @@ -5726,6 +5724,7 @@ compose_output_action__(struct action_xlate_ctx *ctx, uint16_t ofp_port,
> struct ofport_dpif *peer = ofport_get_peer(ofport);
> struct flow old_flow = ctx->flow;
> const struct ofproto_dpif *peer_ofproto;
> + struct ofport_dpif *in_port;
>
> if (!peer) {
> xlate_report(ctx, "Nonexistent patch port peer");
> @@ -5743,7 +5742,22 @@ compose_output_action__(struct action_xlate_ctx *ctx, uint16_t ofp_port,
> ctx->flow.metadata = htonll(0);
> memset(&ctx->flow.tunnel, 0, sizeof ctx->flow.tunnel);
> memset(ctx->flow.regs, 0, sizeof ctx->flow.regs);
> - xlate_table_action(ctx, ctx->flow.in_port, 0, true);
> +
> + in_port = get_ofp_port(ctx->ofproto, ctx->flow.in_port);
> + if (!in_port || may_receive(in_port, ctx)) {
> + if (!in_port || stp_forward_in_state(in_port->stp_state)) {
> + xlate_table_action(ctx, ctx->flow.in_port, 0, true);
> + } else {
> + /* Forwarding is disabled by STP. Let OFPP_NORMAL and the
> + * learning action look at the packet, then drop it. */
> + struct flow old_base_flow = ctx->base_flow;
> + size_t old_size = ctx->odp_actions->size;
> + xlate_table_action(ctx, ctx->flow.in_port, 0, true);
> + ctx->base_flow = old_base_flow;
> + ctx->odp_actions->size = old_size;
> + }
> + }
> +
> ctx->flow = old_flow;
> ctx->ofproto = ofproto_dpif_cast(ofport->up.ofproto);
>
> @@ -6273,16 +6287,9 @@ static void
> do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
> struct action_xlate_ctx *ctx)
> {
> - const struct ofport_dpif *port;
> bool was_evictable = true;
> const struct ofpact *a;
>
> - port = get_ofp_port(ctx->ofproto, ctx->flow.in_port);
> - if (port && !may_receive(port, ctx)) {
> - /* Drop this flow. */
> - return;
> - }
> -
> if (ctx->rule) {
> /* Don't let the rule we're working on get evicted underneath us. */
> was_evictable = ctx->rule->up.evictable;
> @@ -6466,12 +6473,6 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
> }
>
> out:
> - /* We've let OFPP_NORMAL and the learning action look at the packet,
> - * so drop it now if forwarding is disabled. */
> - if (port && !stp_forward_in_state(port->stp_state)) {
> - ofpbuf_clear(ctx->odp_actions);
> - add_sflow_action(ctx);
> - }
> if (ctx->rule) {
> ctx->rule->up.evictable = was_evictable;
> }
> @@ -6534,6 +6535,7 @@ xlate_actions(struct action_xlate_ctx *ctx,
> static bool hit_resubmit_limit;
>
> enum slow_path_reason special;
> + struct ofport_dpif *in_port;
>
> COVERAGE_INC(ofproto_dpif_xlate);
>
> @@ -6587,7 +6589,8 @@ xlate_actions(struct action_xlate_ctx *ctx,
> }
> }
>
> - special = process_special(ctx->ofproto, &ctx->flow, ctx->packet);
> + in_port = get_ofp_port(ctx->ofproto, ctx->flow.in_port);
> + special = process_special(ctx->ofproto, &ctx->flow, in_port, ctx->packet);
> if (special) {
> ctx->slow |= special;
> } else {
> @@ -6596,7 +6599,17 @@ xlate_actions(struct action_xlate_ctx *ctx,
> uint32_t local_odp_port;
>
> add_sflow_action(ctx);
> - do_xlate_actions(ofpacts, ofpacts_len, ctx);
> +
> + if (!in_port || may_receive(in_port, ctx)) {
> + do_xlate_actions(ofpacts, ofpacts_len, ctx);
> +
> + /* We've let OFPP_NORMAL and the learning action look at the
> + * packet, so drop it now if forwarding is disabled. */
> + if (in_port && !stp_forward_in_state(in_port->stp_state)) {
> + ofpbuf_clear(ctx->odp_actions);
> + add_sflow_action(ctx);
> + }
> + }
>
> if (ctx->max_resubmit_trigger && !ctx->resubmit_hook) {
> if (!hit_resubmit_limit) {
> --
> 1.7.2.5
>
More information about the dev
mailing list