diff mbox

PANIC in vxlan <debugging now>

Message ID CAHA+R7N-FbNVSY-fjObfSrzc3UFMdAT-h-TPnX09EuA4R79U0g@mail.gmail.com
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

Cong Wang Jan. 17, 2014, 3:47 a.m. UTC
On Thu, Jan 16, 2014 at 6:03 PM, Jesse Brandeburg
<jesse.brandeburg@intel.com> wrote:
>
> It appears that the bug is in acaf4e70997f (net: vxlan: when lower dev
> unregisters remove vxlan dev as well).
>
> reverting that patch avoids the panic.  I wasn't able to see
> immediately what was wrong in the patch.

It seems vxlan pernet ops is run after loopback register.

Please try the attached (totally untested) patch?

Comments

Cong Wang Jan. 17, 2014, 4:24 a.m. UTC | #1
On Thu, Jan 16, 2014 at 7:47 PM, Cong Wang <cwang@twopensource.com> wrote:
> On Thu, Jan 16, 2014 at 6:03 PM, Jesse Brandeburg
> <jesse.brandeburg@intel.com> wrote:
>>
>> It appears that the bug is in acaf4e70997f (net: vxlan: when lower dev
>> unregisters remove vxlan dev as well).
>>
>> reverting that patch avoids the panic.  I wasn't able to see
>> immediately what was wrong in the patch.
>
> It seems vxlan pernet ops is run after loopback register.
>
> Please try the attached (totally untested) patch?

Never mind, I already verified it by myself.
A formal patch was just sent out.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index a2dee80..2812559 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2655,36 +2655,30 @@  static struct rtnl_link_ops vxlan_link_ops __read_mostly = {
 	.fill_info	= vxlan_fill_info,
 };
 
-static void vxlan_handle_lowerdev_unregister(struct vxlan_net *vn,
-					     struct net_device *dev)
-{
-	struct vxlan_dev *vxlan, *next;
-	LIST_HEAD(list_kill);
-
-	list_for_each_entry_safe(vxlan, next, &vn->vxlan_list, next) {
-		struct vxlan_rdst *dst = &vxlan->default_dst;
-
-		/* In case we created vxlan device with carrier
-		 * and we loose the carrier due to module unload
-		 * we also need to remove vxlan device. In other
-		 * cases, it's not necessary and remote_ifindex
-		 * is 0 here, so no matches.
-		 */
-		if (dst->remote_ifindex == dev->ifindex)
-			vxlan_dellink(vxlan->dev, &list_kill);
-	}
-
-	unregister_netdevice_many(&list_kill);
-}
-
 static int vxlan_lowerdev_event(struct notifier_block *unused,
 				unsigned long event, void *ptr)
 {
-	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
+	if (event == NETDEV_UNREGISTER) {
+		struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+		struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
+		struct vxlan_dev *vxlan, *next;
+		LIST_HEAD(list_kill);
+
+		list_for_each_entry_safe(vxlan, next, &vn->vxlan_list, next) {
+			struct vxlan_rdst *dst = &vxlan->default_dst;
+
+			/* In case we created vxlan device with carrier
+			 * and we loose the carrier due to module unload
+			 * we also need to remove vxlan device. In other
+			 * cases, it's not necessary and remote_ifindex
+			 * is 0 here, so no matches.
+			 */
+			if (dst->remote_ifindex == dev->ifindex)
+				vxlan_dellink(vxlan->dev, &list_kill);
+		}
 
-	if (event == NETDEV_UNREGISTER)
-		vxlan_handle_lowerdev_unregister(vn, dev);
+		unregister_netdevice_many(&list_kill);
+	}
 
 	return NOTIFY_DONE;
 }