net/failsafe: fix hotplug races
[dpdk.git] / drivers / net / failsafe / failsafe_flow.c
index 4d18e8e..ec8c909 100644 (file)
@@ -55,6 +55,7 @@ fs_flow_validate(struct rte_eth_dev *dev,
        uint8_t i;
        int ret;
 
+       fs_lock(dev, 0);
        FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
                DEBUG("Calling rte_flow_validate on sub_device %d", i);
                ret = rte_flow_validate(PORT_ID(sdev),
@@ -62,9 +63,11 @@ fs_flow_validate(struct rte_eth_dev *dev,
                if ((ret = fs_err(sdev, ret))) {
                        ERROR("Operation rte_flow_validate failed for sub_device %d"
                              " with error %d", i, ret);
+                       fs_unlock(dev, 0);
                        return ret;
                }
        }
+       fs_unlock(dev, 0);
        return 0;
 }
 
@@ -79,6 +82,7 @@ fs_flow_create(struct rte_eth_dev *dev,
        struct rte_flow *flow;
        uint8_t i;
 
+       fs_lock(dev, 0);
        flow = fs_flow_allocate(attr, patterns, actions);
        FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
                flow->flows[i] = rte_flow_create(PORT_ID(sdev),
@@ -90,6 +94,7 @@ fs_flow_create(struct rte_eth_dev *dev,
                }
        }
        TAILQ_INSERT_TAIL(&PRIV(dev)->flow_list, flow, next);
+       fs_unlock(dev, 0);
        return flow;
 err:
        FOREACH_SUBDEV(sdev, i, dev) {
@@ -98,6 +103,7 @@ err:
                                flow->flows[i], error);
        }
        fs_flow_release(&flow);
+       fs_unlock(dev, 0);
        return NULL;
 }
 
@@ -115,6 +121,7 @@ fs_flow_destroy(struct rte_eth_dev *dev,
                return -EINVAL;
        }
        ret = 0;
+       fs_lock(dev, 0);
        FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
                int local_ret;
 
@@ -131,6 +138,7 @@ fs_flow_destroy(struct rte_eth_dev *dev,
        }
        TAILQ_REMOVE(&PRIV(dev)->flow_list, flow, next);
        fs_flow_release(&flow);
+       fs_unlock(dev, 0);
        return ret;
 }
 
@@ -144,12 +152,14 @@ fs_flow_flush(struct rte_eth_dev *dev,
        uint8_t i;
        int ret;
 
+       fs_lock(dev, 0);
        FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
                DEBUG("Calling rte_flow_flush on sub_device %d", i);
                ret = rte_flow_flush(PORT_ID(sdev), error);
                if ((ret = fs_err(sdev, ret))) {
                        ERROR("Operation rte_flow_flush failed for sub_device %d"
                              " with error %d", i, ret);
+                       fs_unlock(dev, 0);
                        return ret;
                }
        }
@@ -157,6 +167,7 @@ fs_flow_flush(struct rte_eth_dev *dev,
                TAILQ_REMOVE(&PRIV(dev)->flow_list, flow, next);
                fs_flow_release(&flow);
        }
+       fs_unlock(dev, 0);
        return 0;
 }
 
@@ -169,15 +180,19 @@ fs_flow_query(struct rte_eth_dev *dev,
 {
        struct sub_device *sdev;
 
+       fs_lock(dev, 0);
        sdev = TX_SUBDEV(dev);
        if (sdev != NULL) {
                int ret = rte_flow_query(PORT_ID(sdev),
                                         flow->flows[SUB_ID(sdev)],
                                         type, arg, error);
 
-               if ((ret = fs_err(sdev, ret)))
+               if ((ret = fs_err(sdev, ret))) {
+                       fs_unlock(dev, 0);
                        return ret;
+               }
        }
+       fs_unlock(dev, 0);
        WARN("No active sub_device to query about its flow");
        return -1;
 }
@@ -191,6 +206,7 @@ fs_flow_isolate(struct rte_eth_dev *dev,
        uint8_t i;
        int ret;
 
+       fs_lock(dev, 0);
        FOREACH_SUBDEV(sdev, i, dev) {
                if (sdev->state < DEV_PROBED)
                        continue;
@@ -202,11 +218,13 @@ fs_flow_isolate(struct rte_eth_dev *dev,
                if ((ret = fs_err(sdev, ret))) {
                        ERROR("Operation rte_flow_isolate failed for sub_device %d"
                              " with error %d", i, ret);
+                       fs_unlock(dev, 0);
                        return ret;
                }
                sdev->flow_isolated = set;
        }
        PRIV(dev)->flow_isolated = set;
+       fs_unlock(dev, 0);
        return 0;
 }