svn commit: r359012 - in stable/12/sys: fs/fifofs kern sys

Konstantin Belousov kib at FreeBSD.org
Mon Mar 16 11:41:00 UTC 2020


Author: kib
Date: Mon Mar 16 11:40:59 2020
New Revision: 359012
URL: https://svnweb.freebsd.org/changeset/base/359012

Log:
  MFC r358825:
  Preallocate pipe buffers on pipe creation.

Modified:
  stable/12/sys/fs/fifofs/fifo_vnops.c
  stable/12/sys/kern/sys_pipe.c
  stable/12/sys/sys/pipe.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/fs/fifofs/fifo_vnops.c
==============================================================================
--- stable/12/sys/fs/fifofs/fifo_vnops.c	Mon Mar 16 11:38:26 2020	(r359011)
+++ stable/12/sys/fs/fifofs/fifo_vnops.c	Mon Mar 16 11:40:59 2020	(r359012)
@@ -150,7 +150,9 @@ fifo_open(ap)
 	if (fp == NULL || (ap->a_mode & FEXEC) != 0)
 		return (EINVAL);
 	if ((fip = vp->v_fifoinfo) == NULL) {
-		pipe_named_ctor(&fpipe, td);
+		error = pipe_named_ctor(&fpipe, td);
+		if (error != 0)
+			return (error);
 		fip = malloc(sizeof(*fip), M_VNODE, M_WAITOK);
 		fip->fi_pipe = fpipe;
 		fpipe->pipe_wgen = fip->fi_readers = fip->fi_writers = 0;

Modified: stable/12/sys/kern/sys_pipe.c
==============================================================================
--- stable/12/sys/kern/sys_pipe.c	Mon Mar 16 11:38:26 2020	(r359011)
+++ stable/12/sys/kern/sys_pipe.c	Mon Mar 16 11:40:59 2020	(r359012)
@@ -226,8 +226,8 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, piperesizeallowed, CTL
 static void pipeinit(void *dummy __unused);
 static void pipeclose(struct pipe *cpipe);
 static void pipe_free_kmem(struct pipe *cpipe);
-static void pipe_create(struct pipe *pipe, int backing);
-static void pipe_paircreate(struct thread *td, struct pipepair **p_pp);
+static int pipe_create(struct pipe *pipe, bool backing);
+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);
 #ifndef PIPE_NODIRECT
@@ -335,11 +335,12 @@ pipe_zone_fini(void *mem, int size)
 	mtx_destroy(&pp->pp_mtx);
 }
 
