Moves the registration of the RHEL specific OVS hook to the compat backport of netdev_rx_handler_register(). This moves the hook unregistration from the RCU callback to the netdev_destroy() callback directly.
This is purely cosmetic though, the RHEL hook is only used if the IFF_OVS_DATAPATH flag is present which was removed under RTNL protection before the RCU callback. Signed-off-by: Thomas Graf <tg...@redhat.com> --- datapath/linux/compat/include/linux/netdevice.h | 21 ++++++++++++++++++++- datapath/vport-netdev.c | 17 +---------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/datapath/linux/compat/include/linux/netdevice.h b/datapath/linux/compat/include/linux/netdevice.h index b051baf..90edb7d 100644 --- a/datapath/linux/compat/include/linux/netdevice.h +++ b/datapath/linux/compat/include/linux/netdevice.h @@ -20,6 +20,11 @@ struct net; #define to_net_dev(class) container_of(class, struct net_device, NETDEV_DEV_MEMBER) #endif +#ifdef HAVE_RHEL_OVS_HOOK +extern struct sk_buff *(*openvswitch_handle_frame_hook)(struct sk_buff *skb); +extern atomic_t nr_bridges; +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) static inline struct net *dev_net(const struct net_device *dev) @@ -84,19 +89,33 @@ extern int skb_checksum_help(struct sk_buff *skb, int); extern int skb_checksum_help(struct sk_buff *skb); #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) || \ + defined HAVE_RHEL_OVS_HOOK static inline int netdev_rx_handler_register(struct net_device *dev, void *rx_handler, void *rx_handler_data) { +#ifdef HAVE_RHEL_OVS_HOOK + rcu_assign_pointer(dev->ax25_ptr, rx_handler_data); + atomic_inc(&nr_bridges); + rcu_assign_pointer(openvswitch_handle_frame_hook, rx_handler_data); +#else if (dev->br_port) return -EBUSY; rcu_assign_pointer(dev->br_port, rx_handler_data); +#endif return 0; } static inline void netdev_rx_handler_unregister(struct net_device *dev) { +#ifdef HAVE_RHEL_OVS_HOOK + rcu_assign_pointer(dev->ax25_ptr, NULL); + + if (atomic_dec_and_test(&nr_bridges)) + rcu_assign_pointer(openvswitch_handle_frame_hook, NULL); +#else rcu_assign_pointer(dev->br_port, NULL); +#endif } #endif diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c index fe7e359..d043eae 100644 --- a/datapath/vport-netdev.c +++ b/datapath/vport-netdev.c @@ -46,9 +46,8 @@ MODULE_PARM_DESC(vlan_tso, "Enable TSO for VLAN packets"); #endif #ifdef HAVE_RHEL_OVS_HOOK -static atomic_t nr_bridges = ATOMIC_INIT(0); +atomic_t nr_bridges = ATOMIC_INIT(0); -extern struct sk_buff *(*openvswitch_handle_frame_hook)(struct sk_buff *skb); #endif static void netdev_port_receive(struct vport *vport, struct sk_buff *skb); @@ -171,16 +170,10 @@ static struct vport *netdev_create(const struct vport_parms *parms) } rtnl_lock(); -#ifdef HAVE_RHEL_OVS_HOOK - rcu_assign_pointer(netdev_vport->dev->ax25_ptr, vport); - atomic_inc(&nr_bridges); - rcu_assign_pointer(openvswitch_handle_frame_hook, netdev_frame_hook); -#else err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook, vport); if (err) goto error_unlock; -#endif dev_set_promiscuity(netdev_vport->dev, 1); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) @@ -192,9 +185,7 @@ static struct vport *netdev_create(const struct vport_parms *parms) netdev_init(); return vport; -#ifndef HAVE_RHEL_OVS_HOOK error_unlock: -#endif rtnl_unlock(); error_put: dev_put(netdev_vport->dev); @@ -209,12 +200,6 @@ static void free_port_rcu(struct rcu_head *rcu) struct netdev_vport *netdev_vport = container_of(rcu, struct netdev_vport, rcu); -#ifdef HAVE_RHEL_OVS_HOOK - rcu_assign_pointer(netdev_vport->dev->ax25_ptr, NULL); - - if (atomic_dec_and_test(&nr_bridges)) - rcu_assign_pointer(openvswitch_handle_frame_hook, NULL); -#endif dev_put(netdev_vport->dev); ovs_vport_free(vport_from_priv(netdev_vport)); } -- 1.8.3.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev