Thanks for the review! The series pushed to master,
Jarno On Apr 23, 2014, at 4:56 PM, Ethan Jackson <et...@nicira.com> wrote: > 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