Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 24 May 2014 12:16:33 +0000 (UTC)
From:      Dmitry Chagin <dchagin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r266614 - user/dchagin/lemul/sys/compat/linux
Message-ID:  <201405241216.s4OCGXZK064118@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dchagin
Date: Sat May 24 12:16:33 2014
New Revision: 266614
URL: http://svnweb.freebsd.org/changeset/base/266614

Log:
  Fix some bugs in eventfd:
  
  Do not disable eventfd read and write system call restart
  after signal being caught. [1]
  
  Rewrite eventfd_read(). Check predicate again after mtx_sleep()
  to prevent spurious wakeups. Avoid using uiomove_nofault() call which
  will fail if the destination user buffer is not physically mapped.
  Instead, unlock efd->efd_lock and then call uiomove(). [2]
  
  Drop the efd_count overflow check in eventfd_poll() as eventfd_write() can
  never overflow it.
  
  Pointed out by Jilles Tjoelker. [1, 2]

Modified:
  user/dchagin/lemul/sys/compat/linux/linux_event.c

Modified: user/dchagin/lemul/sys/compat/linux/linux_event.c
==============================================================================
--- user/dchagin/lemul/sys/compat/linux/linux_event.c	Sat May 24 11:42:50 2014	(r266613)
+++ user/dchagin/lemul/sys/compat/linux/linux_event.c	Sat May 24 12:16:33 2014	(r266614)
@@ -649,14 +649,15 @@ eventfd_read(struct file *fp, struct uio
 
 	error = 0;
 	mtx_lock(&efd->efd_lock);
+retry:
 	if (efd->efd_count == 0) {
 		if ((efd->efd_flags & LINUX_O_NONBLOCK) != 0) {
 			mtx_unlock(&efd->efd_lock);
 			return (EAGAIN);
 		}
 		error = mtx_sleep(&efd->efd_count, &efd->efd_lock, PCATCH, "lefdrd", 0);
-		if (error == ERESTART)
-			error = EINTR;
+		if (error == 0)
+			goto retry;
 	}
 	if (error == 0) {
 		if ((efd->efd_flags & LINUX_EFD_SEMAPHORE) != 0) {
@@ -666,14 +667,13 @@ eventfd_read(struct file *fp, struct uio
 			count = efd->efd_count;
 			efd->efd_count = 0;
 		}
-		error = uiomove_nofault(&count, sizeof(eventfd_t), uio);
-		if (error == 0) {
-			KNOTE_LOCKED(&efd->efd_sel.si_note, 0);
-			selwakeup(&efd->efd_sel);
-			wakeup(&efd->efd_count);
-		}
-	}
-	mtx_unlock(&efd->efd_lock);
+		KNOTE_LOCKED(&efd->efd_sel.si_note, 0);
+		selwakeup(&efd->efd_sel);
+		wakeup(&efd->efd_count);
+		mtx_unlock(&efd->efd_lock);
+		error = uiomove(&count, sizeof(eventfd_t), uio);
+	} else
+		mtx_unlock(&efd->efd_lock);
 
 	return (error);
 }
@@ -708,8 +708,6 @@ retry:
 		}
 		error = mtx_sleep(&efd->efd_count, &efd->efd_lock,
 		    PCATCH, "lefdwr", 0);
-		if (error == ERESTART)
-			error = EINTR;
 		if (error == 0)
 			goto retry;
 	}
@@ -736,8 +734,6 @@ eventfd_poll(struct file *fp, int events
 		return (POLLERR);
 
 	mtx_lock(&efd->efd_lock);
-	if (efd->efd_count == UINT64_MAX)
-		revents |= events & POLLERR;
 	if ((events & (POLLIN|POLLRDNORM)) && efd->efd_count > 0)
 		revents |= events & (POLLIN|POLLRDNORM);
 	if ((events & (POLLOUT|POLLWRNORM)) && UINT64_MAX - 1 > efd->efd_count)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405241216.s4OCGXZK064118>