From owner-svn-src-all@FreeBSD.ORG Wed Mar 7 07:31:50 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id BD7F4106566C; Wed, 7 Mar 2012 07:31:50 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A84E08FC12; Wed, 7 Mar 2012 07:31:50 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q277VopH080884; Wed, 7 Mar 2012 07:31:50 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q277VoDY080879; Wed, 7 Mar 2012 07:31:50 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201203070731.q277VoDY080879@svn.freebsd.org> From: Konstantin Belousov Date: Wed, 7 Mar 2012 07:31:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r232641 - in head/sys: fs/fifofs kern sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 07 Mar 2012 07:31:50 -0000 Author: kib Date: Wed Mar 7 07:31:50 2012 New Revision: 232641 URL: http://svn.freebsd.org/changeset/base/232641 Log: The pipe_poll() performs lockless access to the vnode to test fifo_iseof() condition, allowing the v_fifoinfo to be reset and freed by fifo_cleanup(). Precalculate EOF at the places were fo_wgen is changed, and cache the state in a new pipe state flag PIPE_SAMEWGEN. Reported and tested by: bf Submitted by: gianni MFC after: 1 week (a backport) Modified: head/sys/fs/fifofs/fifo.h head/sys/fs/fifofs/fifo_vnops.c head/sys/kern/sys_pipe.c head/sys/sys/pipe.h Modified: head/sys/fs/fifofs/fifo.h ============================================================================== --- head/sys/fs/fifofs/fifo.h Wed Mar 7 07:22:53 2012 (r232640) +++ head/sys/fs/fifofs/fifo.h Wed Mar 7 07:31:50 2012 (r232641) @@ -33,7 +33,6 @@ /* * Prototypes for fifo operations on vnodes. */ -int fifo_iseof(struct file *); int fifo_vnoperate(struct vop_generic_args *); int fifo_printinfo(struct vnode *); Modified: head/sys/fs/fifofs/fifo_vnops.c ============================================================================== --- head/sys/fs/fifofs/fifo_vnops.c Wed Mar 7 07:22:53 2012 (r232640) +++ head/sys/fs/fifofs/fifo_vnops.c Wed Mar 7 07:31:50 2012 (r232641) @@ -67,8 +67,16 @@ struct fifoinfo { long fi_readers; long fi_writers; int fi_wgen; + int fi_seqcount; }; +#define FIFO_UPDWGEN(fip, pip) do { \ + if ((fip)->fi_wgen == (fip)->fi_seqcount) \ + (pip)->pipe_state |= PIPE_SAMEWGEN; \ + else \ + (pip)->pipe_state &= ~PIPE_SAMEWGEN; \ +} while (0) + static vop_print_t fifo_print; static vop_open_t fifo_open; static vop_close_t fifo_close; @@ -174,7 +182,8 @@ fifo_open(ap) if (fip->fi_writers > 0) wakeup(&fip->fi_writers); } - fp->f_seqcount = fip->fi_wgen - fip->fi_writers; + fip->fi_seqcount = fip->fi_wgen - fip->fi_writers; + FIFO_UPDWGEN(fip, fpipe); } if (ap->a_mode & FWRITE) { if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) { @@ -228,6 +237,7 @@ fifo_open(ap) if (fpipe->pipe_state & PIPE_WANTR) wakeup(fpipe); fip->fi_wgen++; + FIFO_UPDWGEN(fip, fpipe); PIPE_UNLOCK(fpipe); fifo_cleanup(vp); } @@ -287,6 +297,7 @@ fifo_close(ap) if (cpipe->pipe_state & PIPE_WANTR) wakeup(cpipe); fip->fi_wgen++; + FIFO_UPDWGEN(fip, cpipe); PIPE_UNLOCK(cpipe); } } @@ -373,15 +384,3 @@ fifo_advlock(ap) return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL); } -int -fifo_iseof(struct file *fp) -{ - struct fifoinfo *fip; - - KASSERT(fp->f_vnode != NULL, ("fifo_iseof: no vnode info")); - KASSERT(fp->f_vnode->v_fifoinfo != NULL, ("fifo_iseof: no fifoinfo")); - fip = fp->f_vnode->v_fifoinfo; - PIPE_LOCK_ASSERT(fip->fi_pipe, MA_OWNED); - return (fp->f_seqcount == fip->fi_wgen); -} - Modified: head/sys/kern/sys_pipe.c ============================================================================== --- head/sys/kern/sys_pipe.c Wed Mar 7 07:22:53 2012 (r232640) +++ head/sys/kern/sys_pipe.c Wed Mar 7 07:31:50 2012 (r232641) @@ -1430,7 +1430,7 @@ pipe_poll(fp, events, active_cred, td) levents = events & (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND); if (rpipe->pipe_state & PIPE_NAMED && fp->f_flag & FREAD && levents && - fifo_iseof(fp)) + rpipe->pipe_state & PIPE_SAMEWGEN) events |= POLLINIGNEOF; if ((events & POLLINIGNEOF) == 0) { Modified: head/sys/sys/pipe.h ============================================================================== --- head/sys/sys/pipe.h Wed Mar 7 07:22:53 2012 (r232640) +++ head/sys/sys/pipe.h Wed Mar 7 07:31:50 2012 (r232641) @@ -96,6 +96,7 @@ struct pipemapping { #define PIPE_DIRECTW 0x400 /* Pipe direct write active. */ #define PIPE_DIRECTOK 0x800 /* Direct mode ok. */ #define PIPE_NAMED 0x1000 /* Is a named pipe. */ +#define PIPE_SAMEWGEN 0x2000 /* same write generation for named pipes. */ /* * Per-pipe data structure.