Module Name:    src
Committed By:   ozaki-r
Date:           Thu Dec 22 12:55:28 UTC 2016

Modified Files:
        src/sys/rump/net/lib/libshmif: if_shmem.c

Log Message:
Fix that rump.ifconfig shmifN destroy hangs up

rump.ifconfig shmifN destroy sometimes hangs up on closing a file
descriptor of kqueue under heavy load. It seems it happens because of
a race condition between closing a fd and kevent to the same fd on
another kthread for packet Rx. Fix it by executing the close operation
after the kthread left.


To generate a diff of this commit:
cvs rdiff -u -r1.71 -r1.72 src/sys/rump/net/lib/libshmif/if_shmem.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/rump/net/lib/libshmif/if_shmem.c
diff -u src/sys/rump/net/lib/libshmif/if_shmem.c:1.71 src/sys/rump/net/lib/libshmif/if_shmem.c:1.72
--- src/sys/rump/net/lib/libshmif/if_shmem.c:1.71	Thu Dec 22 10:13:09 2016
+++ src/sys/rump/net/lib/libshmif/if_shmem.c	Thu Dec 22 12:55:28 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_shmem.c,v 1.71 2016/12/22 10:13:09 ozaki-r Exp $	*/
+/*	$NetBSD: if_shmem.c,v 1.72 2016/12/22 12:55:28 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 2009, 2010 Antti Kantee.  All Rights Reserved.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.71 2016/12/22 10:13:09 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.72 2016/12/22 12:55:28 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -374,7 +374,6 @@ shmif_unclone(struct ifnet *ifp)
 
 	shmif_stop(ifp, 1);
 	if_down(ifp);
-	finibackend(sc);
 
 	mutex_enter(&sc->sc_mtx);
 	sc->sc_dying = true;
@@ -385,6 +384,13 @@ shmif_unclone(struct ifnet *ifp)
 		kthread_join(sc->sc_rcvl);
 	sc->sc_rcvl = NULL;
 
+	/*
+	 * Need to be called after the kthread left, otherwise closing kqueue
+	 * (sc_kq) hangs sometimes perhaps because of a race condition between
+	 * close and kevent in the kthread on the kqueue.
+	 */
+	finibackend(sc);
+
 	vmem_xfree(shmif_units, sc->sc_unit+1, 1);
 
 	ether_ifdetach(ifp);

Reply via email to