| version 1.79, 2003/04/09 18:38:03 |
version 1.80, 2003/05/03 17:53:17 |
| Line 153 int sokvawaiters; |
|
| Line 153 int sokvawaiters; |
|
| #define SOCK_LOAN_THRESH 4096 |
#define SOCK_LOAN_THRESH 4096 |
| #define SOCK_LOAN_CHUNK 65536 |
#define SOCK_LOAN_CHUNK 65536 |
| |
|
| |
static size_t sodopendfree(struct socket *); |
| |
|
| |
vaddr_t |
| |
sokvaalloc(vsize_t len, struct socket *so) |
| |
{ |
| |
vaddr_t lva; |
| |
int s; |
| |
|
| |
while (socurkva + len > somaxkva) { |
| |
if (sodopendfree(so)) |
| |
continue; |
| |
SOSEND_COUNTER_INCR(&sosend_kvalimit); |
| |
s = splvm(); |
| |
sokvawaiters++; |
| |
(void) tsleep(&socurkva, PVM, "sokva", 0); |
| |
sokvawaiters--; |
| |
splx(s); |
| |
} |
| |
|
| |
lva = uvm_km_valloc_wait(kernel_map, len); |
| |
if (lva == 0) |
| |
return (0); |
| |
socurkva += len; |
| |
|
| |
return lva; |
| |
} |
| |
|
| |
void |
| |
sokvafree(vaddr_t sva, vsize_t len) |
| |
{ |
| |
|
| |
uvm_km_free(kernel_map, sva, len); |
| |
socurkva -= len; |
| |
if (sokvawaiters) |
| |
wakeup(&socurkva); |
| |
} |
| |
|
| static void |
static void |
| sodoloanfree(struct vm_page **pgs, caddr_t buf, size_t size) |
sodoloanfree(struct vm_page **pgs, caddr_t buf, size_t size) |
| { |
{ |
| Line 179 sodoloanfree(struct vm_page **pgs, caddr |
|
| Line 216 sodoloanfree(struct vm_page **pgs, caddr |
|
| pmap_kremove(sva, len); |
pmap_kremove(sva, len); |
| pmap_update(pmap_kernel()); |
pmap_update(pmap_kernel()); |
| uvm_unloan(pgs, npgs, UVM_LOAN_TOPAGE); |
uvm_unloan(pgs, npgs, UVM_LOAN_TOPAGE); |
| uvm_km_free(kernel_map, sva, len); |
sokvafree(sva, len); |
| socurkva -= len; |
|
| if (sokvawaiters) |
|
| wakeup(&socurkva); |
|
| } |
} |
| |
|
| static size_t |
static size_t |
| Line 228 sodopendfree(struct socket *so) |
|
| Line 262 sodopendfree(struct socket *so) |
|
| return (rv); |
return (rv); |
| } |
} |
| |
|
| static void |
void |
| soloanfree(struct mbuf *m, caddr_t buf, size_t size, void *arg) |
soloanfree(struct mbuf *m, caddr_t buf, size_t size, void *arg) |
| { |
{ |
| struct socket *so = arg; |
struct socket *so = arg; |
| Line 254 sosend_loan(struct socket *so, struct ui |
|
| Line 288 sosend_loan(struct socket *so, struct ui |
|
| vaddr_t sva, eva; |
vaddr_t sva, eva; |
| vsize_t len; |
vsize_t len; |
| vaddr_t lva, va; |
vaddr_t lva, va; |
| int npgs, s, i, error; |
int npgs, i, error; |
| |
|
| if (uio->uio_segflg != UIO_USERSPACE) |
if (uio->uio_segflg != UIO_USERSPACE) |
| return (0); |
return (0); |
| Line 272 sosend_loan(struct socket *so, struct ui |
|
| Line 306 sosend_loan(struct socket *so, struct ui |
|
| /* XXX KDASSERT */ |
/* XXX KDASSERT */ |
| KASSERT(npgs <= M_EXT_MAXPAGES); |
KASSERT(npgs <= M_EXT_MAXPAGES); |
| |
|
| while (socurkva + len > somaxkva) { |
lva = sokvaalloc(len, so); |
| if (sodopendfree(so)) |
|
| continue; |
|
| SOSEND_COUNTER_INCR(&sosend_kvalimit); |
|
| s = splvm(); |
|
| sokvawaiters++; |
|
| (void) tsleep(&socurkva, PVM, "sokva", 0); |
|
| sokvawaiters--; |
|
| splx(s); |
|
| } |
|
| |
|
| lva = uvm_km_valloc_wait(kernel_map, len); |
|
| if (lva == 0) |
if (lva == 0) |
| return (0); |
return 0; |
| socurkva += len; |
|
| |
|
| error = uvm_loan(&uio->uio_procp->p_vmspace->vm_map, sva, len, |
error = uvm_loan(&uio->uio_procp->p_vmspace->vm_map, sva, len, |
| m->m_ext.ext_pgs, UVM_LOAN_TOPAGE); |
m->m_ext.ext_pgs, UVM_LOAN_TOPAGE); |
| if (error) { |
if (error) { |
| uvm_km_free(kernel_map, lva, len); |
sokvafree(lva, len); |
| socurkva -= len; |
|
| return (0); |
return (0); |
| } |
} |
| |
|