Pushed to master,

  Jarno

> On Jun 1, 2015, at 6:06 PM, Jarno Rajahalme <jrajaha...@nicira.com> wrote:
> 
> 
>> On Jun 1, 2015, at 2:48 PM, Ben Pfaff <b...@nicira.com 
>> <mailto:b...@nicira.com>> wrote:
>> 
>> On Mon, Jun 01, 2015 at 01:58:41PM -0700, Jarno Rajahalme wrote:
>>> 
>>>> On Jun 1, 2015, at 1:47 PM, Jarno Rajahalme <jrajaha...@nicira.com 
>>>> <mailto:jrajaha...@nicira.com>> wrote:
>>>> 
>>>> 
>>>>> On May 29, 2015, at 5:38 PM, Ben Pfaff <b...@nicira.com 
>>>>> <mailto:b...@nicira.com>> wrote:
>>>>> 
>>>>> On Mon, May 18, 2015 at 04:10:15PM -0700, Jarno Rajahalme wrote:
>>>>>> OpenFlow bundle messages should be decoded and validated at the time
>>>>>> they are added to the bundle.  This commit does this for flow mod and
>>>>>> port mod messages.
>>>>>> 
>>>>>> Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com 
>>>>>> <mailto:jrajaha...@nicira.com>>
>>>>> 
>>>>> It's pretty expensive to give every ofp_bundle_entry a 1-kB stub for
>>>>> actions, when there might be many thousands of them allocated at a time
>>>>> into a bundle.  It might be better to accumulate the actions into a
>>>>> function-local stub then use ofpbuf_clone() or similar to allocate a
>>>>> correctly sized buffer for ofp_bundle_entry.
>>>>> 
>>>>> I guess that it would be even cheaper, memory-wise (struct match by
>>>>> itself is almost 1/2 kB!), to just decode the raw message a second time
>>>>> when we apply the bundle, but maybe that is not worth the extra trouble.
>>>> 
>>>> I???ll look if I can get the actual replacement rule created at the 
>>>> validation time for the versioned case (after patch 17). For this patch, 
>>>> I???ll just make the stub smaller (64 bytes?).
>>>> 
>>> 
>>> Are you OK with deferring further optimization to the end of the series? 
>>> I.e., can I push this with a smaller stub?
>> 
>> Why bother with a stub at all in the struct?  I suggest using a
>> function-local stub on the stack when decoding the flow_mod, then
>> ofpbuf_steal_data() to put that data into the ofp_bundle.
> 
> 
> OK, I got it now :-) Incremental:
> 
> diff --git a/ofproto/bundles.h b/ofproto/bundles.h
> index 7084b08..c8ce5c9 100644
> --- a/ofproto/bundles.h
> +++ b/ofproto/bundles.h
> @@ -33,13 +33,11 @@ extern "C" {
>  struct ofp_bundle_entry {
>      struct ovs_list   node;
>      ovs_be32          xid;   /* For error returns. */
> -    enum ofptype      type;
> +    enum ofptype      type;  /* OFPTYPE_FLOW_MOD or OFPTYPE_PORT_MOD. */
>      union {
> -        struct ofputil_flow_mod fm;
> +        struct ofputil_flow_mod fm;   /* 'fm.ofpacts' must be malloced. */
>          struct ofputil_port_mod pm;
>      };
> -    struct ofpbuf ofpacts;
> -    uint64_t ofpacts_stub[64 / 8];
>  };
>  
>  static inline struct ofp_bundle_entry *ofp_bundle_entry_alloc(
> @@ -59,8 +57,6 @@ ofp_bundle_entry_alloc(enum ofptype type, ovs_be32 xid)
>  {
>      struct ofp_bundle_entry *entry = xmalloc(sizeof *entry);
>  
> -    ofpbuf_use_stub(&entry->ofpacts, entry->ofpacts_stub,
> -                    sizeof entry->ofpacts_stub);
>      entry->xid = xid;
>      entry->type = type;
>  
> @@ -70,7 +66,9 @@ ofp_bundle_entry_alloc(enum ofptype type, ovs_be32 xid)
>  static inline void ofp_bundle_entry_free(struct ofp_bundle_entry *entry)
>  {
>      if (entry) {
> -        ofpbuf_uninit(&entry->ofpacts);
> +        if (entry->type == OFPTYPE_FLOW_MOD) {
> +            free(entry->fm.ofpacts);
> +        }
>          free(entry);
>      }
>  }
> diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
> index 54d66b6..0a8c82a 100644
> --- a/ofproto/ofproto.c
> +++ b/ofproto/ofproto.c
> @@ -6378,20 +6378,26 @@ handle_bundle_add(struct ofconn *ofconn, const struct 
> ofp_header *oh)
>      if (type == OFPTYPE_PORT_MOD) {
>          error = ofputil_decode_port_mod(badd.msg, &bmsg->pm, false);
>      } else if (type == OFPTYPE_FLOW_MOD) {
> +        struct ofpbuf ofpacts;
> +        uint64_t ofpacts_stub[1024 / 8];
> +
> +        ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
>          error = ofputil_decode_flow_mod(&bmsg->fm, badd.msg,
>                                          ofconn_get_protocol(ofconn),
> -                                        &bmsg->ofpacts,
> +                                        &ofpacts,
>                                          u16_to_ofp(ofproto->max_ports),
>                                          ofproto->n_tables);
> +        /* Move actions to heap. */
> +        bmsg->fm.ofpacts = ofpbuf_steal_data(&ofpacts);
> +
> +        if (!error && bmsg->fm.ofpacts_len) {
> +            error = ofproto_check_ofpacts(ofproto, bmsg->fm.ofpacts,
> +                                          bmsg->fm.ofpacts_len);
> +        }
>      } else {
>          OVS_NOT_REACHED();
>      }
>  
> -    if (!error && bmsg->ofpacts.size) {
> -        error = ofproto_check_ofpacts(ofproto, bmsg->ofpacts.data,
> -                                      bmsg->ofpacts.size);
> -    }
> -
>      if (!error) {
>          error = ofp_bundle_add_message(ofconn, badd.bundle_id, badd.flags,
>                                         bmsg);
> 
> 
>   Jarno

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to