svn commit: r349367 - head/sys/fs/cuse

Hans Petter Selasky hselasky at FreeBSD.org
Tue Jun 25 11:42:55 UTC 2019


Author: hselasky
Date: Tue Jun 25 11:42:53 2019
New Revision: 349367
URL: https://svnweb.freebsd.org/changeset/base/349367

Log:
  Fix for deadlock situation in cuse(3)
  
  The final server unref should be done by the server thread to prevent
  deadlock in the client cdevpriv destructor, which cannot destroy
  itself.
  
  MFC after:	1 week
  Sponsored by:	Mellanox Technologies

Modified:
  head/sys/fs/cuse/cuse.c

Modified: head/sys/fs/cuse/cuse.c
==============================================================================
--- head/sys/fs/cuse/cuse.c	Tue Jun 25 11:40:37 2019	(r349366)
+++ head/sys/fs/cuse/cuse.c	Tue Jun 25 11:42:53 2019	(r349367)
@@ -699,12 +699,38 @@ cuse_server_unref(struct cuse_server *pcs)
 	free(pcs, M_CUSE);
 }
 
+static int
+cuse_server_do_close(struct cuse_server *pcs)
+{
+	int retval;
+
+	cuse_lock();
+	cuse_server_is_closing(pcs);
+	/* final client wakeup, if any */
+	cuse_server_wakeup_all_client_locked(pcs);
+
+	knlist_clear(&pcs->selinfo.si_note, 1);
+
+	retval = pcs->refs;
+	cuse_unlock();
+
+	return (retval);
+}
+
 static void
 cuse_server_free(void *arg)
 {
 	struct cuse_server *pcs = arg;
 
-	/* drop refcount */
+	/*
+	 * The final server unref should be done by the server thread
+	 * to prevent deadlock in the client cdevpriv destructor,
+	 * which cannot destroy itself.
+	 */
+	while (cuse_server_do_close(pcs) != 1)
+		pause("W", hz);
+
+	/* drop final refcount */
 	cuse_server_unref(pcs);
 }
 
@@ -746,21 +772,10 @@ static int
 cuse_server_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
 {
 	struct cuse_server *pcs;
-	int error;
 
-	error = cuse_server_get(&pcs);
-	if (error != 0)
-		goto done;
+	if (cuse_server_get(&pcs) == 0)
+		cuse_server_do_close(pcs);
 
-	cuse_lock();
-	cuse_server_is_closing(pcs);
-	/* final client wakeup, if any */
-	cuse_server_wakeup_all_client_locked(pcs);
-
-	knlist_clear(&pcs->selinfo.si_note, 1);
-	cuse_unlock();
-
-done:
 	return (0);
 }
 


More information about the svn-src-head mailing list