Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 31 Jul 2012 02:10:11 GMT
From:      dfilter@FreeBSD.ORG (dfilter service)
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/170203: commit references a PR
Message-ID:  <201207310210.q6V2ABRu024619@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/170203; it has been noted by GNATS.

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/170203: commit references a PR
Date: Tue, 31 Jul 2012 02:00:54 +0000 (UTC)

 Author: davidxu
 Date: Tue Jul 31 02:00:37 2012
 New Revision: 238928
 URL: http://svn.freebsd.org/changeset/base/238928
 
 Log:
   When a thread is blocked in direct write state, it only sets PIPE_DIRECTW
   flag but not PIPE_WANTW, but FIFO pipe code does not understand this internal
   state, when a FIFO peer reader closes the pipe, it wants to notify the writer,
   it checks PIPE_WANTW, if not set, it skips calling wakeup(), so blocked writer
   never noticed the case, but in general, the writer should return from the
   syscall with EPIPE error code and may get SIGPIPE signal. Setting the
   PIPE_WANTW fixed problem, or you can turn off direct write, it should fix the
   problem too. This bug is found by PR/170203.
   
   Another bug in FIFO pipe code is when peer closes the pipe, another end which
   is being blocked in select() or poll() is not notified, it missed to call
   pipeselwakeup().
   
   Third problem is found in poll regression test, the existing code can not
   pass 6b,6c,6d tests, but FreeBSD-4 works. This commit does not fix the
   problem, I still need to study more to find the cause.
   
   PR: 170203
   Tested by: Garrett Copper &lt; yanegomi at gmail dot com &gt;
 
 Modified:
   head/sys/fs/fifofs/fifo_vnops.c
   head/sys/kern/sys_pipe.c
   head/sys/sys/pipe.h
 
 Modified: head/sys/fs/fifofs/fifo_vnops.c
 ==============================================================================
 --- head/sys/fs/fifofs/fifo_vnops.c	Tue Jul 31 00:46:19 2012	(r238927)
 +++ head/sys/fs/fifofs/fifo_vnops.c	Tue Jul 31 02:00:37 2012	(r238928)
 @@ -283,8 +283,11 @@ fifo_close(ap)
  		if (fip->fi_readers == 0) {
  			PIPE_LOCK(cpipe);
  			cpipe->pipe_state |= PIPE_EOF;
 -			if (cpipe->pipe_state & PIPE_WANTW)
 +			if ((cpipe->pipe_state & PIPE_WANTW)) {
 +				cpipe->pipe_state &= ~PIPE_WANTW;
  				wakeup(cpipe);
 +			}
 +			pipeselwakeup(cpipe);
  			PIPE_UNLOCK(cpipe);
  		}
  	}
 @@ -293,10 +296,13 @@ fifo_close(ap)
  		if (fip->fi_writers == 0) {
  			PIPE_LOCK(cpipe);
  			cpipe->pipe_state |= PIPE_EOF;
 -			if (cpipe->pipe_state & PIPE_WANTR)
 +			if ((cpipe->pipe_state & PIPE_WANTR)) {
 +				cpipe->pipe_state &= ~PIPE_WANTR;
  				wakeup(cpipe);
 +			}
  			fip->fi_wgen++;
  			FIFO_UPDWGEN(fip, cpipe);
 +			pipeselwakeup(cpipe);
  			PIPE_UNLOCK(cpipe);
  		}
  	}
 
 Modified: head/sys/kern/sys_pipe.c
 ==============================================================================
 --- head/sys/kern/sys_pipe.c	Tue Jul 31 00:46:19 2012	(r238927)
 +++ head/sys/kern/sys_pipe.c	Tue Jul 31 02:00:37 2012	(r238928)
 @@ -227,7 +227,6 @@ static int pipe_create(struct pipe *pipe
  static int pipe_paircreate(struct thread *td, struct pipepair **p_pp);
  static __inline int pipelock(struct pipe *cpipe, int catch);
  static __inline void pipeunlock(struct pipe *cpipe);
 -static __inline void pipeselwakeup(struct pipe *cpipe);
  #ifndef PIPE_NODIRECT
  static int pipe_build_write_buffer(struct pipe *wpipe, struct uio *uio);
  static void pipe_destroy_write_buffer(struct pipe *wpipe);
 @@ -607,7 +606,7 @@ pipeunlock(cpipe)
  	}
  }
  
 -static __inline void
 +void
  pipeselwakeup(cpipe)
  	struct pipe *cpipe;
  {
 @@ -738,7 +737,7 @@ pipe_read(fp, uio, active_cred, flags, t
  			rpipe->pipe_map.pos += size;
  			rpipe->pipe_map.cnt -= size;
  			if (rpipe->pipe_map.cnt == 0) {
 -				rpipe->pipe_state &= ~PIPE_DIRECTW;
 +				rpipe->pipe_state &= ~(PIPE_DIRECTW|PIPE_WANTW);
  				wakeup(rpipe);
  			}
  #endif
 @@ -1001,6 +1000,7 @@ retry:
  			wakeup(wpipe);
  		}
  		pipeselwakeup(wpipe);
 +		wpipe->pipe_state |= PIPE_WANTW;
  		pipeunlock(wpipe);
  		error = msleep(wpipe, PIPE_MTX(wpipe), PRIBIO | PCATCH,
  		    "pipdwt", 0);
 
 Modified: head/sys/sys/pipe.h
 ==============================================================================
 --- head/sys/sys/pipe.h	Tue Jul 31 00:46:19 2012	(r238927)
 +++ head/sys/sys/pipe.h	Tue Jul 31 02:00:37 2012	(r238928)
 @@ -143,5 +143,5 @@ struct pipepair {
  
  void	pipe_dtor(struct pipe *dpipe);
  int	pipe_named_ctor(struct pipe **ppipe, struct thread *td);
 -
 +void	pipeselwakeup(struct pipe *cpipe);
  #endif /* !_SYS_PIPE_H_ */
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 



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