In multiqueue mode several pmd threads may process one
port, but different queues. Flow doesn't depend on queue.

So, while miss upcall processing, all threads (except first
for that port) will receive error = ENOSPC due to
ukey_install failure. Therefore they will not add the flow
to flow_table and will not insert it to exact match cache.

As a result all threads (except first for that port) will
always execute a miss.

Fix that by comparing ukeys not only by ufids but also
by pmd_ids.

Signed-off-by: Ilya Maximets <i.maxim...@samsung.com>
---
 ofproto/ofproto-dpif-upcall.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 440f9e9..38e03c5 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -286,7 +286,8 @@ static bool ukey_install_start(struct udpif *, struct 
udpif_key *ukey);
 static bool ukey_install_finish(struct udpif_key *ukey, int error);
 static bool ukey_install(struct udpif *udpif, struct udpif_key *ukey);
 static struct udpif_key *ukey_lookup(struct udpif *udpif,
-                                     const ovs_u128 *ufid);
+                                     const ovs_u128 *ufid,
+                                     const unsigned pmd_id);
 static int ukey_acquire(struct udpif *, const struct dpif_flow *,
                         struct udpif_key **result, int *error);
 static void ukey_delete__(struct udpif_key *);
@@ -1141,7 +1142,8 @@ process_upcall(struct udpif *udpif, struct upcall *upcall,
             }
             if (actions_len == 0) {
                 /* Lookup actions in userspace cache. */
-                struct udpif_key *ukey = ukey_lookup(udpif, upcall->ufid);
+                struct udpif_key *ukey = ukey_lookup(udpif, upcall->ufid,
+                                                     upcall->pmd_id);
                 if (ukey) {
                     actions = ukey->actions->data;
                     actions_len = ukey->actions->size;
@@ -1324,14 +1326,14 @@ get_ufid_hash(const ovs_u128 *ufid)
 }
 
 static struct udpif_key *
-ukey_lookup(struct udpif *udpif, const ovs_u128 *ufid)
+ukey_lookup(struct udpif *udpif, const ovs_u128 *ufid, const unsigned pmd_id)
 {
     struct udpif_key *ukey;
     int idx = get_ufid_hash(ufid) % N_UMAPS;
     struct cmap *cmap = &udpif->ukeys[idx].cmap;
 
     CMAP_FOR_EACH_WITH_HASH (ukey, cmap_node, get_ufid_hash(ufid), cmap) {
-        if (ovs_u128_equals(&ukey->ufid, ufid)) {
+        if (ovs_u128_equals(&ukey->ufid, ufid) && ukey->pmd_id == pmd_id) {
             return ukey;
         }
     }
@@ -1488,7 +1490,7 @@ ukey_install_start(struct udpif *udpif, struct udpif_key 
*new_ukey)
     idx = new_ukey->hash % N_UMAPS;
     umap = &udpif->ukeys[idx];
     ovs_mutex_lock(&umap->mutex);
-    old_ukey = ukey_lookup(udpif, &new_ukey->ufid);
+    old_ukey = ukey_lookup(udpif, &new_ukey->ufid, new_ukey->pmd_id);
     if (old_ukey) {
         /* Uncommon case: A ukey is already installed with the same UFID. */
         if (old_ukey->key_len == new_ukey->key_len
@@ -1570,7 +1572,7 @@ ukey_acquire(struct udpif *udpif, const struct dpif_flow 
*flow,
     struct udpif_key *ukey;
     int retval;
 
-    ukey = ukey_lookup(udpif, &flow->ufid);
+    ukey = ukey_lookup(udpif, &flow->ufid, flow->pmd_id);
     if (ukey) {
         retval = ovs_mutex_trylock(&ukey->mutex);
     } else {
-- 
2.1.4

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

Reply via email to