> On Jun 1, 2015, at 2:48 PM, Ben Pfaff <[email protected]> wrote:
>
> On Mon, Jun 01, 2015 at 01:58:41PM -0700, Jarno Rajahalme wrote:
>>
>>> On Jun 1, 2015, at 1:47 PM, Jarno Rajahalme <[email protected]> wrote:
>>>
>>>
>>>> On May 29, 2015, at 5:38 PM, Ben Pfaff <[email protected]> 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 <[email protected]>
>>>>
>>>> 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
[email protected]
http://openvswitch.org/mailman/listinfo/dev