- Update global counters using atomics before allocating. When freeing,
update the couters afterwards. - Cosmetic / code generation changes.
This commit is contained in:
parent
40fb254ec2
commit
5ba557a53c
@ -1,7 +1,7 @@
|
|||||||
/* $NetBSD: sys_pipe.c,v 1.94 2008/01/04 21:18:14 ad Exp $ */
|
/* $NetBSD: sys_pipe.c,v 1.95 2008/01/28 20:01:50 ad Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
|
* Copyright (c) 2003, 2007, 2008 The NetBSD Foundation, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This code is derived from software contributed to The NetBSD Foundation
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
@ -83,7 +83,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.94 2008/01/04 21:18:14 ad Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.95 2008/01/28 20:01:50 ad Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
@ -461,12 +461,13 @@ pipe_read(struct file *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
|
|||||||
{
|
{
|
||||||
struct pipe *rpipe = (struct pipe *) fp->f_data;
|
struct pipe *rpipe = (struct pipe *) fp->f_data;
|
||||||
struct pipebuf *bp = &rpipe->pipe_buffer;
|
struct pipebuf *bp = &rpipe->pipe_buffer;
|
||||||
|
kmutex_t *lock = rpipe->pipe_lock;
|
||||||
int error;
|
int error;
|
||||||
size_t nread = 0;
|
size_t nread = 0;
|
||||||
size_t size;
|
size_t size;
|
||||||
size_t ocnt;
|
size_t ocnt;
|
||||||
|
|
||||||
mutex_enter(rpipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
++rpipe->pipe_busy;
|
++rpipe->pipe_busy;
|
||||||
ocnt = bp->cnt;
|
ocnt = bp->cnt;
|
||||||
|
|
||||||
@ -486,9 +487,9 @@ again:
|
|||||||
if (size > uio->uio_resid)
|
if (size > uio->uio_resid)
|
||||||
size = uio->uio_resid;
|
size = uio->uio_resid;
|
||||||
|
|
||||||
mutex_exit(rpipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
error = uiomove((char *)bp->buffer + bp->out, size, uio);
|
error = uiomove((char *)bp->buffer + bp->out, size, uio);
|
||||||
mutex_enter(rpipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -525,9 +526,9 @@ again:
|
|||||||
size = uio->uio_resid;
|
size = uio->uio_resid;
|
||||||
|
|
||||||
va = (char *)rpipe->pipe_map.kva + rpipe->pipe_map.pos;
|
va = (char *)rpipe->pipe_map.kva + rpipe->pipe_map.pos;
|
||||||
mutex_exit(rpipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
error = uiomove(va, size, uio);
|
error = uiomove(va, size, uio);
|
||||||
mutex_enter(rpipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
nread += size;
|
nread += size;
|
||||||
@ -585,7 +586,7 @@ again:
|
|||||||
cv_broadcast(&rpipe->pipe_cv);
|
cv_broadcast(&rpipe->pipe_cv);
|
||||||
|
|
||||||
/* Now wait until the pipe is filled */
|
/* Now wait until the pipe is filled */
|
||||||
error = cv_wait_sig(&rpipe->pipe_cv, rpipe->pipe_lock);
|
error = cv_wait_sig(&rpipe->pipe_cv, lock);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
goto unlocked_error;
|
goto unlocked_error;
|
||||||
goto again;
|
goto again;
|
||||||
@ -612,7 +613,7 @@ unlocked_error:
|
|||||||
rpipe->pipe_state &= ~PIPE_SIGNALR;
|
rpipe->pipe_state &= ~PIPE_SIGNALR;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_exit(rpipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,12 +627,14 @@ pipe_loan_alloc(struct pipe *wpipe, int npages)
|
|||||||
vsize_t len;
|
vsize_t len;
|
||||||
|
|
||||||
len = (vsize_t)npages << PAGE_SHIFT;
|
len = (vsize_t)npages << PAGE_SHIFT;
|
||||||
|
atomic_add_int(&amountpipekva, len);
|
||||||
wpipe->pipe_map.kva = uvm_km_alloc(kernel_map, len, 0,
|
wpipe->pipe_map.kva = uvm_km_alloc(kernel_map, len, 0,
|
||||||
UVM_KMF_VAONLY | UVM_KMF_WAITVA);
|
UVM_KMF_VAONLY | UVM_KMF_WAITVA);
|
||||||
if (wpipe->pipe_map.kva == 0)
|
if (wpipe->pipe_map.kva == 0) {
|
||||||
|
atomic_add_int(&amountpipekva, -len);
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
atomic_add_int(&amountpipekva, len);
|
|
||||||
wpipe->pipe_map.npages = npages;
|
wpipe->pipe_map.npages = npages;
|
||||||
wpipe->pipe_map.pgs = malloc(npages * sizeof(struct vm_page *), M_PIPE,
|
wpipe->pipe_map.pgs = malloc(npages * sizeof(struct vm_page *), M_PIPE,
|
||||||
M_WAITOK);
|
M_WAITOK);
|
||||||
@ -672,11 +675,12 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio)
|
|||||||
vaddr_t bbase, kva, base, bend;
|
vaddr_t bbase, kva, base, bend;
|
||||||
vsize_t blen, bcnt;
|
vsize_t blen, bcnt;
|
||||||
voff_t bpos;
|
voff_t bpos;
|
||||||
|
kmutex_t *lock = wpipe->pipe_lock;
|
||||||
|
|
||||||
KASSERT(mutex_owned(wpipe->pipe_lock));
|
KASSERT(mutex_owned(wpipe->pipe_lock));
|
||||||
KASSERT(wpipe->pipe_map.cnt == 0);
|
KASSERT(wpipe->pipe_map.cnt == 0);
|
||||||
|
|
||||||
mutex_exit(wpipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle first PIPE_CHUNK_SIZE bytes of buffer. Deal with buffers
|
* Handle first PIPE_CHUNK_SIZE bytes of buffer. Deal with buffers
|
||||||
@ -708,7 +712,7 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio)
|
|||||||
if (wpipe->pipe_map.kva == 0) {
|
if (wpipe->pipe_map.kva == 0) {
|
||||||
error = pipe_loan_alloc(wpipe, npages);
|
error = pipe_loan_alloc(wpipe, npages);
|
||||||
if (error) {
|
if (error) {
|
||||||
mutex_enter(wpipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -719,7 +723,7 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio)
|
|||||||
pgs, UVM_LOAN_TOPAGE);
|
pgs, UVM_LOAN_TOPAGE);
|
||||||
if (error) {
|
if (error) {
|
||||||
pipe_loan_free(wpipe);
|
pipe_loan_free(wpipe);
|
||||||
mutex_enter(wpipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
return (ENOMEM); /* so that caller fallback to ordinary write */
|
return (ENOMEM); /* so that caller fallback to ordinary write */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -739,13 +743,13 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio)
|
|||||||
* have to wait until the pipe is drained. Release the
|
* have to wait until the pipe is drained. Release the
|
||||||
* pipe lock while we wait.
|
* pipe lock while we wait.
|
||||||
*/
|
*/
|
||||||
mutex_enter(wpipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
wpipe->pipe_state |= PIPE_DIRECTW;
|
wpipe->pipe_state |= PIPE_DIRECTW;
|
||||||
pipeunlock(wpipe);
|
pipeunlock(wpipe);
|
||||||
|
|
||||||
while (error == 0 && wpipe->pipe_buffer.cnt > 0) {
|
while (error == 0 && wpipe->pipe_buffer.cnt > 0) {
|
||||||
cv_broadcast(&wpipe->pipe_cv);
|
cv_broadcast(&wpipe->pipe_cv);
|
||||||
error = cv_wait_sig(&wpipe->pipe_cv, wpipe->pipe_lock);
|
error = cv_wait_sig(&wpipe->pipe_cv, lock);
|
||||||
if (error == 0 && wpipe->pipe_state & PIPE_EOF)
|
if (error == 0 && wpipe->pipe_state & PIPE_EOF)
|
||||||
error = EPIPE;
|
error = EPIPE;
|
||||||
}
|
}
|
||||||
@ -757,7 +761,7 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio)
|
|||||||
while (error == 0 && (wpipe->pipe_state & PIPE_DIRECTR)) {
|
while (error == 0 && (wpipe->pipe_state & PIPE_DIRECTR)) {
|
||||||
cv_broadcast(&wpipe->pipe_cv);
|
cv_broadcast(&wpipe->pipe_cv);
|
||||||
pipeselwakeup(wpipe, wpipe, POLL_IN);
|
pipeselwakeup(wpipe, wpipe, POLL_IN);
|
||||||
error = cv_wait_sig(&wpipe->pipe_cv, wpipe->pipe_lock);
|
error = cv_wait_sig(&wpipe->pipe_cv, lock);
|
||||||
if (error == 0 && wpipe->pipe_state & PIPE_EOF)
|
if (error == 0 && wpipe->pipe_state & PIPE_EOF)
|
||||||
error = EPIPE;
|
error = EPIPE;
|
||||||
}
|
}
|
||||||
@ -767,7 +771,7 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio)
|
|||||||
|
|
||||||
/* Acquire the pipe lock and cleanup */
|
/* Acquire the pipe lock and cleanup */
|
||||||
(void)pipelock(wpipe, 0);
|
(void)pipelock(wpipe, 0);
|
||||||
mutex_exit(wpipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
|
|
||||||
if (pgs != NULL) {
|
if (pgs != NULL) {
|
||||||
pmap_kremove(wpipe->pipe_map.kva, blen);
|
pmap_kremove(wpipe->pipe_map.kva, blen);
|
||||||
@ -776,7 +780,7 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio)
|
|||||||
if (error || amountpipekva > maxpipekva)
|
if (error || amountpipekva > maxpipekva)
|
||||||
pipe_loan_free(wpipe);
|
pipe_loan_free(wpipe);
|
||||||
|
|
||||||
mutex_enter(wpipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
if (error) {
|
if (error) {
|
||||||
pipeselwakeup(wpipe, wpipe, POLL_ERR);
|
pipeselwakeup(wpipe, wpipe, POLL_ERR);
|
||||||
|
|
||||||
@ -815,34 +819,33 @@ pipe_write(struct file *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
|
|||||||
{
|
{
|
||||||
struct pipe *wpipe, *rpipe;
|
struct pipe *wpipe, *rpipe;
|
||||||
struct pipebuf *bp;
|
struct pipebuf *bp;
|
||||||
|
kmutex_t *lock;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* We want to write to our peer */
|
/* We want to write to our peer */
|
||||||
rpipe = (struct pipe *) fp->f_data;
|
rpipe = (struct pipe *) fp->f_data;
|
||||||
|
lock = rpipe->pipe_lock;
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
mutex_enter(rpipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
wpipe = rpipe->pipe_peer;
|
wpipe = rpipe->pipe_peer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Detect loss of pipe read side, issue SIGPIPE if lost.
|
* Detect loss of pipe read side, issue SIGPIPE if lost.
|
||||||
*/
|
*/
|
||||||
if (wpipe == NULL) {
|
if (wpipe == NULL || (wpipe->pipe_state & PIPE_EOF) != 0) {
|
||||||
mutex_exit(rpipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
return EPIPE;
|
|
||||||
} else if ((wpipe->pipe_state & PIPE_EOF) != 0) {
|
|
||||||
mutex_exit(rpipe->pipe_lock);
|
|
||||||
return EPIPE;
|
return EPIPE;
|
||||||
}
|
}
|
||||||
++wpipe->pipe_busy;
|
++wpipe->pipe_busy;
|
||||||
|
|
||||||
/* Aquire the long-term pipe lock */
|
/* Aquire the long-term pipe lock */
|
||||||
if ((error = pipelock(wpipe,1)) != 0) {
|
if ((error = pipelock(wpipe, 1)) != 0) {
|
||||||
--wpipe->pipe_busy;
|
--wpipe->pipe_busy;
|
||||||
if (wpipe->pipe_busy == 0) {
|
if (wpipe->pipe_busy == 0) {
|
||||||
cv_broadcast(&wpipe->pipe_cv);
|
cv_broadcast(&wpipe->pipe_cv);
|
||||||
}
|
}
|
||||||
mutex_exit(rpipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -877,8 +880,7 @@ pipe_write(struct file *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
|
|||||||
while (error == 0 && wpipe->pipe_state & PIPE_DIRECTW) {
|
while (error == 0 && wpipe->pipe_state & PIPE_DIRECTW) {
|
||||||
cv_broadcast(&wpipe->pipe_cv);
|
cv_broadcast(&wpipe->pipe_cv);
|
||||||
pipeunlock(wpipe);
|
pipeunlock(wpipe);
|
||||||
error = cv_wait_sig(&wpipe->pipe_cv,
|
error = cv_wait_sig(&wpipe->pipe_cv, lock);
|
||||||
wpipe->pipe_lock);
|
|
||||||
(void)pipelock(wpipe, 0);
|
(void)pipelock(wpipe, 0);
|
||||||
if (wpipe->pipe_state & PIPE_EOF)
|
if (wpipe->pipe_state & PIPE_EOF)
|
||||||
error = EPIPE;
|
error = EPIPE;
|
||||||
@ -945,7 +947,7 @@ pipe_write(struct file *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
|
|||||||
segsize = size;
|
segsize = size;
|
||||||
|
|
||||||
/* Transfer first segment */
|
/* Transfer first segment */
|
||||||
mutex_exit(wpipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
error = uiomove((char *)bp->buffer + bp->in, segsize,
|
error = uiomove((char *)bp->buffer + bp->in, segsize,
|
||||||
uio);
|
uio);
|
||||||
|
|
||||||
@ -963,7 +965,7 @@ pipe_write(struct file *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
|
|||||||
error = uiomove(bp->buffer,
|
error = uiomove(bp->buffer,
|
||||||
size - segsize, uio);
|
size - segsize, uio);
|
||||||
}
|
}
|
||||||
mutex_enter(wpipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1003,7 +1005,7 @@ pipe_write(struct file *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
|
|||||||
pipeselwakeup(wpipe, wpipe, POLL_OUT);
|
pipeselwakeup(wpipe, wpipe, POLL_OUT);
|
||||||
|
|
||||||
pipeunlock(wpipe);
|
pipeunlock(wpipe);
|
||||||
error = cv_wait_sig(&wpipe->pipe_cv, wpipe->pipe_lock);
|
error = cv_wait_sig(&wpipe->pipe_cv, lock);
|
||||||
(void)pipelock(wpipe, 0);
|
(void)pipelock(wpipe, 0);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
break;
|
break;
|
||||||
@ -1046,7 +1048,7 @@ pipe_write(struct file *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
|
|||||||
wpipe->pipe_state |= PIPE_SIGNALR;
|
wpipe->pipe_state |= PIPE_SIGNALR;
|
||||||
|
|
||||||
pipeunlock(wpipe);
|
pipeunlock(wpipe);
|
||||||
mutex_exit(wpipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1058,6 +1060,7 @@ pipe_ioctl(struct file *fp, u_long cmd, void *data, struct lwp *l)
|
|||||||
{
|
{
|
||||||
struct pipe *pipe = (struct pipe *)fp->f_data;
|
struct pipe *pipe = (struct pipe *)fp->f_data;
|
||||||
struct proc *p = l->l_proc;
|
struct proc *p = l->l_proc;
|
||||||
|
kmutex_t *lock = pipe->pipe_lock;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
|
||||||
@ -1065,43 +1068,43 @@ pipe_ioctl(struct file *fp, u_long cmd, void *data, struct lwp *l)
|
|||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
case FIOASYNC:
|
case FIOASYNC:
|
||||||
mutex_enter(pipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
if (*(int *)data) {
|
if (*(int *)data) {
|
||||||
pipe->pipe_state |= PIPE_ASYNC;
|
pipe->pipe_state |= PIPE_ASYNC;
|
||||||
} else {
|
} else {
|
||||||
pipe->pipe_state &= ~PIPE_ASYNC;
|
pipe->pipe_state &= ~PIPE_ASYNC;
|
||||||
}
|
}
|
||||||
mutex_exit(pipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
case FIONREAD:
|
case FIONREAD:
|
||||||
mutex_enter(pipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
#ifndef PIPE_NODIRECT
|
#ifndef PIPE_NODIRECT
|
||||||
if (pipe->pipe_state & PIPE_DIRECTW)
|
if (pipe->pipe_state & PIPE_DIRECTW)
|
||||||
*(int *)data = pipe->pipe_map.cnt;
|
*(int *)data = pipe->pipe_map.cnt;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
*(int *)data = pipe->pipe_buffer.cnt;
|
*(int *)data = pipe->pipe_buffer.cnt;
|
||||||
mutex_exit(pipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
case FIONWRITE:
|
case FIONWRITE:
|
||||||
/* Look at other side */
|
/* Look at other side */
|
||||||
pipe = pipe->pipe_peer;
|
pipe = pipe->pipe_peer;
|
||||||
mutex_enter(pipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
#ifndef PIPE_NODIRECT
|
#ifndef PIPE_NODIRECT
|
||||||
if (pipe->pipe_state & PIPE_DIRECTW)
|
if (pipe->pipe_state & PIPE_DIRECTW)
|
||||||
*(int *)data = pipe->pipe_map.cnt;
|
*(int *)data = pipe->pipe_map.cnt;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
*(int *)data = pipe->pipe_buffer.cnt;
|
*(int *)data = pipe->pipe_buffer.cnt;
|
||||||
mutex_exit(pipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
case FIONSPACE:
|
case FIONSPACE:
|
||||||
/* Look at other side */
|
/* Look at other side */
|
||||||
pipe = pipe->pipe_peer;
|
pipe = pipe->pipe_peer;
|
||||||
mutex_enter(pipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
#ifndef PIPE_NODIRECT
|
#ifndef PIPE_NODIRECT
|
||||||
/*
|
/*
|
||||||
* If we're in direct-mode, we don't really have a
|
* If we're in direct-mode, we don't really have a
|
||||||
@ -1114,7 +1117,7 @@ pipe_ioctl(struct file *fp, u_long cmd, void *data, struct lwp *l)
|
|||||||
#endif
|
#endif
|
||||||
*(int *)data = pipe->pipe_buffer.size -
|
*(int *)data = pipe->pipe_buffer.size -
|
||||||
pipe->pipe_buffer.cnt;
|
pipe->pipe_buffer.cnt;
|
||||||
mutex_exit(pipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
case TIOCSPGRP:
|
case TIOCSPGRP:
|
||||||
@ -1222,10 +1225,10 @@ pipe_free_kmem(struct pipe *pipe)
|
|||||||
if (pipe->pipe_buffer.buffer != NULL) {
|
if (pipe->pipe_buffer.buffer != NULL) {
|
||||||
if (pipe->pipe_buffer.size > PIPE_SIZE)
|
if (pipe->pipe_buffer.size > PIPE_SIZE)
|
||||||
atomic_dec_uint(&nbigpipe);
|
atomic_dec_uint(&nbigpipe);
|
||||||
atomic_add_int(&amountpipekva, -pipe->pipe_buffer.size);
|
|
||||||
uvm_km_free(kernel_map,
|
uvm_km_free(kernel_map,
|
||||||
(vaddr_t)pipe->pipe_buffer.buffer,
|
(vaddr_t)pipe->pipe_buffer.buffer,
|
||||||
pipe->pipe_buffer.size, UVM_KMF_PAGEABLE);
|
pipe->pipe_buffer.size, UVM_KMF_PAGEABLE);
|
||||||
|
atomic_add_int(&amountpipekva, -pipe->pipe_buffer.size);
|
||||||
pipe->pipe_buffer.buffer = NULL;
|
pipe->pipe_buffer.buffer = NULL;
|
||||||
}
|
}
|
||||||
#ifndef PIPE_NODIRECT
|
#ifndef PIPE_NODIRECT
|
||||||
@ -1246,13 +1249,14 @@ static void
|
|||||||
pipeclose(struct file *fp, struct pipe *pipe)
|
pipeclose(struct file *fp, struct pipe *pipe)
|
||||||
{
|
{
|
||||||
struct pipe_mutex *mutex;
|
struct pipe_mutex *mutex;
|
||||||
|
kmutex_t *lock;
|
||||||
struct pipe *ppipe;
|
struct pipe *ppipe;
|
||||||
u_int refcnt;
|
u_int refcnt;
|
||||||
|
|
||||||
if (pipe == NULL)
|
if (pipe == NULL)
|
||||||
return;
|
return;
|
||||||
|
lock = pipe->pipe_lock;
|
||||||
mutex_enter(pipe->pipe_lock);
|
mutex_enter(lock);
|
||||||
pipeselwakeup(pipe, pipe, POLL_HUP);
|
pipeselwakeup(pipe, pipe, POLL_HUP);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1263,7 +1267,7 @@ pipeclose(struct file *fp, struct pipe *pipe)
|
|||||||
if (pipe->pipe_busy) {
|
if (pipe->pipe_busy) {
|
||||||
while (pipe->pipe_busy) {
|
while (pipe->pipe_busy) {
|
||||||
cv_broadcast(&pipe->pipe_cv);
|
cv_broadcast(&pipe->pipe_cv);
|
||||||
cv_wait_sig(&pipe->pipe_cv, pipe->pipe_lock);
|
cv_wait_sig(&pipe->pipe_cv, lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1279,10 +1283,10 @@ pipeclose(struct file *fp, struct pipe *pipe)
|
|||||||
|
|
||||||
KASSERT((pipe->pipe_state & PIPE_LOCKFL) == 0);
|
KASSERT((pipe->pipe_state & PIPE_LOCKFL) == 0);
|
||||||
|
|
||||||
mutex = (struct pipe_mutex *)pipe->pipe_lock;
|
mutex = (struct pipe_mutex *)lock;
|
||||||
refcnt = --(mutex->pm_refcnt);
|
refcnt = --(mutex->pm_refcnt);
|
||||||
KASSERT(refcnt == 0 || refcnt == 1);
|
KASSERT(refcnt == 0 || refcnt == 1);
|
||||||
mutex_exit(pipe->pipe_lock);
|
mutex_exit(lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* free resources
|
* free resources
|
||||||
|
Loading…
Reference in New Issue
Block a user