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>