Page MenuHomeFreeBSD

D36082.id109419.diff
No OneTemporary

D36082.id109419.diff

Index: sys/kern/sys_pipe.c
===================================================================
--- sys/kern/sys_pipe.c
+++ sys/kern/sys_pipe.c
@@ -721,6 +721,30 @@
int size;
rpipe = fp->f_data;
+
+ /*
+ * Try to avoid locking the pipe if we have nothing to do.
+ *
+ * There are programs which share one pipe amongst multiple processes
+ * and perform non-blocking reads in parallel, even if the pipe is
+ * empty. This in particular is the case with BSD make, which when
+ * spawned with a high -j number can find itself with over half of the
+ * calls failing to find anything.
+ */
+ if ((fp->f_flag & FNONBLOCK) != 0 && !mac_pipe_check_read_enabled()) {
+ if (__predict_false(uio->uio_resid == 0))
+ return (0);
+ if ((atomic_load_short(&rpipe->pipe_state) & PIPE_EOF) != 0)
+ return (0);
+ if (atomic_load_int(&rpipe->pipe_buffer.cnt) == 0 &&
+#ifdef __ILP32__
+ (atomic_load_int(&rpipe->pipe_pages.cnt) == 0)
+#else
+ (atomic_load_long(&rpipe->pipe_pages.cnt) == 0)
+#endif
+ return (EAGAIN);
+ }
+
PIPE_LOCK(rpipe);
++rpipe->pipe_busy;
error = pipelock(rpipe, 1);
Index: sys/security/mac/mac_framework.h
===================================================================
--- sys/security/mac/mac_framework.h
+++ sys/security/mac/mac_framework.h
@@ -271,7 +271,22 @@
#endif
#define mac_pipe_check_stat_enabled() __predict_false(mac_pipe_check_stat_fp_flag)
int mac_pipe_check_stat(struct ucred *cred, struct pipepair *pp);
-int mac_pipe_check_read(struct ucred *cred, struct pipepair *pp);
+int mac_pipe_check_read_impl(struct ucred *cred, struct pipepair *pp);
+#ifdef MAC
+extern bool mac_pipe_check_read_fp_flag;
+#else
+#define mac_pipe_check_read_fp_flag false
+#endif
+#define mac_pipe_check_read_enabled() __predict_false(mac_pipe_check_read_fp_flag)
+static inline int
+mac_pipe_check_read(struct ucred *cred, struct pipepair *pp)
+{
+
+ if (mac_pipe_check_read_enabled())
+ return (mac_pipe_check_read_impl(cred, pp));
+ return (0);
+}
+
int mac_pipe_check_write(struct ucred *cred, struct pipepair *pp);
void mac_pipe_create(struct ucred *cred, struct pipepair *pp);
void mac_pipe_destroy(struct pipepair *);
Index: sys/security/mac/mac_framework.c
===================================================================
--- sys/security/mac/mac_framework.c
+++ sys/security/mac/mac_framework.c
@@ -145,6 +145,7 @@
FPFLAG_RARE(vnode_check_readlink);
FPFLAG_RARE(pipe_check_stat);
FPFLAG_RARE(pipe_check_poll);
+FPFLAG_RARE(pipe_check_read);
FPFLAG_RARE(ifnet_create_mbuf);
FPFLAG_RARE(ifnet_check_transmit);
@@ -447,6 +448,8 @@
.flag = &mac_pipe_check_stat_fp_flag },
{ .offset = FPO(pipe_check_poll),
.flag = &mac_pipe_check_poll_fp_flag },
+ { .offset = FPO(pipe_check_read),
+ .flag = &mac_pipe_check_read_fp_flag },
{ .offset = FPO(ifnet_create_mbuf),
.flag = &mac_ifnet_create_mbuf_fp_flag },
{ .offset = FPO(ifnet_check_transmit),
Index: sys/security/mac/mac_pipe.c
===================================================================
--- sys/security/mac/mac_pipe.c
+++ sys/security/mac/mac_pipe.c
@@ -179,7 +179,7 @@
"struct pipepair *");
int
-mac_pipe_check_read(struct ucred *cred, struct pipepair *pp)
+mac_pipe_check_read_impl(struct ucred *cred, struct pipepair *pp)
{
int error;

File Metadata

Mime Type
text/plain
Expires
Thu, Aug 27, 4:24 AM (4 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37276005
Default Alt Text
D36082.id109419.diff (3 KB)

Event Timeline