Re: [RFC PATCH net-next v5 2/4] net: Introduce generic bypass module

2018-04-06 Thread Samudrala, Sridhar

On 4/6/2018 5:57 AM, Jiri Pirko wrote:

Thu, Apr 05, 2018 at 11:08:21PM CEST, sridhar.samudr...@intel.com wrote:

This provides a generic interface for paravirtual drivers to listen
for netdev register/unregister/link change events from pci ethernet
devices with the same MAC and takeover their datapath. The notifier and
event handling code is based on the existing netvsc implementation. A
paravirtual driver can use this module by registering a set of ops and
each instance of the device when it is probed.

Signed-off-by: Sridhar Samudrala 
---
include/net/bypass.h |  80 ++
net/Kconfig  |  18 +++
net/core/Makefile|   1 +
net/core/bypass.c| 406 +++
4 files changed, 505 insertions(+)
create mode 100644 include/net/bypass.h
create mode 100644 net/core/bypass.c

diff --git a/include/net/bypass.h b/include/net/bypass.h
new file mode 100644
index ..e2dd122f951a
--- /dev/null
+++ b/include/net/bypass.h
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, Intel Corporation. */
+
+#ifndef _NET_BYPASS_H
+#define _NET_BYPASS_H
+
+#include 
+
+struct bypass_ops {

Perhaps "net_bypass_" would be better prefix for this module structs
and functions. No strong opinion though.



+   int (*register_child)(struct net_device *bypass_netdev,
+ struct net_device *child_netdev);

We have master/slave upper/lower netdevices. This adds "child". Consider
using some existing names. Not sure if possible without loss of meaning.


OK. will change this to register_slave()





+   int (*join_child)(struct net_device *bypass_netdev,
+ struct net_device *child_netdev);
+   int (*unregister_child)(struct net_device *bypass_netdev,
+   struct net_device *child_netdev);
+   int (*release_child)(struct net_device *bypass_netdev,
+struct net_device *child_netdev);
+   int (*update_link)(struct net_device *bypass_netdev,
+  struct net_device *child_netdev);
+   rx_handler_result_t (*handle_frame)(struct sk_buff **pskb);
+};
+
+struct bypass_instance {
+   struct list_head list;
+   struct net_device __rcu *bypass_netdev;
+   struct bypass *bypass;
+};
+
+struct bypass {
+   struct list_head list;
+   const struct bypass_ops *ops;
+   const struct net_device_ops *netdev_ops;
+   struct list_head instance_list;
+   struct mutex lock;
+};
+
+#if IS_ENABLED(CONFIG_NET_BYPASS)
+
+struct bypass *bypass_register_driver(const struct bypass_ops *ops,
+ const struct net_device_ops *netdev_ops);
+void bypass_unregister_driver(struct bypass *bypass);
+
+int bypass_register_instance(struct bypass *bypass, struct net_device *dev);
+int bypass_unregister_instance(struct bypass *bypass, struct net_device
*dev);
+
+int bypass_unregister_child(struct net_device *child_netdev);
+
+#else
+
+static inline
+struct bypass *bypass_register_driver(const struct bypass_ops *ops,
+ const struct net_device_ops *netdev_ops)
+{
+   return NULL;
+}
+
+static inline void bypass_unregister_driver(struct bypass *bypass)
+{
+}
+
+static inline int bypass_register_instance(struct bypass *bypass,
+  struct net_device *dev)
+{
+   return 0;
+}
+
+static inline int bypass_unregister_instance(struct bypass *bypass,
+struct net_device *dev)
+{
+   return 0;
+}
+
+static inline int bypass_unregister_child(struct net_device *child_netdev)
+{
+   return 0;
+}
+
+#endif
+
+#endif /* _NET_BYPASS_H */
diff --git a/net/Kconfig b/net/Kconfig
index 0428f12c25c2..994445f4a96a 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -423,6 +423,24 @@ config MAY_USE_DEVLINK
  on MAY_USE_DEVLINK to ensure they do not cause link errors when
  devlink is a loadable module and the driver using it is built-in.

+config NET_BYPASS
+   tristate "Bypass interface"
+   ---help---
+ This provides a generic interface for paravirtual drivers to listen
+ for netdev register/unregister/link change events from pci ethernet
+ devices with the same MAC and takeover their datapath. This also
+ enables live migration of a VM with direct attached VF by failing
+ over to the paravirtual datapath when the VF is unplugged.
+
+config MAY_USE_BYPASS
+   tristate
+   default m if NET_BYPASS=m
+   default y if NET_BYPASS=y || NET_BYPASS=n
+   help
+ Drivers using the bypass infrastructure should have a dependency
+ on MAY_USE_BYPASS to ensure they do not cause link errors when
+ bypass is a loadable module and the driver using it is built-in.
+
endif   # if NET

# Used by archs to tell that they support BPF JIT compiler plus which 

Re: [RFC PATCH net-next v5 2/4] net: Introduce generic bypass module

