Re: [RFC PATCH net-next v5 2/4] net: Introduce generic bypass module
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 flavour. diff --git a/net/core/Ma
Re: [RFC PATCH net-next v5 2/4] net: Introduce generic bypass module
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 plus which flavour. >diff --git a