svn commit: r317780 - stable/11/sys/compat/linuxkpi/common/src

Mark Johnston markj at FreeBSD.org
Wed May 3 23:41:11 UTC 2017


Author: markj
Date: Wed May  3 23:41:09 2017
New Revision: 317780
URL: https://svnweb.freebsd.org/changeset/base/317780

Log:
  MFC r317148:
  Drop Giant before sleeping in linux_wait_for_{timeout_,}common().

Modified:
  stable/11/sys/compat/linuxkpi/common/src/linux_compat.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/compat/linuxkpi/common/src/linux_compat.c
==============================================================================
--- stable/11/sys/compat/linuxkpi/common/src/linux_compat.c	Wed May  3 22:35:41 2017	(r317779)
+++ stable/11/sys/compat/linuxkpi/common/src/linux_compat.c	Wed May  3 23:41:09 2017	(r317780)
@@ -1096,28 +1096,38 @@ linux_complete_common(struct completion 
 long
 linux_wait_for_common(struct completion *c, int flags)
 {
+	long error;
+
 	if (SCHEDULER_STOPPED())
 		return (0);
 
+	DROP_GIANT();
+
 	if (flags != 0)
 		flags = SLEEPQ_INTERRUPTIBLE | SLEEPQ_SLEEP;
 	else
 		flags = SLEEPQ_SLEEP;
+	error = 0;
 	for (;;) {
 		sleepq_lock(c);
 		if (c->done)
 			break;
 		sleepq_add(c, NULL, "completion", flags, 0);
 		if (flags & SLEEPQ_INTERRUPTIBLE) {
-			if (sleepq_wait_sig(c, 0) != 0)
-				return (-ERESTARTSYS);
+			if (sleepq_wait_sig(c, 0) != 0) {
+				error = -ERESTARTSYS;
+				goto intr;
+			}
 		} else
 			sleepq_wait(c, 0);
 	}
 	c->done--;
 	sleepq_release(c);
 
-	return (0);
+intr:
+	PICKUP_GIANT();
+
+	return (error);
 }
 
 /*
@@ -1126,18 +1136,22 @@ linux_wait_for_common(struct completion 
 long
 linux_wait_for_timeout_common(struct completion *c, long timeout, int flags)
 {
-	long end = jiffies + timeout;
+	long end = jiffies + timeout, error;
+	int ret;
 
 	if (SCHEDULER_STOPPED())
 		return (0);
 
+	DROP_GIANT();
+
 	if (flags != 0)
 		flags = SLEEPQ_INTERRUPTIBLE | SLEEPQ_SLEEP;
 	else
 		flags = SLEEPQ_SLEEP;
-	for (;;) {
-		int ret;
 
+	error = 0;
+	ret = 0;
+	for (;;) {
 		sleepq_lock(c);
 		if (c->done)
 			break;
@@ -1150,16 +1164,20 @@ linux_wait_for_timeout_common(struct com
 		if (ret != 0) {
 			/* check for timeout or signal */
 			if (ret == EWOULDBLOCK)
-				return (0);
+				error = 0;
 			else
-				return (-ERESTARTSYS);
+				error = -ERESTARTSYS;
+			goto intr;
 		}
 	}
 	c->done--;
 	sleepq_release(c);
 
+intr:
+	PICKUP_GIANT();
+
 	/* return how many jiffies are left */
-	return (linux_timer_jiffies_until(end));
+	return (ret != 0 ? error : linux_timer_jiffies_until(end));
 }
 
 int


More information about the svn-src-all mailing list