Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/kern/uipc_socket.c,v retrieving revision 1.135 retrieving revision 1.136 diff -u -p -r1.135 -r1.136 --- src/sys/kern/uipc_socket.c 2007/03/12 18:18:34 1.135 +++ src/sys/kern/uipc_socket.c 2007/03/12 21:33:08 1.136 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_socket.c,v 1.135 2007/03/12 18:18:34 ad Exp $ */ +/* $NetBSD: uipc_socket.c,v 1.136 2007/03/12 21:33:08 ad Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.135 2007/03/12 18:18:34 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.136 2007/03/12 21:33:08 ad Exp $"); #include "opt_sock_counters.h" #include "opt_sosend_loan.h" @@ -92,6 +92,8 @@ __KERNEL_RCSID(0, "$NetBSD: uipc_socket. #include #include #include +#include +#include #include @@ -136,7 +138,7 @@ int sock_loan_thresh = -1; int sock_loan_thresh = 4096; #endif -static struct simplelock so_pendfree_slock = SIMPLELOCK_INITIALIZER; +static kmutex_t so_pendfree_lock; static struct mbuf *so_pendfree; #ifndef SOMAXKVA @@ -144,7 +146,7 @@ static struct mbuf *so_pendfree; #endif int somaxkva = SOMAXKVA; static int socurkva; -static int sokvawaiters; +static kcondvar_t socurkva_cv; #define SOCK_LOAN_CHUNK 65536 @@ -154,11 +156,9 @@ static size_t sodopendfreel(void); static vsize_t sokvareserve(struct socket *so, vsize_t len) { - int s; int error; - s = splvm(); - simple_lock(&so_pendfree_slock); + mutex_enter(&so_pendfree_lock); while (socurkva + len > somaxkva) { size_t freed; @@ -176,33 +176,25 @@ sokvareserve(struct socket *so, vsize_t continue; SOSEND_COUNTER_INCR(&sosend_kvalimit); - sokvawaiters++; - error = ltsleep(&socurkva, PVM | PCATCH, "sokva", 0, - &so_pendfree_slock); - sokvawaiters--; + error = cv_wait_sig(&socurkva_cv, &so_pendfree_lock); if (error) { len = 0; break; } } socurkva += len; - simple_unlock(&so_pendfree_slock); - splx(s); + mutex_exit(&so_pendfree_lock); return len; } static void sokvaunreserve(vsize_t len) { - int s; - s = splvm(); - simple_lock(&so_pendfree_slock); + mutex_enter(&so_pendfree_lock); socurkva -= len; - if (sokvawaiters) - wakeup(&socurkva); - simple_unlock(&so_pendfree_slock); - splx(s); + cv_broadcast(&socurkva_cv); + mutex_exit(&so_pendfree_lock); } /* @@ -287,24 +279,20 @@ sodoloanfree(struct vm_page **pgs, void static size_t sodopendfree() { - int s; size_t rv; - s = splvm(); - simple_lock(&so_pendfree_slock); + mutex_enter(&so_pendfree_lock); rv = sodopendfreel(); - simple_unlock(&so_pendfree_slock); - splx(s); + mutex_exit(&so_pendfree_lock); return rv; } /* * sodopendfreel: free mbufs on "pendfree" list. - * unlock and relock so_pendfree_slock when freeing mbufs. + * unlock and relock so_pendfree_lock when freeing mbufs. * - * => called with so_pendfree_slock held. - * => called at splvm. + * => called with so_pendfree_lock held. */ static size_t @@ -312,7 +300,7 @@ sodopendfreel() { size_t rv = 0; - LOCK_ASSERT(simple_lock_held(&so_pendfree_slock)); + KASSERT(mutex_owned(&so_pendfree_lock)); for (;;) { struct mbuf *m; @@ -322,8 +310,7 @@ sodopendfreel() if (m == NULL) break; so_pendfree = NULL; - simple_unlock(&so_pendfree_slock); - /* XXX splx */ + mutex_exit(&so_pendfree_lock); for (; m != NULL; m = next) { next = m->m_next; @@ -335,8 +322,7 @@ sodopendfreel() pool_cache_put(&mbpool_cache, m); } - /* XXX splvm */ - simple_lock(&so_pendfree_slock); + mutex_enter(&so_pendfree_lock); } return (rv); @@ -345,7 +331,6 @@ sodopendfreel() void soloanfree(struct mbuf *m, void *buf, size_t size, void *arg) { - int s; if (m == NULL) { @@ -364,14 +349,11 @@ soloanfree(struct mbuf *m, void *buf, si * because we need to put kva back to kernel_map. */ - s = splvm(); - simple_lock(&so_pendfree_slock); + mutex_enter(&so_pendfree_lock); m->m_next = so_pendfree; so_pendfree = m; - if (sokvawaiters) - wakeup(&socurkva); - simple_unlock(&so_pendfree_slock); - splx(s); + cv_broadcast(&socurkva_cv); + mutex_exit(&so_pendfree_lock); } static long @@ -450,6 +432,9 @@ void soinit(void) { + mutex_init(&so_pendfree_lock, MUTEX_DRIVER, IPL_VM); + cv_init(&socurkva_cv, "sokva"); + /* Set the initial adjusted socket buffer size. */ if (sb_max_set(sb_max)) panic("bad initial sb_max value: %lu", sb_max); @@ -1795,7 +1780,6 @@ sysctl_kern_somaxkva(SYSCTLFN_ARGS) { int error, new_somaxkva; struct sysctlnode node; - int s; new_somaxkva = somaxkva; node = *rnode; @@ -1807,12 +1791,10 @@ sysctl_kern_somaxkva(SYSCTLFN_ARGS) if (new_somaxkva < (16 * 1024 * 1024)) /* sanity */ return (EINVAL); - s = splvm(); - simple_lock(&so_pendfree_slock); + mutex_enter(&so_pendfree_lock); somaxkva = new_somaxkva; - wakeup(&socurkva); - simple_unlock(&so_pendfree_slock); - splx(s); + cv_broadcast(&socurkva_cv); + mutex_exit(&so_pendfree_lock); return (error); }