2018-04-06 Thread Jiri Pirko
Thu, Apr 05, 2018 at 11:08:21PM CEST, sridhar.samudr...@intel.com wrote:
>This provides a generic interface for paravirtual drivers to listen
>for netdev register/unregister/link change events from pci ethernet
>devices with the same MAC and takeover their datapath. The notifier and
>event handling code is based on the existing netvsc implementation. A
>paravirtual driver can use this module by registering a set of ops and
>each instance of the device when it is probed.
>
>Signed-off-by: Sridhar Samudrala 
>---
> include/net/bypass.h |  80 ++
> net/Kconfig  |  18 +++
> net/core/Makefile|   1 +
> net/core/bypass.c| 406 +++
> 4 files changed, 505 insertions(+)
> create mode 100644 include/net/bypass.h
> create mode 100644 net/core/bypass.c
>
>diff --git a/include/net/bypass.h b/include/net/bypass.h
>new file mode 100644
>index ..e2dd122f951a
>--- /dev/null
>+++ b/include/net/bypass.h
>@@ -0,0 +1,80 @@
>+// SPDX-License-Identifier: GPL-2.0
>+/* Copyright (c) 2018, Intel Corporation. */
>+
>+#ifndef _NET_BYPASS_H
>+#define _NET_BYPASS_H
>+
>+#include 
>+
>+struct bypass_ops {

Perhaps "net_bypass_" would be better prefix for this module structs
and functions. No strong opinion though.


>+  int (*register_child)(struct net_device *bypass_netdev,
>+struct net_device *child_netdev);

We have master/slave upper/lower netdevices. This adds "child". Consider
using some existing names. Not sure if possible without loss of meaning.


>+  int (*join_child)(struct net_device *bypass_netdev,
>+struct net_device *child_netdev);
>+  int (*unregister_child)(struct net_device *bypass_netdev,
>+  struct net_device *child_netdev);
>+  int (*release_child)(struct net_device *bypass_netdev,
>+   struct net_device *child_netdev);
>+  int (*update_link)(struct net_device *bypass_netdev,
>+ struct net_device *child_netdev);
>+  rx_handler_result_t (*handle_frame)(struct sk_buff **pskb);
>+};
>+
>+struct bypass_instance {
>+  struct list_head list;
>+  struct net_device __rcu *bypass_netdev;
>+  struct bypass *bypass;
>+};
>+
>+struct bypass {
>+  struct list_head list;
>+  const struct bypass_ops *ops;
>+  const struct net_device_ops *netdev_ops;
>+  struct list_head instance_list;
>+  struct mutex lock;
>+};
>+
>+#if IS_ENABLED(CONFIG_NET_BYPASS)
>+
>+struct bypass *bypass_register_driver(const struct bypass_ops *ops,
>+const struct net_device_ops *netdev_ops);
>+void bypass_unregister_driver(struct bypass *bypass);
>+
>+int bypass_register_instance(struct bypass *bypass, struct net_device *dev);
>+int bypass_unregister_instance(struct bypass *bypass, struct net_device   
>*dev);
>+
>+int bypass_unregister_child(struct net_device *child_netdev);
>+
>+#else
>+
>+static inline
>+struct bypass *bypass_register_driver(const struct bypass_ops *ops,
>+const struct net_device_ops *netdev_ops)
>+{
>+  return NULL;
>+}
>+
>+static inline void bypass_unregister_driver(struct bypass *bypass)
>+{
>+}
>+
>+static inline int bypass_register_instance(struct bypass *bypass,
>+ struct net_device *dev)
>+{
>+  return 0;
>+}
>+
>+static inline int bypass_unregister_instance(struct bypass *bypass,
>+   struct net_device *dev)
>+{
>+  return 0;
>+}
>+
>+static inline int bypass_unregister_child(struct net_device *child_netdev)
>+{
>+  return 0;
>+}
>+
>+#endif
>+
>+#endif /* _NET_BYPASS_H */
>diff --git a/net/Kconfig b/net/Kconfig
>index 0428f12c25c2..994445f4a96a 100644
>--- a/net/Kconfig
>+++ b/net/Kconfig
>@@ -423,6 +423,24 @@ config MAY_USE_DEVLINK
> on MAY_USE_DEVLINK to ensure they do not cause link errors when
> devlink is a loadable module and the driver using it is built-in.
> 
>+config NET_BYPASS
>+  tristate "Bypass interface"
>+  ---help---
>+This provides a generic interface for paravirtual drivers to listen
>+for netdev register/unregister/link change events from pci ethernet
>+devices with the same MAC and takeover their datapath. This also
>+enables live migration of a VM with direct attached VF by failing
>+over to the paravirtual datapath when the VF is unplugged.
>+
>+config MAY_USE_BYPASS
>+  tristate
>+  default m if NET_BYPASS=m
>+  default y if NET_BYPASS=y || NET_BYPASS=n
>+  help
>+Drivers using the bypass infrastructure should have a dependency
>+on MAY_USE_BYPASS to ensure they do not cause link errors when
>+bypass is a loadable module and the driver using it is built-in.
>+
> endif   # if NET
> 
> # Used by archs to tell that they support BPF JIT compiler 

