On Fri, Apr 07, 2017 at 04:12:50PM +0300, Roi Dayan wrote:
> From: Paul Blakey <pa...@mellanox.com>
> 
> Add a new configuration option - hw-offload that enables netdev
> flow api. Enabling this option will allow offloading flows
> using netdev implementation instead of the kernel datapath.
> This configuration option defaults to false - disabled.
> 
> Signed-off-by: Paul Blakey <pa...@mellanox.com>
> Reviewed-by: Roi Dayan <r...@mellanox.com>
> Reviewed-by: Simon Horman <simon.hor...@netronome.com>
> ---
>  lib/netdev.c         | 30 ++++++++++++++++++++++++++++++
>  lib/netdev.h         |  2 ++
>  vswitchd/bridge.c    |  1 +
>  vswitchd/vswitch.xml | 11 +++++++++++
>  4 files changed, 44 insertions(+)
> 
> diff --git a/lib/netdev.c b/lib/netdev.c
> index f7b80b2..977844a 100644
> --- a/lib/netdev.c
> +++ b/lib/netdev.c
> @@ -2092,7 +2092,37 @@ netdev_init_flow_api(struct netdev *netdev)
>  {
>      const struct netdev_class *class = netdev->netdev_class;
>  
> +    if (!netdev_flow_api_enabled) {
> +        return EOPNOTSUPP;
> +    }
> +
>      return (class->init_flow_api
>              ? class->init_flow_api(netdev)
>              : EOPNOTSUPP);
>  }
> +
> +bool netdev_flow_api_enabled = false;
> +
> +#ifdef __linux__
> +void
> +netdev_set_flow_api_enabled(const struct smap *ovs_other_config)
> +{
> +    if (smap_get_bool(ovs_other_config, "hw-offload", false)) {
> +        static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
> +
> +        if (ovsthread_once_start(&once)) {
> +            netdev_flow_api_enabled = true;
> +
> +            VLOG_INFO("netdev: Flow API Enabled");
> +
> +            ovsthread_once_done(&once);
> +        }
> +    }
> +}
> +#else
> +void
> +netdev_set_flow_api_enabled(const struct smap *ovs_other_config OVS_UNUSED)
> +{
> +    netdev_flow_api_enabled = false;
> +}
> +#endif
> diff --git a/lib/netdev.h b/lib/netdev.h
> index 6d2db7d..e2d1799 100644
> --- a/lib/netdev.h
> +++ b/lib/netdev.h
> @@ -178,6 +178,8 @@ int netdev_flow_get(struct netdev *, struct match *, 
> struct nlattr **actions,
>  int netdev_flow_del(struct netdev *, const ovs_u128 *,
>                      struct dpif_flow_stats *);
>  int netdev_init_flow_api(struct netdev *);
> +extern bool netdev_flow_api_enabled;
> +void netdev_set_flow_api_enabled(const struct smap *ovs_other_config);
>  
>  /* native tunnel APIs */
>  /* Structure to pass parameters required to build a tunnel header. */
> diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
> index 867a26d..0f65858 100644
> --- a/vswitchd/bridge.c
> +++ b/vswitchd/bridge.c
> @@ -2953,6 +2953,7 @@ bridge_run(void)
>      cfg = ovsrec_open_vswitch_first(idl);
>  
>      if (cfg) {
> +        netdev_set_flow_api_enabled(&cfg->other_config);
>          dpdk_init(&cfg->other_config);
>      }
>  
> diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
> index 14297bf..de86049 100644
> --- a/vswitchd/vswitch.xml
> +++ b/vswitchd/vswitch.xml
> @@ -170,6 +170,17 @@
>          <p>
>            The default is 10000.
>          </p>
> +    </column>
> +
> +      <column name="other_config" key="hw-offload"
> +              type='{"type": "boolean"}'>
> +        <p>
> +          Set this value to <code>true</code> to enable netdev flow offload.
> +        </p>
> +        <p>
> +          The default value is <code>false</code>. Changing this value 
> requires
> +          restarting the daemon
> +        </p>


Since this is a compile time feature, I think somehow we need to 
document that it's only available on Linux. Something like:

Currently Open vSwitch supports hardware offloading on
Linux systems.  On other systems, this value is ignored.



This looks better to me:

---8<---
diff --git a/lib/netdev.c b/lib/netdev.c
index 64f5e85..4b5f1990 100644
--- a/lib/netdev.c
+++ b/lib/netdev.c
@@ -2330,13 +2330,13 @@ netdev_ports_flow_init(void)
 }
 
 void
