prevent-traceback.patch 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. commit d4d1107c3a49a4dadf6dc8ac55d6fefa25a8e06a
  2. Author: Alexei Starovoitov <ast@plumgrid.com>
  3. Date: Wed Oct 16 15:28:23 2013 -0700
  4. cherry-pick 8e04c6e10c28e42c715eb9fef749554c123bddbc
  5. diff --git a/AUTHORS b/AUTHORS
  6. index 2d29e66..7a62704 100644
  7. --- a/AUTHORS
  8. +++ b/AUTHORS
  9. @@ -2,6 +2,8 @@ The following people, in alphabetical order, have either authored or
  10. signed off on commits in the Open vSwitch version control repository.
  11. Aaron Rosen arosen@clemson.edu
  12. +Alexandru Copot alex.mihai.c@gmail.com
  13. +Alexei Starovoitov ast@plumgrid.com
  14. Alexey I. Froloff raorn@altlinux.org
  15. Alex Wang alexw@nicira.com
  16. Andrew Evans aevans@nicira.com
  17. diff --git a/datapath/dp_notify.c b/datapath/dp_notify.c
  18. index 847f611..a973623 100644
  19. --- a/datapath/dp_notify.c
  20. +++ b/datapath/dp_notify.c
  21. @@ -66,8 +66,7 @@ void ovs_dp_notify_wq(struct work_struct *work)
  22. continue;
  23. netdev_vport = netdev_vport_priv(vport);
  24. - if (netdev_vport->dev->reg_state == NETREG_UNREGISTERED ||
  25. - netdev_vport->dev->reg_state == NETREG_UNREGISTERING)
  26. + if (!(ovs_netdev_get_vport(netdev_vport->dev)))
  27. dp_detach_port_notify(vport);
  28. }
  29. }
  30. @@ -89,6 +88,10 @@ static int dp_device_event(struct notifier_block *unused, unsigned long event,
  31. return NOTIFY_DONE;
  32. if (event == NETDEV_UNREGISTER) {
  33. + /* upper_dev_unlink and decrement promisc immediately */
  34. + ovs_netdev_detach_dev(vport);
  35. +
  36. + /* schedule vport destroy, dev_put and genl notification */
  37. ovs_net = net_generic(dev_net(dev), ovs_net_id);
  38. queue_work(&ovs_net->dp_notify_work);
  39. }
  40. diff --git a/datapath/linux/compat/include/linux/netdevice.h b/datapath/linux/compat/include/linux/netdevice.h
  41. index 4e2b7f5..908ed86 100644
  42. --- a/datapath/linux/compat/include/linux/netdevice.h
  43. +++ b/datapath/linux/compat/include/linux/netdevice.h
  44. @@ -118,6 +118,11 @@ static inline void netdev_upper_dev_unlink(struct net_device *dev,
  45. struct net_device *upper_dev)
  46. {
  47. }
  48. +
  49. +static inline struct net_device *netdev_master_upper_dev_get(struct net_device *dev)
  50. +{
  51. + return NULL;
  52. +}
  53. #endif
  54. #endif
  55. diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c
  56. index 215a47e..0c9f603 100644
  57. --- a/datapath/vport-netdev.c
  58. +++ b/datapath/vport-netdev.c
  59. @@ -201,16 +201,27 @@ static void free_port_rcu(struct rcu_head *rcu)
  60. ovs_vport_free(vport_from_priv(netdev_vport));
  61. }
  62. -static void netdev_destroy(struct vport *vport)
  63. +void ovs_netdev_detach_dev(struct vport *vport)
  64. {
  65. struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
  66. - netdev_exit();
  67. - rtnl_lock();
  68. + ASSERT_RTNL();
  69. netdev_vport->dev->priv_flags &= ~IFF_OVS_DATAPATH;
  70. netdev_rx_handler_unregister(netdev_vport->dev);
  71. - netdev_upper_dev_unlink(netdev_vport->dev, get_dpdev(vport->dp));
  72. + netdev_upper_dev_unlink(netdev_vport->dev,
  73. + netdev_master_upper_dev_get(netdev_vport->dev));
  74. dev_set_promiscuity(netdev_vport->dev, -1);
  75. +}
  76. +
  77. +static void netdev_destroy(struct vport *vport)
  78. +{
  79. + struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
  80. +
  81. + netdev_exit();
  82. +
  83. + rtnl_lock();
  84. + if (ovs_netdev_get_vport(netdev_vport->dev))
  85. + ovs_netdev_detach_dev(vport);
  86. rtnl_unlock();
  87. call_rcu(&netdev_vport->rcu, free_port_rcu);
  88. diff --git a/datapath/vport-netdev.h b/datapath/vport-netdev.h
  89. index dd298b5..8df01c1 100644
  90. --- a/datapath/vport-netdev.h
  91. +++ b/datapath/vport-netdev.h
  92. @@ -39,5 +39,6 @@ netdev_vport_priv(const struct vport *vport)
  93. }
  94. const char *ovs_netdev_get_name(const struct vport *);
  95. +void ovs_netdev_detach_dev(struct vport *);
  96. #endif /* vport_netdev.h */