From owner-svn-src-user@FreeBSD.ORG Sat May 24 12:16:34 2014 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 27353C22; Sat, 24 May 2014 12:16:34 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id EF4F426D6; Sat, 24 May 2014 12:16:33 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s4OCGXQb064119; Sat, 24 May 2014 12:16:33 GMT (envelope-from dchagin@svn.freebsd.org) Received: (from dchagin@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s4OCGXZK064118; Sat, 24 May 2014 12:16:33 GMT (envelope-from dchagin@svn.freebsd.org) Message-Id: <201405241216.s4OCGXZK064118@svn.freebsd.org> From: Dmitry Chagin Date: Sat, 24 May 2014 12:16:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r266614 - user/dchagin/lemul/sys/compat/linux X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 24 May 2014 12:16:34 -0000 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)