On Wed, Apr 18, 2012 at 11:30, Ethan Jackson <et...@nicira.com> wrote:
> The addition of the ofpbuf stubs is a really useful optimization, but
> it makes the memory management a bit more difficult to work out
> conceptually, so please excuse me if my following comment is
> misguided:
>
> It looks to me like handle_flow_miss() can populate elements of
> 'ops->dpif_op.u.execute' with odp_actions.data which could be
> allocated on the stack.  This data is then used by the caller of
> handle_flow_miss() in its call to dpif_operate().  Also, it seems to
> me that more than one packet could have its dpif_execute actions
> populated from the same stack allocated odp_actions buffer.  Again, I
> may be reading the code wrong, so if you think it's correct feel free
> to ignore.
>
> Ethan

Ah I think I get it now, I think you intended to use the stub in
struct flow_miss_op instead of allocating one on the stack.  The next
patch in the series fixes the problem.  May as well fix it here as
too.

Ethan

>
>
>
> On Mon, Apr 16, 2012 at 17:19, Ben Pfaff <b...@nicira.com> wrote:
>> Signed-off-by: Ben Pfaff <b...@nicira.com>
>> ---
>>  ofproto/ofproto-dpif.c |   68 
>> ++++++++++++++++++++++++++---------------------
>>  1 files changed, 38 insertions(+), 30 deletions(-)
>>
>> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
>> index 8eeefd3..b74331e 100644
>> --- a/ofproto/ofproto-dpif.c
>> +++ b/ofproto/ofproto-dpif.c
>> @@ -334,7 +334,8 @@ static void subfacet_update_time(struct subfacet *, long 
>> long int used);
>>  static void subfacet_update_stats(struct subfacet *,
>>                                   const struct dpif_flow_stats *);
>>  static void subfacet_make_actions(struct subfacet *,
>> -                                  const struct ofpbuf *packet);
>> +                                  const struct ofpbuf *packet,
>> +                                  struct ofpbuf *odp_actions);
>>  static int subfacet_install(struct subfacet *,
>>                             const struct nlattr *actions, size_t actions_len,
>>                             struct dpif_flow_stats *);
>> @@ -2481,7 +2482,9 @@ struct flow_miss {
>>
>>  struct flow_miss_op {
>>     struct dpif_op dpif_op;
>> -    struct subfacet *subfacet;
>> +    struct subfacet *subfacet;  /* Subfacet  */
>> +    void *garbage;              /* Pointer to pass to free(), NULL if none. 
>> */
>> +    uint64_t stub[1024 / 8];    /* Temporary buffer. */
>>  };
>>
>>  /* Sends an OFPT_PACKET_IN message for 'packet' of type OFPR_NO_MATCH to 
>> each
>> @@ -2598,9 +2601,12 @@ handle_flow_miss(struct ofproto_dpif *ofproto, struct 
>> flow_miss *miss,
>>                                miss->initial_tci);
>>
>>     LIST_FOR_EACH (packet, list_node, &miss->packets) {
>> +        struct flow_miss_op *op = &ops[*n_ops];
>> +        struct dpif_execute *execute = &op->dpif_op.u.execute;
>>         struct dpif_flow_stats stats;
>> -        struct flow_miss_op *op;
>> -        struct dpif_execute *execute;
>> +
>> +        uint64_t odp_actions_stub[1024 / 8];
>> +        struct ofpbuf odp_actions;
>>
>>         ofproto->n_matches++;
>>
>> @@ -2618,8 +2624,10 @@ handle_flow_miss(struct ofproto_dpif *ofproto, struct 
>> flow_miss *miss,
>>             send_packet_in_miss(ofproto, packet, flow);
>>         }
>>
>> +        ofpbuf_use_stub(&odp_actions,
>> +                        odp_actions_stub, sizeof odp_actions_stub);
>>         if (!facet->may_install || !subfacet->actions) {
>> -            subfacet_make_actions(subfacet, packet);
>> +            subfacet_make_actions(subfacet, packet, &odp_actions);
>>         }
>>
>>         dpif_flow_stats_extract(&facet->flow, packet, &stats);
>> @@ -2639,18 +2647,22 @@ handle_flow_miss(struct ofproto_dpif *ofproto, 
>> struct flow_miss *miss,
>>             eth_pop_vlan(packet);
>>         }
>>
>> -        op = &ops[(*n_ops)++];
>> -        execute = &op->dpif_op.u.execute;
>> -        op->subfacet = subfacet;
>> +        /* Set up operation. */
>>         op->dpif_op.type = DPIF_OP_EXECUTE;
>>         execute->key = miss->key;
>>         execute->key_len = miss->key_len;
>> -        execute->actions = (facet->may_install
>> -                            ? subfacet->actions
>> -                            : xmemdup(subfacet->actions,
>> -                                      subfacet->actions_len));
>> -        execute->actions_len = subfacet->actions_len;
>> +        if (facet->may_install) {
>> +            execute->actions = subfacet->actions;
>> +            execute->actions_len = subfacet->actions_len;
>> +            op->garbage = NULL;
>> +        } else {
>> +            execute->actions = odp_actions.data;
>> +            execute->actions_len = odp_actions.size;
>> +            op->garbage = ofpbuf_get_uninit_pointer(&odp_actions);
>> +        }
>>         execute->packet = packet;
>> +
>> +        (*n_ops)++;
>>     }
>>
>>     if (facet->may_install && subfacet->key_fitness != ODP_FIT_TOO_LITTLE) {
>> @@ -2658,6 +2670,7 @@ handle_flow_miss(struct ofproto_dpif *ofproto, struct 
>> flow_miss *miss,
>>         struct dpif_flow_put *put = &op->dpif_op.u.flow_put;
>>
>>         op->subfacet = subfacet;
>> +        op->garbage = NULL;
>>         op->dpif_op.type = DPIF_OP_FLOW_PUT;
>>         put->flags = DPIF_FP_CREATE | DPIF_FP_MODIFY;
>>         put->key = miss->key;
>> @@ -2815,14 +2828,9 @@ handle_miss_upcalls(struct ofproto_dpif *ofproto, 
>> struct dpif_upcall *upcalls,
>>     /* Free memory and update facets. */
>>     for (i = 0; i < n_ops; i++) {
>>         struct flow_miss_op *op = &flow_miss_ops[i];
>> -        struct dpif_execute *execute;
>>
>>         switch (op->dpif_op.type) {
>>         case DPIF_OP_EXECUTE:
>> -            execute = &op->dpif_op.u.execute;
>> -            if (op->subfacet->actions != execute->actions) {
>> -                free((struct nlattr *) execute->actions);
>> -            }
>>             break;
>>
>>         case DPIF_OP_FLOW_PUT:
>> @@ -2834,6 +2842,8 @@ handle_miss_upcalls(struct ofproto_dpif *ofproto, 
>> struct dpif_upcall *upcalls,
>>         case DPIF_OP_FLOW_DEL:
>>             NOT_REACHED();
>>         }
>> +
>> +        free(op->garbage);
>>     }
>>     hmap_destroy(&todo);
>>  }
>> @@ -3951,22 +3961,22 @@ subfacet_get_key(struct subfacet *subfacet, struct 
>> odputil_keybuf *keybuf,
>>     }
>>  }
>>
>> -/* Composes the datapath actions for 'subfacet' based on its rule's 
>> actions. */
>> +/* Composes the datapath actions for 'subfacet' based on its rule's actions.
>> + * Translates the actions into 'odp_actions', which the caller must have
>> + * initialized and is responsible for uninitializing. */
>>  static void
>> -subfacet_make_actions(struct subfacet *subfacet, const struct ofpbuf 
>> *packet)
>> +subfacet_make_actions(struct subfacet *subfacet, const struct ofpbuf 
>> *packet,
>> +                      struct ofpbuf *odp_actions)
>>  {
>>     struct facet *facet = subfacet->facet;
>>     struct rule_dpif *rule = facet->rule;
>>     struct ofproto_dpif *ofproto = ofproto_dpif_cast(rule->up.ofproto);
>>
>>     struct action_xlate_ctx ctx;
>> -    uint64_t odp_actions_stub[1024 / 8];
>> -    struct ofpbuf odp_actions;
>>
>> -    ofpbuf_use_stub(&odp_actions, odp_actions_stub, sizeof 
>> odp_actions_stub);
>>     action_xlate_ctx_init(&ctx, ofproto, &facet->flow, subfacet->initial_tci,
>>                           rule, 0, packet);
>> -    xlate_actions(&ctx, rule->up.actions, rule->up.n_actions, &odp_actions);
>> +    xlate_actions(&ctx, rule->up.actions, rule->up.n_actions, odp_actions);
>>     facet->tags = ctx.tags;
>>     facet->may_install = ctx.may_set_up_flow;
>>     facet->has_learn = ctx.has_learn;
>> @@ -3975,14 +3985,12 @@ subfacet_make_actions(struct subfacet *subfacet, 
>> const struct ofpbuf *packet)
>>     facet->nf_flow.output_iface = ctx.nf_output_iface;
>>     facet->mirrors = ctx.mirrors;
>>
>> -    if (subfacet->actions_len != odp_actions.size
>> -        || memcmp(subfacet->actions, odp_actions.data, odp_actions.size)) {
>> +    if (subfacet->actions_len != odp_actions->size
>> +        || memcmp(subfacet->actions, odp_actions->data, odp_actions->size)) 
>> {
>>         free(subfacet->actions);
>> -        subfacet->actions_len = odp_actions.size;
>> -        subfacet->actions = xmemdup(odp_actions.data, odp_actions.size);
>> +        subfacet->actions_len = odp_actions->size;
>> +        subfacet->actions = xmemdup(odp_actions->data, odp_actions->size);
>>     }
>> -
>> -    ofpbuf_uninit(&odp_actions);
>>  }
>>
>>  /* Updates 'subfacet''s datapath flow, setting its actions to 'actions_len'
>> --
>> 1.7.9
>>
>> _______________________________________________
>> 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