Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 7 Mar 2012 07:31:50 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r232641 - in head/sys: fs/fifofs kern sys
Message-ID:  <201203070731.q277VoDY080879@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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.



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