LGTM

Acked-by: Ethan Jackson <et...@nicira.com>


On Wed, Apr 23, 2014 at 4:20 PM, Jarno Rajahalme <jrajaha...@nicira.com> wrote:
> Only take reference to a looked up rule when needed.
>
> This reduces the total CPU utilization of rule_ref/unref calls by 80%,
> from 5% of total server CPU capacity to 1% in a netperf TCP_CRR
> test stressing the userspace.
>
> Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>
> ---
>  ofproto/ofproto-dpif-xlate.c |   49 
> +++++++++++++++++++++++-------------------
>  1 file changed, 27 insertions(+), 22 deletions(-)
>
> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> index c62424a..6a56a15 100644
> --- a/ofproto/ofproto-dpif-xlate.c
> +++ b/ofproto/ofproto-dpif-xlate.c
> @@ -1996,13 +1996,6 @@ xlate_recursively(struct xlate_ctx *ctx, struct 
> rule_dpif *rule)
>      if (ctx->xin->resubmit_stats) {
>          rule_dpif_credit_stats(rule, ctx->xin->resubmit_stats);
>      }
> -    if (ctx->xin->xcache) {
> -        struct xc_entry *entry;
> -
> -        entry = xlate_cache_add_entry(ctx->xin->xcache, XC_RULE);
> -        entry->u.rule = rule;
> -        rule_dpif_ref(rule);
> -    }
>
>      ctx->resubmits++;
>      ctx->recurse++;
> @@ -2057,7 +2050,8 @@ xlate_table_action(struct xlate_ctx *ctx, ofp_port_t 
> in_port, uint8_t table_id,
>                                                !skip_wildcards
>                                                ? &ctx->xout->wc : NULL,
>                                                honor_table_miss,
> -                                              &ctx->table_id, &rule, true);
> +                                              &ctx->table_id, &rule,
> +                                              ctx->xin->xcache != NULL);
>          ctx->xin->flow.in_port.ofp_port = old_in_port;
>
>          if (ctx->xin->resubmit_hook) {
> @@ -2090,12 +2084,22 @@ xlate_table_action(struct xlate_ctx *ctx, ofp_port_t 
> in_port, uint8_t table_id,
>          }
>
>          choose_miss_rule(config, ctx->xbridge->miss_rule,
> -                         ctx->xbridge->no_packet_in_rule, &rule, true);
> +                         ctx->xbridge->no_packet_in_rule, &rule,
> +                         ctx->xin->xcache != NULL);
>
>  match:
>          if (rule) {
> +            /* Fill in the cache entry here instead of xlate_recursively
> +             * to make the reference counting more explicit.  We take a
> +             * reference in the lookups above if we are going to cache the
> +             * rule. */
> +            if (ctx->xin->xcache) {
> +                struct xc_entry *entry;
> +
> +                entry = xlate_cache_add_entry(ctx->xin->xcache, XC_RULE);
> +                entry->u.rule = rule;
> +            }
>              xlate_recursively(ctx, rule);
> -            rule_dpif_unref(rule);
>          }
>
>          ctx->table_id = old_table_id;
> @@ -2653,6 +2657,8 @@ xlate_learn_action(struct xlate_ctx *ctx,
>
>          entry = xlate_cache_add_entry(ctx->xin->xcache, XC_LEARN);
>          entry->u.learn.ofproto = ctx->xin->ofproto;
> +        /* Lookup the learned rule, taking a reference on it.  The reference
> +         * is released when this cache entry is deleted. */
>          rule_dpif_lookup(ctx->xbridge->ofproto, &ctx->xin->flow, NULL,
>                           &entry->u.learn.rule, true);
>      }
> @@ -2678,10 +2684,11 @@ xlate_fin_timeout(struct xlate_ctx *ctx,
>              struct xc_entry *entry;
>
>              entry = xlate_cache_add_entry(ctx->xin->xcache, XC_FIN_TIMEOUT);
> +            /* XC_RULE already holds a reference on the rule, none is taken
> +             * here. */
>              entry->u.fin.rule = ctx->rule;
>              entry->u.fin.idle = oft->fin_idle_timeout;
>              entry->u.fin.hard = oft->fin_hard_timeout;
> -            rule_dpif_ref(ctx->rule);
>          }
>      }
>  }
> @@ -3230,7 +3237,7 @@ xlate_actions__(struct xlate_in *xin, struct xlate_out 
> *xout)
>
>      ctx.xbridge = xbridge_lookup(xin->ofproto);
>      if (!ctx.xbridge) {
> -        goto out;
> +        return;
>      }
>
>      ctx.rule = xin->rule;
> @@ -3263,7 +3270,7 @@ xlate_actions__(struct xlate_in *xin, struct xlate_out 
> *xout)
>      if (!xin->ofpacts && !ctx.rule) {
>          ctx.table_id = rule_dpif_lookup(ctx.xbridge->ofproto, flow,
>                                          !xin->skip_wildcards ? wc : NULL,
> -                                        &rule, true);
> +                                        &rule, ctx.xin->xcache != NULL);
>          if (ctx.xin->resubmit_stats) {
>              rule_dpif_credit_stats(rule, ctx.xin->resubmit_stats);
>          }
> @@ -3271,7 +3278,6 @@ xlate_actions__(struct xlate_in *xin, struct xlate_out 
> *xout)
>              struct xc_entry *entry;
>
>              entry = xlate_cache_add_entry(ctx.xin->xcache, XC_RULE);
> -            rule_dpif_ref(rule);
>              entry->u.rule = rule;
>          }
>          ctx.rule = rule;
> @@ -3309,7 +3315,7 @@ xlate_actions__(struct xlate_in *xin, struct xlate_out 
> *xout)
>              break;
>
>          case OFPC_FRAG_DROP:
> -            goto out;
> +            return;
>
>          case OFPC_FRAG_REASM:
>              OVS_NOT_REACHED();
> @@ -3456,9 +3462,6 @@ xlate_actions__(struct xlate_in *xin, struct xlate_out 
> *xout)
>          wc->masks.tp_src &= htons(UINT8_MAX);
>          wc->masks.tp_dst &= htons(UINT8_MAX);
>      }
> -
> -out:
> -    rule_dpif_unref(rule);
>  }
>
>  /* Sends 'packet' out 'ofport'.
> @@ -3580,9 +3583,9 @@ xlate_push_stats(struct xlate_cache *xcache, bool 
> may_learn,
>                  struct rule_dpif *rule = entry->u.learn.rule;
>
>                  /* Reset the modified time for a rule that is equivalent to
> -                 * the currently cached rule. If the rule is not the exact
> -                 * rule wehave cached, update the reference that we have. */
> -                    entry->u.learn.rule = ofproto_dpif_refresh_rule(rule);
> +                 * the currently cached rule.  If the rule is not the exact
> +                 * rule we have cached, update the reference that we have. */
> +                entry->u.learn.rule = ofproto_dpif_refresh_rule(rule);
>              }
>              break;
>          case XC_NORMAL:
> @@ -3651,13 +3654,15 @@ xlate_cache_clear(struct xlate_cache *xcache)
>              mbridge_unref(entry->u.mirror.mbridge);
>              break;
>          case XC_LEARN:
> +            /* 'u.learn.rule' is the learned rule. */
>              rule_dpif_unref(entry->u.learn.rule);
>              break;
>          case XC_NORMAL:
>              free(entry->u.normal.flow);
>              break;
>          case XC_FIN_TIMEOUT:
> -            rule_dpif_unref(entry->u.fin.rule);
> +            /* 'u.fin.rule' is always already held as a XC_RULE, which
> +             * has already released it's reference above. */
>              break;
>          default:
>              OVS_NOT_REACHED();
> --
> 1.7.10.4
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to