net/failsafe: support flow API isolation mode
authorGaetan Rivet <gaetan.rivet@6wind.com>
Tue, 18 Jul 2017 12:48:22 +0000 (14:48 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 19 Jul 2017 13:25:43 +0000 (16:25 +0300)
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
drivers/net/failsafe/failsafe_ether.c
drivers/net/failsafe/failsafe_flow.c
drivers/net/failsafe/failsafe_private.h

index d205f61..a3a8cce 100644 (file)
@@ -73,6 +73,28 @@ fs_flow_complain(struct rte_flow_error *error)
        return -err;
 }
 
+static int
+eth_dev_flow_isolate_set(struct rte_eth_dev *dev,
+                        struct sub_device *sdev)
+{
+       struct rte_flow_error ferror;
+       int ret;
+
+       if (!PRIV(dev)->flow_isolated) {
+               DEBUG("Flow isolation already disabled");
+       } else {
+               DEBUG("Enabling flow isolation");
+               ret = rte_flow_isolate(PORT_ID(sdev),
+                                      PRIV(dev)->flow_isolated,
+                                      &ferror);
+               if (ret) {
+                       fs_flow_complain(&ferror);
+                       return ret;
+               }
+       }
+       return 0;
+}
+
 static int
 fs_eth_dev_conf_apply(struct rte_eth_dev *dev,
                struct sub_device *sdev)
@@ -334,9 +356,17 @@ failsafe_eth_dev_state_sync(struct rte_eth_dev *dev)
        if (PRIV(dev)->state < DEV_ACTIVE)
                return 0;
        inactive = 0;
-       FOREACH_SUBDEV(sdev, i, dev)
-               if (sdev->state == DEV_PROBED)
+       FOREACH_SUBDEV(sdev, i, dev) {
+               if (sdev->state == DEV_PROBED) {
                        inactive |= UINT32_C(1) << i;
+                       ret = eth_dev_flow_isolate_set(dev, sdev);
+                       if (ret) {
+                               ERROR("Could not apply configuration to sub_device %d",
+                                     i);
+                               goto err_remove;
+                       }
+               }
+       }
        ret = dev->dev_ops->dev_configure(dev);
        if (ret)
                goto err_remove;
index 0098672..153ceee 100644 (file)
@@ -206,10 +206,39 @@ fs_flow_query(struct rte_eth_dev *dev,
        return -1;
 }
 
+static int
+fs_flow_isolate(struct rte_eth_dev *dev,
+               int set,
+               struct rte_flow_error *error)
+{
+       struct sub_device *sdev;
+       uint8_t i;
+       int ret;
+
+       FOREACH_SUBDEV(sdev, i, dev) {
+               if (sdev->state < DEV_PROBED)
+                       continue;
+               DEBUG("Calling rte_flow_isolate on sub_device %d", i);
+               if (PRIV(dev)->flow_isolated != sdev->flow_isolated)
+                       WARN("flow isolation mode of sub_device %d in incoherent state.",
+                               i);
+               ret = rte_flow_isolate(PORT_ID(sdev), set, error);
+               if (ret) {
+                       ERROR("Operation rte_flow_isolate failed for sub_device %d"
+                             " with error %d", i, ret);
+                       return ret;
+               }
+               sdev->flow_isolated = set;
+       }
+       PRIV(dev)->flow_isolated = set;
+       return 0;
+}
+
 const struct rte_flow_ops fs_flow_ops = {
        .validate = fs_flow_validate,
        .create = fs_flow_create,
        .destroy = fs_flow_destroy,
        .flush = fs_flow_flush,
        .query = fs_flow_query,
+       .isolate = fs_flow_isolate,
 };
index 2c52d2b..0361cf4 100644 (file)
@@ -108,6 +108,8 @@ struct sub_device {
        struct rte_eth_dev *fs_dev;
        /* flag calling for recollection */
        volatile unsigned int remove:1;
+       /* flow isolation state */
+       int flow_isolated:1;
 };
 
 struct fs_priv {
@@ -139,6 +141,8 @@ struct fs_priv {
         */
        enum dev_state state;
        unsigned int pending_alarm:1; /* An alarm is pending */
+       /* flow isolation state */
+       int flow_isolated:1;
 };
 
 /* MISC */