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 |   32 ++++++++++----------------------
 1 file changed, 10 insertions(+), 22 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 409c9bf..072ed5d 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 *);
@@ -560,7 +559,7 @@ create_dp_netdev(const char *name, const struct dpif_class 
*class,
         return error;
     }
 
-    ovs_mutex_init(&dp->emc_mutex);
+    ovs_mutex_init_recursive(&dp->emc_mutex);
     emc_cache_init(&dp->flow_cache);
 
     *dpp = dp;
@@ -1799,14 +1798,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));
     }
 }
 
@@ -2404,18 +2404,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