[RFC PATCH net-next v5 2/4] net: Introduce generic bypass module

2018-04-05 Thread Sridhar Samudrala
This provides a generic interface for paravirtual drivers to listen
for netdev register/unregister/link change events from pci ethernet
devices with the same MAC and takeover their datapath. The notifier and
event handling code is based on the existing netvsc implementation. A
paravirtual driver can use this module by registering a set of ops and
each instance of the device when it is probed.

Signed-off-by: Sridhar Samudrala 
---
 include/net/bypass.h |  80 ++
 net/Kconfig  |  18 +++
 net/core/Makefile|   1 +
 net/core/bypass.c| 406 +++
 4 files changed, 505 insertions(+)
 create mode 100644 include/net/bypass.h
 create mode 100644 net/core/bypass.c

diff --git a/include/net/bypass.h b/include/net/bypass.h
new file mode 100644
index ..e2dd122f951a
--- /dev/null
+++ b/include/net/bypass.h
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, Intel Corporation. */
+
+#ifndef _NET_BYPASS_H
+#define _NET_BYPASS_H
+
+#include 
+
+struct bypass_ops {
+   int (*register_child)(struct net_device *bypass_netdev,
+ struct net_device *child_netdev);
+   int (*join_child)(struct net_device *bypass_netdev,
+ struct net_device *child_netdev);
+   int (*unregister_child)(struct net_device *bypass_netdev,
+   struct net_device *child_netdev);
+   int (*release_child)(struct net_device *bypass_netdev,
+struct net_device *child_netdev);
+   int (*update_link)(struct net_device *bypass_netdev,
+  struct net_device *child_netdev);
+   rx_handler_result_t (*handle_frame)(struct sk_buff **pskb);
+};
+
+struct bypass_instance {
+   struct list_head list;
+   struct net_device __rcu *bypass_netdev;
+   struct bypass *bypass;
+};
+
+struct bypass {
+   struct list_head list;
+   const struct bypass_ops *ops;
+   const struct net_device_ops *netdev_ops;
+   struct list_head instance_list;
+   struct mutex lock;
+};
+
+#if IS_ENABLED(CONFIG_NET_BYPASS)
+
+struct bypass *bypass_register_driver(const struct bypass_ops *ops,
+ const struct net_device_ops *netdev_ops);
+void bypass_unregister_driver(struct bypass *bypass);
+
+int bypass_register_instance(struct bypass *bypass, struct net_device *dev);
+int bypass_unregister_instance(struct bypass *bypass, struct net_device
*dev);
+
+int bypass_unregister_child(struct net_device *child_netdev);
+
+#else
+
+static inline
+struct bypass *bypass_register_driver(const struct bypass_ops *ops,
+ const struct net_device_ops *netdev_ops)
+{
+   return NULL;
+}
+
+static inline void bypass_unregister_driver(struct bypass *bypass)
+{
+}
+
+static inline int bypass_register_instance(struct bypass *bypass,
+  struct net_device *dev)
+{
+   return 0;
+}
+
+static inline int bypass_unregister_instance(struct bypass *bypass,
+struct net_device *dev)
+{
+   return 0;
+}
+
+static inline int bypass_unregister_child(struct net_device *child_netdev)
+{
+   return 0;
+}
+
+#endif
+
+#endif /* _NET_BYPASS_H */
diff --git a/net/Kconfig b/net/Kconfig
index 0428f12c25c2..994445f4a96a 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -423,6 +423,24 @@ config MAY_USE_DEVLINK
  on MAY_USE_DEVLINK to ensure they do not cause link errors when
  devlink is a loadable module and the driver using it is built-in.
 
+config NET_BYPASS
+   tristate "Bypass interface"
+   ---help---
+ This provides a generic interface for paravirtual drivers to listen
+ for netdev register/unregister/link change events from pci ethernet
+ devices with the same MAC and takeover their datapath. This also
+ enables live migration of a VM with direct attached VF by failing
+ over to the paravirtual datapath when the VF is unplugged.
+
+config MAY_USE_BYPASS
+   tristate
+   default m if NET_BYPASS=m
+   default y if NET_BYPASS=y || NET_BYPASS=n
+   help
+ Drivers using the bypass infrastructure should have a dependency
+ on MAY_USE_BYPASS to ensure they do not cause link errors when
+ bypass is a loadable module and the driver using it is built-in.
+
 endif   # if NET
 
 # Used by archs to tell that they support BPF JIT compiler plus which flavour.
diff --git a/net/core/Makefile b/net/core/Makefile
index 6dbbba8c57ae..a9727ed1c8fc 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -30,3 +30,4 @@ obj-$(CONFIG_DST_CACHE) += dst_cache.o
 obj-$(CONFIG_HWBM) += hwbm.o
 obj-$(CONFIG_NET_DEVLINK) += devlink.o
 obj-$(CONFIG_GRO_CELLS) += gro_cells.o
+obj-$(CONFIG_NET_BYPASS) += bypass.o
diff --git a/net/core/bypass.c b/net/core/bypass.c
new file