Hi Matthew,

There is a deadlock when destroying VLANs after the epoch changes were made. Can you have a look and consider the attached patch for 12-current?

Thank you!

--HPS

Thread 1:

epoch_block_handler_preempt() at epoch_block_handler_preempt+0x90/frame 0xfffffe00261b3970 ck_epoch_synchronize_wait() at ck_epoch_synchronize_wait+0x9d/frame 0xfffffe00261b39c0 epoch_wait_preempt() at epoch_wait_preempt+0x170/frame 0xfffffe00261b3a20 vlan_setmulti() at vlan_setmulti+0xb4/frame 0xfffffe00261b3a70 vlan_ioctl() at vlan_ioctl+0x83/frame 0xfffffe00261b3ad0 in6m_release_task() at in6m_release_task+0x32e/frame 0xfffffe00261b3b30 gtaskqueue_run_locked() at gtaskqueue_run_locked+0xf9/frame 0xfffffe00261b3b80 gtaskqueue_thread_loop() at gtaskqueue_thread_loop+0x88/frame 0xfffffe00261b3bb0 fork_exit() at fork_exit+0x84/frame 0xfffffe00261b3bf0 fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe00261b3bf0 --- trap 0, rip = 0, rsp = 0, rbp = 0 ---

Thread 2:

sleepq_switch() at sleepq_switch+0x10d/frame 0xfffffe002bffd3f0 sleepq_wait() at sleepq_wait+0x43/frame 0xfffffe002bffd420 _sx_xlock_hard() at _sx_xlock_hard+0x4a6/frame 0xfffffe002bffd4c0 _sx_xlock() at _sx_xlock+0xc1/frame 0xfffffe002bffd500 in6_leavegroup() at in6_leavegroup+0x27/frame 0xfffffe002bffd520 in6_purgeaddr() at in6_purgeaddr+0xc2/frame 0xfffffe002bffd6a0 if_purgeaddrs() at if_purgeaddrs+0x11e/frame 0xfffffe002bffd750 if_detach_internal() at if_detach_internal+0x709/frame 0xfffffe002bffd7d0 if_detach() at if_detach+0x3d/frame 0xfffffe002bffd7f0 vlan_clone_destroy() at vlan_clone_destroy+0x21/frame 0xfffffe002bffd820 if_clone_destroyif() at if_clone_destroyif+0x175/frame 0xfffffe002bffd870 if_clone_destroy() at if_clone_destroy+0x205/frame 0xfffffe002bffd8c0 ifioctl() at ifioctl+0x582/frame 0xfffffe002bffd990 kern_ioctl() at kern_ioctl+0x2ba/frame 0xfffffe002bffd9f0 sys_ioctl() at sys_ioctl+0x15e/frame 0xfffffe002bffdac0 amd64_syscall() at amd64_syscall+0x28c/frame 0xfffffe002bffdbf0 fast_syscall_common() at fast_syscall_common+0x101/frame 0xfffffe002bffdbf0 --- syscall (54, FreeBSD ELF64, sys_ioctl), rip = 0x80047b92a, rsp = 0x7fffffffe318, rbp = 0x7fffffffe330 ---
Index: sys/net/if_vlan.c
===================================================================
--- sys/net/if_vlan.c	(revision 339234)
+++ sys/net/if_vlan.c	(working copy)
@@ -153,6 +153,7 @@
 struct vlan_mc_entry {
 	struct sockaddr_dl		mc_addr;
 	CK_SLIST_ENTRY(vlan_mc_entry)	mc_entries;
+	struct epoch_context		mc_epoch_ctx;
 };
 
 struct	ifvlan {
@@ -317,6 +318,13 @@
 #define HASH(n, m)	((((n) >> 8) ^ ((n) >> 4) ^ (n)) & (m))
 
 static void
+vlan_mc_free(struct epoch_context *ctx)
+{
+	struct vlan_mc_entry *mc = __containerof(ctx, struct vlan_mc_entry, mc_epoch_ctx);
+	free(mc, M_VLAN);
+}
+
+static void
 vlan_inithash(struct ifvlantrunk *trunk)
 {
 	int i, n;
@@ -572,8 +580,7 @@
 	while ((mc = CK_SLIST_FIRST(&sc->vlan_mc_listhead)) != NULL) {
 		CK_SLIST_REMOVE_HEAD(&sc->vlan_mc_listhead, mc_entries);
 		(void)if_delmulti(ifp_p, (struct sockaddr *)&mc->mc_addr);
-		NET_EPOCH_WAIT();
-		free(mc, M_VLAN);
+		epoch_call(net_epoch_preempt, &mc->mc_epoch_ctx, vlan_mc_free);
 	}
 
 	/* Now program new ones. */
@@ -1485,8 +1492,7 @@
 					    error);
 			}
 			CK_SLIST_REMOVE_HEAD(&ifv->vlan_mc_listhead, mc_entries);
-			NET_EPOCH_WAIT();
-			free(mc, M_VLAN);
+			epoch_call(net_epoch_preempt, &mc->mc_epoch_ctx, vlan_mc_free);
 		}
 
 		vlan_setflags(ifp, 0); /* clear special flags on parent */
_______________________________________________
freebsd-net@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to