summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-09-08 04:58:32 +0000
committeralc <alc@FreeBSD.org>2003-09-08 04:58:32 +0000
commit81a5dc108d0dbc8195066d40a5551a64f03bd689 (patch)
treee189218f7cd9c9ec18b6150891a80d0cda5caa46 /sys
parent806065b5dfe6e8c2f0b5cd650af30af63a9d47fc (diff)
downloadFreeBSD-src-81a5dc108d0dbc8195066d40a5551a64f03bd689.zip
FreeBSD-src-81a5dc108d0dbc8195066d40a5551a64f03bd689.tar.gz
Use pmap_extract_and_hold() in pipe_build_write_buffer(). Consequently,
pipe_build_write_buffer() no longer requires Giant on entry. Reviewed by: tegge
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/sys_pipe.c46
1 files changed, 11 insertions, 35 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index 50ea163..0e7d6f2 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -142,21 +142,6 @@ static struct filterops pipe_rfiltops =
static struct filterops pipe_wfiltops =
{ 1, NULL, filt_pipedetach, filt_pipewrite };
-#define PIPE_GET_GIANT(pipe) \
- do { \
- KASSERT(((pipe)->pipe_state & PIPE_LOCKFL) != 0, \
- ("%s:%d PIPE_GET_GIANT: line pipe not locked", \
- __FILE__, __LINE__)); \
- PIPE_UNLOCK(pipe); \
- mtx_lock(&Giant); \
- } while (0)
-
-#define PIPE_DROP_GIANT(pipe) \
- do { \
- mtx_unlock(&Giant); \
- PIPE_LOCK(pipe); \
- } while (0)
-
/*
* Default pipe buffer size(s), this can be kind-of large now because pipe
* space is pageable. The pipe code will try to maintain locality of
@@ -655,46 +640,37 @@ pipe_build_write_buffer(wpipe, uio)
struct pipe *wpipe;
struct uio *uio;
{
+ pmap_t pmap;
u_int size;
- int i;
+ int i, j;
vm_offset_t addr, endaddr;
- vm_paddr_t paddr;
- GIANT_REQUIRED;
PIPE_LOCK_ASSERT(wpipe, MA_NOTOWNED);
size = (u_int) uio->uio_iov->iov_len;
if (size > wpipe->pipe_buffer.size)
size = wpipe->pipe_buffer.size;
+ pmap = vmspace_pmap(curproc->p_vmspace);
endaddr = round_page((vm_offset_t)uio->uio_iov->iov_base + size);
addr = trunc_page((vm_offset_t)uio->uio_iov->iov_base);
for (i = 0; addr < endaddr; addr += PAGE_SIZE, i++) {
- vm_page_t m;
-
/*
* vm_fault_quick() can sleep. Consequently,
* vm_page_lock_queue() and vm_page_unlock_queue()
* should not be performed outside of this loop.
*/
- if (vm_fault_quick((caddr_t)addr, VM_PROT_READ) < 0 ||
- (paddr = pmap_extract(vmspace_pmap(curproc->p_vmspace),
- addr)) == 0) {
- int j;
-
+ race:
+ if (vm_fault_quick((caddr_t)addr, VM_PROT_READ) < 0) {
vm_page_lock_queues();
- for (j = 0; j < i; j++) {
+ for (j = 0; j < i; j++)
vm_page_unhold(wpipe->pipe_map.ms[j]);
- }
vm_page_unlock_queues();
return (EFAULT);
}
-
- m = PHYS_TO_VM_PAGE(paddr);
- vm_page_lock_queues();
- vm_page_hold(m);
- vm_page_unlock_queues();
- wpipe->pipe_map.ms[i] = m;
+ wpipe->pipe_map.ms[i] = pmap_extract_and_hold(pmap, addr);
+ if (wpipe->pipe_map.ms[i] == NULL)
+ goto race;
}
/*
@@ -846,9 +822,9 @@ retry:
wpipe->pipe_state |= PIPE_DIRECTW;
pipelock(wpipe, 0);
- PIPE_GET_GIANT(wpipe);
+ PIPE_UNLOCK(wpipe);
error = pipe_build_write_buffer(wpipe, uio);
- PIPE_DROP_GIANT(wpipe);
+ PIPE_LOCK(wpipe);
pipeunlock(wpipe);
if (error) {
wpipe->pipe_state &= ~PIPE_DIRECTW;
OpenPOWER on IntegriCloud