Re: [ovs-dev] [PATCH v10 1/5] dpif-netdev: implement function pointers/subtable

2019-07-10 Thread Ian Stokes

On 7/10/2019 4:40 PM, Van Haaren, Harry wrote:

-Original Message-
From: Stokes, Ian
Sent: Wednesday, July 10, 2019 4:30 PM
To: Van Haaren, Harry ; d...@openvswitch.org
Cc: i.maxim...@samsung.com; malvika.gu...@arm.com
Subject: Re: [PATCH v10 1/5] dpif-netdev: implement function pointers/subtable

On 7/9/2019 1:34 PM, Harry van Haaren wrote:

This allows plugging-in of different subtable hash-lookup-verify
routines, and allows special casing of those functions based on
known context (eg: # of bits set) of the specific subtable.

Signed-off-by: Harry van Haaren 
Tested-by: Malvika Gupta 



Thanks for this harry, few minor comments below.


Hey, cool I'll snip away irrelevant code sections for readability.









I've thought about whether an item should be added to the NEWS doc
(possibly not in this patch but perhaps later in the series), it's hard
to say as the changes are under the hood and not configurable by a user.
Thoughts?


Correct the user shouldn't identify the actual changes, except for small
gains in performance if the specialized subtables are in use.

I think it would be good to add a NEWS item, as people profiling OVS's functions
will see different function names, and having called out the DPCLS Function 
Pointer
changes, and why they are there would be beneficial.

I will draft a separate patch for NEWS item - so we can keep it parallel to 
this patch set.
Shout if that is not a good approach :)


I would think it could be added as part of patch 5 of the series as 
that's when the performance increase is introduced? Anyway it's minor 
enough that if there is not another revision of the series it can be 
done upon commit.


Regards
Ian

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH v10 1/5] dpif-netdev: implement function pointers/subtable

2019-07-10 Thread Van Haaren, Harry
> -Original Message-
> From: Stokes, Ian
> Sent: Wednesday, July 10, 2019 4:30 PM
> To: Van Haaren, Harry ; d...@openvswitch.org
> Cc: i.maxim...@samsung.com; malvika.gu...@arm.com
> Subject: Re: [PATCH v10 1/5] dpif-netdev: implement function pointers/subtable
> 
> On 7/9/2019 1:34 PM, Harry van Haaren wrote:
> > This allows plugging-in of different subtable hash-lookup-verify
> > routines, and allows special casing of those functions based on
> > known context (eg: # of bits set) of the specific subtable.
> >
> > Signed-off-by: Harry van Haaren 
> > Tested-by: Malvika Gupta 
> >
> 
> Thanks for this harry, few minor comments below.

Hey, cool I'll snip away irrelevant code sections for readability.




> > +uint32_t
> > +dpcls_subtable_lookup_generic(struct dpcls_subtable *subtable,
> > +  uint32_t keys_map,
> > +  const struct netdev_flow_key *keys[],
> > +  struct dpcls_rule **rules)
> > +{
> > +int i;
> > +uint32_t found_map;
> 
> I was thinking should this be initialized to 0, but  I don't think there
> is a need. the call to cmap_find_batch() below will set it to 0 in the
> case of no math, otherwise set the i-th bit for a match so I thinks it's ok.

Correct - the value is written before being used - always.
Initializing it to zero is pointless, and only waste and instruction.



> > @@ -7849,16 +7931,12 @@ dpcls_lookup(struct dpcls *cls, const struct
> >   if (cnt != MAP_BITS) {
> >   keys_map >>= MAP_BITS - cnt; /* Clear extra bits. */
> > @@ -7866,6 +7944,7 @@ dpcls_lookup(struct dpcls *cls, const struct
> netdev_flow_key *keys[],
> >   memset(rules, 0, cnt * sizeof *rules);
> >
> >   int lookups_match = 0, subtable_pos = 1;
> > +uint32_t found_map;
> 
> Same as above, should be OK as it wont be used until after the call to
> the generic look up function, which will set it to 0 in the event of no
> matches.

Correct - written before use - no use in initializing to any value.


> > -/* None of the found rules was a match.  Reset the i-th bit to
> > - * keep searching this key in the next subtable. */
> > -ULLONG_SET0(found_map, i);  /* Did not match. */
> > -next:
> > -; /* Keep Sparse happy. */
> > -}
> > -keys_map &= ~found_map; /* Clear the found rules. */
> > +/* Clear the found rules, and return early if all packets are
> found. */
> > +keys_map &= ~found_map;
> >   if (!keys_map) {
> >   if (num_lookups_p) {
> >   *num_lookups_p = lookups_match;
> >   }
> > -return true;  /* All found. */
> > +return true;
> >   }
> >   subtable_pos++;
> >   }
> > +
> >   if (num_lookups_p) {
> >   *num_lookups_p = lookups_match;
> >   }
> > -return false; /* Some misses. */
> > +return false;
> >   }
> >
> 
> I've thought about whether an item should be added to the NEWS doc
> (possibly not in this patch but perhaps later in the series), it's hard
> to say as the changes are under the hood and not configurable by a user.
> Thoughts?

Correct the user shouldn't identify the actual changes, except for small
gains in performance if the specialized subtables are in use.

I think it would be good to add a NEWS item, as people profiling OVS's functions
will see different function names, and having called out the DPCLS Function 
Pointer
changes, and why they are there would be beneficial.

I will draft a separate patch for NEWS item - so we can keep it parallel to 
this patch set.
Shout if that is not a good approach :)

> Regards
> Ian

Thanks for review!

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH v10 1/5] dpif-netdev: implement function pointers/subtable

