dpif_netdev_execute may be called while doing upcall processing.
Since the context of the input port is not tracked upto this point, we
used the chared dp->emc_cache for packet execution.  Execution needs
to be able to pass the cache to recirculation code.

Typically the pmd threads use their own emc_cache, so there is little
value in using the shared emc_cache while processing recirculation
during packet execution.  Also, whenever the shared emc_cache was
already used while doing the upcall, the emc_mutex is already held,
and would be locked recursively in dpif_netdev_execute().  Rather than
changing the mutex to a recursive type, it seems more proper to not
use any emc_cache in dpif_netdev_execute.

Forthcoming new unit tests will fail with the current lock recursion.

Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>
---
 lib/dpif-netdev.c |   42 ++++++++++++++++++------------------------
 1 file changed, 18 insertions(+), 24 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 869fb55..846c329 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -380,10 +380,9 @@ static void dp_netdev_execute_actions(struct dp_netdev *dp,
                                       struct emc_cache *flow_cache,
                                       const struct nlattr *actions,
                                       size_t actions_len);
-static void dp_netdev_port_input(struct dp_netdev *dp,
-                                 struct emc_cache *flow_cache,
-                                 struct dpif_packet **packets, int cnt,
-                                 odp_port_t port_no);
+static void dp_netdev_input(struct dp_netdev *, struct emc_cache *,
+                            struct dpif_packet **, int cnt,
+                            struct pkt_metadata *);
 
 static void dp_netdev_set_pmd_threads(struct dp_netdev *, int n);
 static void dp_netdev_disable_upcall(struct dp_netdev *);
@@ -1176,6 +1175,10 @@ emc_insert(struct emc_cache *cache, const struct 
miniflow *mf, uint32_t hash,
     struct emc_entry *to_be_replaced = NULL;
     struct emc_entry *current_entry;
 
+    if (OVS_UNLIKELY(!cache)) {
+        return;
+    }
+
     EMC_FOR_EACH_POS_WITH_HASH(cache, current_entry, hash) {
         if (current_entry->hash == hash
             && miniflow_equal(&current_entry->mf.flow, mf)) {
@@ -1708,11 +1711,9 @@ dpif_netdev_execute(struct dpif *dpif, struct 
dpif_execute *execute)
     packet.ofpbuf = *execute->packet;
     pp = &packet;
 
-    ovs_mutex_lock(&dp->emc_mutex);
     dp_netdev_execute_actions(dp, &pp, 1, false, md,
-                              &dp->flow_cache, execute->actions,
+                              NULL, execute->actions,
                               execute->actions_len);
-    ovs_mutex_unlock(&dp->emc_mutex);
 
     /* Even though may_steal is set to false, some actions could modify or
      * reallocate the ofpbuf memory. We need to pass those changes to the
@@ -1799,14 +1800,15 @@ dp_netdev_process_rxq_port(struct dp_netdev *dp,
 
     error = netdev_rxq_recv(rxq, packets, &cnt);
     if (!error) {
-        dp_netdev_port_input(dp, flow_cache, packets, cnt, port->port_no);
+        struct pkt_metadata md = PKT_METADATA_INITIALIZER(port->port_no);
+
+        *recirc_depth_get() = 0;
+        dp_netdev_input(dp, flow_cache, packets, cnt, &md);
     } else if (error != EAGAIN && error != EOPNOTSUPP) {
-        static struct vlog_rate_limit rl
-            = VLOG_RATE_LIMIT_INIT(1, 5);
+        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
 
         VLOG_ERR_RL(&rl, "error receiving data from %s: %s",
-                    netdev_get_name(port->netdev),
-                    ovs_strerror(error));
+                    netdev_get_name(port->netdev), ovs_strerror(error));
     }
 }
 
@@ -2240,6 +2242,10 @@ emc_processing(struct dp_netdev *dp, struct emc_cache 
*flow_cache,
     size_t n_batches, i;
     size_t notfound_cnt = 0;
 
+    if (OVS_UNLIKELY(!flow_cache)) {
+        return cnt;
+    }
+
     n_batches = 0;
     miniflow_initialize(&key.flow, key.buf);
     for (i = 0; i < cnt; i++) {
@@ -2404,18 +2410,6 @@ dp_netdev_input(struct dp_netdev *dp, struct emc_cache 
*flow_cache,
     }
 }
 
-
-static void
-dp_netdev_port_input(struct dp_netdev *dp, struct emc_cache *flow_cache,
-                     struct dpif_packet **packets, int cnt, odp_port_t port_no)
-{
-    uint32_t *recirc_depth = recirc_depth_get();
-    struct pkt_metadata md = PKT_METADATA_INITIALIZER(port_no);
-
-    *recirc_depth = 0;
-    dp_netdev_input(dp, flow_cache, packets, cnt, &md);
-}
-
 struct dp_netdev_execute_aux {
     struct dp_netdev *dp;
     struct emc_cache *flow_cache;
-- 
1.7.10.4

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

Reply via email to