On 03/13/2014 10:04 PM, Alex Wang wrote:
After asking around, there are two solutions listed as follows:

1. Ask user to specify the number of handlers to be power of 2.  This
way, we can use the bitwise AND for modular operation.

2. Use the reciprocal division.  At time of setting the
'upcall_portids', we compute the reciprocal_value of the 'n_ids'.
      And the ovs_vport_find_portid() is changed to:

"""
@@ -445,13 +437,14 @@ int ovs_vport_get_upcall_portids(const struct
vport *vport,
  u32 ovs_vport_find_portid(const struct vport *p, struct sk_buff *skb)
  {
         struct vport_portids *ids;
+       u32 hash;
         ids = rcu_dereference_ovsl(p->upcall_portids);
         if (ids->n_ids == 1 && *ids->ids == 0)
                 return 0;
-       return ids->ids[skb_get_rxhash(skb) % ids->n_ids];
+       hash = skb_get_rxhash(skb);
+       return ids->ids[hash - ids->n_ids * reciprocal_div(hash,
ids->rn_ids)];
  }"""

We tend to take the second one, in that, we want to allow user to
flexibly configure the number of threads in userspace,
and the change of division to "one subtract, two multiplication and one
shift" saves the cpu cycles.  (There may be better
way of using reciprocal_div() than the one I gave)

I agree. If this was the fast path I would have suggested to go with
(1) but given we only hit this frequently in exception cases the
added flexibility in defining an arbitrary number of threads seems
worth it.
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to