-netdev_set_flow_api_enabled(const struct smap *ovs_other_config)
+netdev_set_flow_api_enabled(bool enabled)
 {
     if (!netdev_flow_api_supported) {
         return;
     }
 
-    if (smap_get_bool(ovs_other_config, "hw-offload", false)) {
+    if (enabled) {
         static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
 
         if (ovsthread_once_start(&once)) {
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 0f65858..18bbeb6 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -2953,7 +2953,8 @@ bridge_run(void)
     cfg = ovsrec_open_vswitch_first(idl);
 
     if (cfg) {
-        netdev_set_flow_api_enabled(&cfg->other_config);
+        netdev_set_flow_api_enabled(smap_get_bool(&cfg->other_config,
+                                    "hw-offload", false));
         dpdk_init(&cfg->other_config);
     }
---8<---



Also that it's exporting a variable, so maybe this would be better:
(compile tested on Linux only)


---8<---
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index acce90e..0adc9c7 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -1088,7 +1088,7 @@ dpif_netlink_flow_flush(struct dpif *dpif_)
     flow.cmd = OVS_FLOW_CMD_DEL;
     flow.dp_ifindex = dpif->dp_ifindex;
 
-    if (netdev_flow_api_enabled) {
+    if (netdev_is_flow_api_enabled()) {
         netdev_ports_flow_flush(DPIF_HMAP_KEY(dpif_));
     }
 
@@ -1428,7 +1428,7 @@ dpif_netlink_get_dump_type(char *str) {
     if (!str || !strcmp(str, "ovs") || !strcmp(str, "dpctl")) {
         type |= DUMP_OVS_FLOWS;
     }
-    if ((netdev_flow_api_enabled && !str)
+    if ((netdev_is_flow_api_enabled() && !str)
         || (str && (!strcmp(str, "offloaded") || !strcmp(str, "dpctl")))) {
         type |= DUMP_OFFLOADED_FLOWS;
     }
@@ -2207,7 +2207,7 @@ dpif_netlink_operate(struct dpif *dpif_, struct dpif_op 
**ops, size_t n_ops)
     int i = 0;
     int err = 0;
 
-    if (netdev_flow_api_enabled) {
+    if (netdev_is_flow_api_enabled()) {
         while (n_ops > 0) {
             count = 0;
 
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index a48c6d9..41d959d 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -2052,7 +2052,7 @@ netdev_linux_set_policing(struct netdev *netdev_,
     int error;
     int ifindex;
 
-    if (netdev_flow_api_enabled) {
+    if (netdev_is_flow_api_enabled()) {
         if (kbits_rate) {
             VLOG_WARN_RL(&rl, "%s: policing with offload isn't supported",
                          netdev_name);
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index d310771..5f5e571 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -796,7 +796,7 @@ netdev_vport_get_ifindex__(const struct netdev *netdev_)
 static int
 netdev_vport_get_ifindex(const struct netdev *netdev_)
 {
-    if (netdev_flow_api_enabled)
+    if (netdev_is_flow_api_enabled())
         return netdev_vport_get_ifindex__(netdev_);
     else
         return -EOPNOTSUPP;
diff --git a/lib/netdev.c b/lib/netdev.c
index f020d46..64f5e85 100644
--- a/lib/netdev.c
+++ b/lib/netdev.c
@@ -95,6 +95,15 @@ struct netdev_registered_class {
     struct ovs_refcount refcnt;
 };
 
+
+#ifdef __linux__
+static bool netdev_flow_api_supported = true;
+#else
+static bool netdev_flow_api_supported = false;
+#endif
+
+static bool netdev_flow_api_enabled = false;
+
 /* This is set pretty low because we probably won't learn anything from the
  * additional log messages. */
 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
@@ -2090,12 +2099,18 @@ netdev_flow_del(struct netdev *netdev, const ovs_u128 
*ufid,
             : EOPNOTSUPP);
 }
 
+bool
+netdev_is_flow_api_enabled(void)
+{
+    return netdev_flow_api_enabled;
+}
+
 int
 netdev_init_flow_api(struct netdev *netdev)
 {
     const struct netdev_class *class = netdev->netdev_class;
 
-    if (!netdev_flow_api_enabled) {
+    if (!netdev_is_flow_api_enabled()) {
         return EOPNOTSUPP;
     }
 
@@ -2302,9 +2317,6 @@ netdev_ports_flow_get(const void *obj, struct match 
*match,
     return ENOENT;
 }
 
-bool netdev_flow_api_enabled = false;
-
-#ifdef __linux__
 static void
 netdev_ports_flow_init(void)
 {
@@ -2320,6 +2332,10 @@ netdev_ports_flow_init(void)
 void
 netdev_set_flow_api_enabled(const struct smap *ovs_other_config)
 {
+    if (!netdev_flow_api_supported) {
+        return;
+    }
+
     if (smap_get_bool(ovs_other_config, "hw-offload", false)) {
         static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
 
@@ -2337,10 +2353,3 @@ netdev_set_flow_api_enabled(const struct smap 
*ovs_other_config)
         }
     }
 }
-#else
-void
-netdev_set_flow_api_enabled(const struct smap *ovs_other_config OVS_UNUSED)
-{
-    netdev_flow_api_enabled = false;
-}
-#endif
diff --git a/lib/netdev.h b/lib/netdev.h
index 00cbbdf..5b0a475 100644
--- a/lib/netdev.h
+++ b/lib/netdev.h
@@ -178,7 +178,7 @@ int netdev_flow_get(struct netdev *, struct match *, struct 
nlattr **actions,
 int netdev_flow_del(struct netdev *, const ovs_u128 *,
                     struct dpif_flow_stats *);
 int netdev_init_flow_api(struct netdev *);
-extern bool netdev_flow_api_enabled;
+bool netdev_is_flow_api_enabled(void);
 void netdev_set_flow_api_enabled(const struct smap *ovs_other_config);
 
 struct dpif_port;
---8<---

Thanks,

-- 
Flavio

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to