2019-07-10 Thread Ian Stokes

On 7/9/2019 1:34 PM, Harry van Haaren wrote:

This allows plugging-in of different subtable hash-lookup-verify
routines, and allows special casing of those functions based on
known context (eg: # of bits set) of the specific subtable.

Signed-off-by: Harry van Haaren 
Tested-by: Malvika Gupta 



Thanks for this harry, few minor comments below.


---

v10:
- Fix capitalization of comments, and punctuation. (Ian)
- Variable declarations up top before use (Ian)
- Fix alignment of function parameters, had to newline after typedef (Ian)
- Some mailing-list questions relpied to on-list (Ian)

v9:
- Use count_1bits in favour of __builtin_popcount (Ilya)

v6:
- Implement subtable effort per packet "lookups_match" counter  (Ilya)
- Remove double newline (Eelco)
- Remove double * before comments (Eelco)
- Reword comments in dpcls_lookup() for clarity (Harry)
---
  lib/dpif-netdev.c | 138 --
  1 file changed, 96 insertions(+), 42 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index f4b59e41b..f02bcd552 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -7603,6 +7603,28 @@ dpif_dummy_register(enum dummy_level level)
  
  /* Datapath Classifier. */
  
+/* Forward declaration for lookup_func typedef. */

+struct dpcls_subtable;
+
+/* Lookup function for a subtable in the dpcls. This function is called
+ * by each subtable with an array of packets, and a bitmask of packets to
+ * perform the lookup on. Using a function pointer gives flexibility to
+ * optimize the lookup function based on subtable properties and the
+ * CPU instruction set available at runtime.
+ */
+typedef
+uint32_t (*dpcls_subtable_lookup_func)(struct dpcls_subtable *subtable,
+   uint32_t keys_map,
+   const struct netdev_flow_key *keys[],
+   struct dpcls_rule **rules);
+
+/* Prototype for generic lookup func, using same code path as before. */
+uint32_t
+dpcls_subtable_lookup_generic(struct dpcls_subtable *subtable,
+  uint32_t keys_map,
+  const struct netdev_flow_key *keys[],
+  struct dpcls_rule **rules);
+
  /* A set of rules that all have the same fields wildcarded. */
  struct dpcls_subtable {
  /* The fields are only used by writers. */
@@ -7612,6 +7634,13 @@ struct dpcls_subtable {
  struct cmap rules;   /* Contains "struct dpcls_rule"s. */
  uint32_t hit_cnt;/* Number of match hits in subtable in 
current
  optimization interval. */
+
+/* The lookup function to use for this subtable. If there is a known
+ * property of the subtable (eg: only 3 bits of miniflow metadata is
+ * used for the lookup) then this can point at an optimized version of
+ * the lookup function for this particular subtable. */
+dpcls_subtable_lookup_func lookup_func;
+
  struct netdev_flow_key mask; /* Wildcards for fields (const). */
  /* 'mask' must be the last field, additional space is allocated here. */
  };
@@ -7671,6 +7700,10 @@ dpcls_create_subtable(struct dpcls *cls, const struct 
netdev_flow_key *mask)
  cmap_init(&subtable->rules);
  subtable->hit_cnt = 0;
  netdev_flow_key_clone(&subtable->mask, mask);
+
+/* Decide which hash/lookup/verify function to use. */
+subtable->lookup_func = dpcls_subtable_lookup_generic;
+
  cmap_insert(&cls->subtables_map, &subtable->cmap_node, mask->hash);
  /* Add the new subtable at the end of the pvector (with no hits yet) */
  pvector_insert(&cls->subtables, subtable, 0);
@@ -7831,6 +7864,55 @@ dpcls_rule_matches_key(const struct dpcls_rule *rule,
  return true;
  }
  
+uint32_t

+dpcls_subtable_lookup_generic(struct dpcls_subtable *subtable,
+  uint32_t keys_map,
+  const struct netdev_flow_key *keys[],
+  struct dpcls_rule **rules)
+{
+int i;
+uint32_t found_map;


I was thinking should this be initialized to 0, but  I don't think there 
is a need. the call to cmap_find_batch() below will set it to 0 in the 
case of no math, otherwise set the i-th bit for a match so I thinks it's ok.



+
+/* Compute hashes for the remaining keys.  Each search-key is
+ * masked with the subtable's mask to avoid hashing the wildcarded
+ * bits. */
+uint32_t hashes[NETDEV_MAX_BURST];
+ULLONG_FOR_EACH_1(i, keys_map) {
+hashes[i] = netdev_flow_key_hash_in_mask(keys[i],
+ &subtable->mask);
+}
+
+/* Lookup. */
+const struct cmap_node *nodes[NETDEV_MAX_BURST];
+found_map = cmap_find_batch(&subtable->rules, keys_map, hashes, nodes);
+
+/* Check results.  When the i-th bit of found_map is set, it means
+ * that