diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 511afe72af31fe92ba11e30cf706168d993625b2..39f8d0120104ce316bfe35c3f1977ec4e5af7379 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -161,10 +161,10 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
 
 	grp->nr_vlans--;
 
-	if (!grp->killall) {
-		vlan_group_set_device(grp, vlan_id, NULL);
+	vlan_group_set_device(grp, vlan_id, NULL);
+	if (!grp->killall)
 		synchronize_net();
-	}
+
 	unregister_netdevice_queue(dev, head);
 
 	/* If the group is now empty, kill off the group. */
@@ -184,34 +184,6 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
 	dev_put(real_dev);
 }
 
-void unregister_vlan_dev_alls(struct vlan_group *grp)
-{
-	LIST_HEAD(list);
-	int i;
-	struct net_device *vlandev;
-	struct vlan_group save;
-
-	memcpy(&save, grp, sizeof(save));
-	memset(&grp->vlan_devices_arrays, 0, sizeof(grp->vlan_devices_arrays));
-	grp->killall = 1;
-
-	synchronize_net();
-
-	/* Delete all VLANs for this dev. */
-	for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
-		vlandev = vlan_group_get_device(&save, i);
-		if (!vlandev)
-			continue;
-
-		unregister_vlan_dev(vlandev, &list);
-		if (grp->nr_vlans == 0)
-			break;
-	}
-	unregister_netdevice_many(&list);
-	for (i = 0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++)
-		kfree(save.vlan_devices_arrays[i]);
-}
-
 static void vlan_transfer_operstate(const struct net_device *dev,
 				    struct net_device *vlandev)
 {
@@ -456,6 +428,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 	struct vlan_group *grp;
 	int i, flgs;
 	struct net_device *vlandev;
+	LIST_HEAD(list);
 
 	if (is_vlan_dev(dev))
 		__vlan_device_event(dev, event);
@@ -553,7 +526,22 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 		break;
 
 	case NETDEV_UNREGISTER:
-		unregister_vlan_dev_alls(grp);
+		/* Delete all VLANs for this dev. */
+		grp->killall = 1;
+
+		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+			vlandev = vlan_group_get_device(grp, i);
+			if (!vlandev)
+				continue;
+
+			/* unregistration of last vlan destroys group, abort
+			 * afterwards */
+			if (grp->nr_vlans == 1)
+				i = VLAN_GROUP_ARRAY_LEN;
+
+			unregister_vlan_dev(vlandev, &list);
+		}
+		unregister_netdevice_many(&list);
 		break;
 	}