flow: Take advantage of zero-padding in struct flow and flow_wildcards.
authorBen Pfaff <blp@nicira.com>
Mon, 18 Jun 2012 22:12:57 +0000 (15:12 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 4 Sep 2012 18:19:16 +0000 (11:19 -0700)
Since we know these bytes are always 0 in both structures, we can use
faster functions that only work with full words.

Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/flow.c
lib/flow.h

index c414e81228e72830ccb476f97ced92fa2ab07fe4..a16c8ef62016db806d14a94f853a547138c28fa4 100644 (file)
@@ -756,11 +756,7 @@ flow_wildcards_combine(struct flow_wildcards *dst,
 uint32_t
 flow_wildcards_hash(const struct flow_wildcards *wc, uint32_t basis)
 {
-    /* If you change struct flow_wildcards and thereby trigger this
-     * assertion, please check that the new struct flow_wildcards has no holes
-     * in it before you update the assertion. */
-    BUILD_ASSERT_DECL(sizeof *wc == 120 + FLOW_N_REGS * 4);
-    return hash_bytes(wc, sizeof *wc, basis);
+    return hash_words((const uint32_t *) wc, sizeof *wc / 4, basis);
 }
 
 /* Returns true if 'a' and 'b' represent the same wildcards, false if they are
index 30cd044d878888a151cb4ff1305fae0e9e88e176..3534fb485c61f4fccd2996150cedd97c0c347540 100644 (file)
@@ -77,6 +77,10 @@ struct flow {
     uint8_t nw_frag;            /* FLOW_FRAG_* flags. */
     uint8_t zeros[2];           /* Must be zero. */
 };
+BUILD_ASSERT_DECL(sizeof(struct flow) % 8 == 0);
+
+/* Remember to update FLOW_WC_SEQ when changing 'struct flow'. */
+BUILD_ASSERT_DECL(sizeof(struct flow) == 152 && FLOW_WC_SEQ == 17);
 
 /* Represents the metadata fields of struct flow. */
 struct flow_metadata {
@@ -86,17 +90,6 @@ struct flow_metadata {
     uint16_t in_port;                /* OpenFlow port or zero. */
 };
 
-/* Assert that there are FLOW_SIG_SIZE bytes of significant data in "struct
- * flow", followed by FLOW_PAD_SIZE bytes of padding. */
-#define FLOW_SIG_SIZE (118 + FLOW_N_REGS * 4)
-#define FLOW_PAD_SIZE 2
-BUILD_ASSERT_DECL(offsetof(struct flow, nw_frag) == FLOW_SIG_SIZE - 1);
-BUILD_ASSERT_DECL(sizeof(((struct flow *)0)->nw_frag) == 1);
-BUILD_ASSERT_DECL(sizeof(struct flow) == FLOW_SIG_SIZE + FLOW_PAD_SIZE);
-
-/* Remember to update FLOW_WC_SEQ when changing 'struct flow'. */
-BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 150 && FLOW_WC_SEQ == 17);
-
 void flow_extract(struct ofpbuf *, uint32_t priority, ovs_be64 tun_id,
                   uint16_t in_port, struct flow *);
 void flow_zero_wildcards(struct flow *, const struct flow_wildcards *);
@@ -118,7 +111,7 @@ void flow_compose(struct ofpbuf *, const struct flow *);
 static inline int
 flow_compare_3way(const struct flow *a, const struct flow *b)
 {
-    return memcmp(a, b, FLOW_SIG_SIZE);
+    return memcmp(a, b, sizeof *a);
 }
 
 static inline bool
@@ -130,7 +123,7 @@ flow_equal(const struct flow *a, const struct flow *b)
 static inline size_t
 flow_hash(const struct flow *flow, uint32_t basis)
 {
-    return hash_bytes(flow, FLOW_SIG_SIZE, basis);
+    return hash_words((const uint32_t *) flow, sizeof *flow / 4, basis);
 }
 
 /* Information on wildcards for a flow, as a supplement to "struct flow". */
@@ -160,6 +153,7 @@ struct flow_wildcards {
     uint8_t nw_ttl_mask;        /* 1-bit in each significant nw_ttl bit. */
     uint8_t zeros[6];           /* Padding field set to zero. */
 };
+BUILD_ASSERT_DECL(sizeof(struct flow_wildcards) % 8 == 0);
 
 /* Remember to update FLOW_WC_SEQ when updating struct flow_wildcards. */
 BUILD_ASSERT_DECL(sizeof(struct flow_wildcards) == 152 && FLOW_WC_SEQ == 17);