diff options
author | alc <alc@FreeBSD.org> | 2002-07-13 04:09:45 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2002-07-13 04:09:45 +0000 |
commit | 41fc8114c091411a45564a858af8e7b3cc3af5b7 (patch) | |
tree | 5e444afa69050e763c5282ba5c919210b25abec4 /sys/kern/sys_pipe.c | |
parent | 11a8bfb92369446efa4603ca160d80657e9a4f67 (diff) | |
download | FreeBSD-src-41fc8114c091411a45564a858af8e7b3cc3af5b7.zip FreeBSD-src-41fc8114c091411a45564a858af8e7b3cc3af5b7.tar.gz |
o Lock accesses to the page queues.
o Add a comment explaining why hoisting the page queue lock outside
of a particular loop is not possible.
Diffstat (limited to 'sys/kern/sys_pipe.c')
-rw-r--r-- | sys/kern/sys_pipe.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index 289bc37..135d5eb 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -616,18 +616,27 @@ pipe_build_write_buffer(wpipe, uio) 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; + vm_page_lock_queues(); for (j = 0; j < i; j++) vm_page_unwire(wpipe->pipe_map.ms[j], 1); + vm_page_unlock_queues(); return (EFAULT); } m = PHYS_TO_VM_PAGE(paddr); + vm_page_lock_queues(); vm_page_wire(m); + vm_page_unlock_queues(); wpipe->pipe_map.ms[i] = m; } @@ -690,8 +699,10 @@ pipe_destroy_write_buffer(wpipe) amountpipekva -= wpipe->pipe_buffer.size + PAGE_SIZE; } } + vm_page_lock_queues(); for (i = 0; i < wpipe->pipe_map.npages; i++) vm_page_unwire(wpipe->pipe_map.ms[i], 1); + vm_page_unlock_queues(); wpipe->pipe_map.npages = 0; } |