-static void
+static int
 pipe_paircreate(struct thread *td, struct pipepair **p_pp)
 {
 	struct pipepair *pp;
 	struct pipe *rpipe, *wpipe;
+	int error;
 
 	*p_pp = pp = uma_zalloc(pipe_zone, M_WAITOK);
 #ifdef MAC
@@ -357,22 +358,44 @@ pipe_paircreate(struct thread *td, struct pipepair **p
 	knlist_init_mtx(&rpipe->pipe_sel.si_note, PIPE_MTX(rpipe));
 	knlist_init_mtx(&wpipe->pipe_sel.si_note, PIPE_MTX(wpipe));
 
-	/* Only the forward direction pipe is backed by default */
-	pipe_create(rpipe, 1);
-	pipe_create(wpipe, 0);
+	/*
+	 * Only the forward direction pipe is backed by big buffer by
+	 * default.
+	 */
+	error = pipe_create(rpipe, true);
+	if (error != 0)
+		goto fail;
+	error = pipe_create(wpipe, false);
+	if (error != 0) {
+		pipe_free_kmem(rpipe);
+		goto fail;
+	}
 
 	rpipe->pipe_state |= PIPE_DIRECTOK;
 	wpipe->pipe_state |= PIPE_DIRECTOK;
+	return (0);
+
+fail:
+	knlist_destroy(&rpipe->pipe_sel.si_note);
+	knlist_destroy(&wpipe->pipe_sel.si_note);
+#ifdef MAC
+	mac_pipe_destroy(pp);
+#endif
+	return (error);
 }
 
-void
+int
 pipe_named_ctor(struct pipe **ppipe, struct thread *td)
 {
 	struct pipepair *pp;
+	int error;
 
-	pipe_paircreate(td, &pp);
+	error = pipe_paircreate(td, &pp);
+	if (error != 0)
+		return (error);
 	pp->pp_rpipe.pipe_state |= PIPE_NAMED;
 	*ppipe = &pp->pp_rpipe;
+	return (0);
 }
 
 void
@@ -404,7 +427,9 @@ kern_pipe(struct thread *td, int fildes[2], int flags,
 	struct pipepair *pp;
 	int fd, fflags, error;
 
-	pipe_paircreate(td, &pp);
+	error = pipe_paircreate(td, &pp);
+	if (error != 0)
+		return (error);
 	rpipe = &pp->pp_rpipe;
 	wpipe = &pp->pp_wpipe;
 	error = falloc_caps(td, &rf, &fd, flags, fcaps1);
@@ -618,25 +643,16 @@ pipeselwakeup(struct pipe *cpipe)
  * Initialize and allocate VM and memory for pipe.  The structure
  * will start out zero'd from the ctor, so we just manage the kmem.
  */
-static void
-pipe_create(struct pipe *pipe, int backing)
+static int
+pipe_create(struct pipe *pipe, bool large_backing)
 {
+	int error;
 
-	if (backing) {
-		/*
-		 * Note that these functions can fail if pipe map is exhausted
-		 * (as a result of too many pipes created), but we ignore the
-		 * error as it is not fatal and could be provoked by
-		 * unprivileged users. The only consequence is worse performance
-		 * with given pipe.
-		 */
-		if (amountpipekva > maxpipekva / 2)
-			(void)pipespace_new(pipe, SMALL_PIPE_SIZE);
-		else
-			(void)pipespace_new(pipe, PIPE_SIZE);
-	}
-
-	pipe->pipe_ino = alloc_unr64(&pipeino_unr);
+	error = pipespace_new(pipe, !large_backing || amountpipekva >
+	    maxpipekva / 2 ? SMALL_PIPE_SIZE : PIPE_SIZE);
+	if (error == 0)
+		pipe->pipe_ino = alloc_unr64(&pipeino_unr);
+	return (error);
 }
 
 /* ARGSUSED */
@@ -1070,17 +1086,7 @@ pipe_write(struct file *fp, struct uio *uio, struct uc
 		pipespace(wpipe, desiredsize);
 		PIPE_LOCK(wpipe);
 	}
-	if (wpipe->pipe_buffer.size == 0) {
-		/*
-		 * This can only happen for reverse direction use of pipes
-		 * in a complete OOM situation.
-		 */
-		error = ENOMEM;
-		--wpipe->pipe_busy;
-		pipeunlock(wpipe);
-		PIPE_UNLOCK(wpipe);
-		return (error);
-	}
+	MPASS(wpipe->pipe_buffer.size != 0);
 
 	pipeunlock(wpipe);
 

Modified: stable/12/sys/sys/pipe.h
==============================================================================
--- stable/12/sys/sys/pipe.h	Mon Mar 16 11:38:26 2020	(r359011)
+++ stable/12/sys/sys/pipe.h	Mon Mar 16 11:40:59 2020	(r359012)
@@ -142,6 +142,6 @@ struct pipepair {
 #define PIPE_LOCK_ASSERT(pipe, type)  mtx_assert(PIPE_MTX(pipe), (type))
 
 void	pipe_dtor(struct pipe *dpipe);
-void	pipe_named_ctor(struct pipe **ppipe, struct thread *td);
+int	pipe_named_ctor(struct pipe **ppipe, struct thread *td);
 void	pipeselwakeup(struct pipe *cpipe);
 #endif /* !_SYS_PIPE_H_ */


More information about the svn-src-all mailing list