uipc_mbuf.c (70254) | uipc_mbuf.c (70858) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1988, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 | 1/* 2 * Copyright (c) 1982, 1986, 1988, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 |
34 * $FreeBSD: head/sys/kern/uipc_mbuf.c 70254 2000-12-21 21:44:31Z bmilekic $ | 34 * $FreeBSD: head/sys/kern/uipc_mbuf.c 70858 2001-01-09 23:58:56Z bmilekic $ |
35 */ 36 37#include "opt_param.h" 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/malloc.h> 41#include <sys/mbuf.h> 42#include <sys/mutex.h> --- 261 unchanged lines hidden (view full) --- 304 * Once the mb_map has been exhausted and if the call to the allocation macros 305 * (or, in some cases, functions) is with M_TRYWAIT, then it is necessary to 306 * rely solely on reclaimed mbufs. 307 * 308 * Here we request for the protocols to free up some resources and, if we 309 * still cannot get anything, then we wait for an mbuf to be freed for a 310 * designated (mbuf_wait) time. 311 * | 35 */ 36 37#include "opt_param.h" 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/malloc.h> 41#include <sys/mbuf.h> 42#include <sys/mutex.h> --- 261 unchanged lines hidden (view full) --- 304 * Once the mb_map has been exhausted and if the call to the allocation macros 305 * (or, in some cases, functions) is with M_TRYWAIT, then it is necessary to 306 * rely solely on reclaimed mbufs. 307 * 308 * Here we request for the protocols to free up some resources and, if we 309 * still cannot get anything, then we wait for an mbuf to be freed for a 310 * designated (mbuf_wait) time. 311 * |
312 * Must be called with the mmbfree mutex held, and we will probably end 313 * up recursing into that lock from some of the drain routines, but 314 * this should be okay, as long as we don't block there, or attempt 315 * to allocate from them (theoretically impossible). | 312 * Must be called with the mmbfree mutex held. |
316 */ 317struct mbuf * 318m_mballoc_wait(void) 319{ 320 struct mbuf *p = NULL; 321 322 /* 323 * See if we can drain some resources out of the protocols. | 313 */ 314struct mbuf * 315m_mballoc_wait(void) 316{ 317 struct mbuf *p = NULL; 318 319 /* 320 * See if we can drain some resources out of the protocols. |
321 * We drop the mmbfree mutex to avoid recursing into it in some of 322 * the drain routines. Clearly, we're faced with a race here because 323 * once something is freed during the drain, it may be grabbed right 324 * from under us by some other thread. But we accept this possibility 325 * in order to avoid a potentially large lock recursion and, more 326 * importantly, to avoid a potential lock order reversal which may 327 * result in deadlock (See comment above m_reclaim()). |
|
324 */ | 328 */ |
329 mtx_exit(&mmbfree.m_mtx, MTX_DEF); |
|
325 m_reclaim(); | 330 m_reclaim(); |
331 332 mtx_enter(&mmbfree.m_mtx, MTX_DEF); |
|
326 _MGET(p, M_DONTWAIT); 327 328 if (p == NULL) { 329 m_mballoc_wid++; 330 if (msleep(&m_mballoc_wid, &mmbfree.m_mtx, PVM, "mballc", 331 mbuf_wait) == EWOULDBLOCK) 332 m_mballoc_wid--; 333 --- 110 unchanged lines hidden (view full) --- 444 atomic_add_long(&mbstat.m_drops, 1); 445 446 return (p); 447} 448 449/* 450 * m_reclaim: drain protocols in hopes to free up some resources... 451 * | 333 _MGET(p, M_DONTWAIT); 334 335 if (p == NULL) { 336 m_mballoc_wid++; 337 if (msleep(&m_mballoc_wid, &mmbfree.m_mtx, PVM, "mballc", 338 mbuf_wait) == EWOULDBLOCK) 339 m_mballoc_wid--; 340 --- 110 unchanged lines hidden (view full) --- 451 atomic_add_long(&mbstat.m_drops, 1); 452 453 return (p); 454} 455 456/* 457 * m_reclaim: drain protocols in hopes to free up some resources... 458 * |
452 * Should be called with mmbfree.m_mtx mutex held. We will most likely 453 * recursively grab it from within some drain routines, but that's okay, 454 * as the mutex will never be completely released until we let go of it 455 * after our m_reclaim() is over. 456 * 457 * Note: Drain routines are only allowed to free mbufs (and mclusters, 458 * as a consequence, if need be). They are not allowed to allocate 459 * new ones (that would defeat the purpose, anyway). | 459 * XXX: No locks should be held going in here. The drain routines have 460 * to presently acquire some locks which raises the possibility of lock 461 * order violation if we're holding any mutex if that mutex is acquired in 462 * reverse order relative to one of the locks in the drain routines. |
460 */ 461static void 462m_reclaim() 463{ 464 register struct domain *dp; 465 register struct protosw *pr; 466 467 for (dp = domains; dp; dp = dp->dom_next) --- 720 unchanged lines hidden --- | 463 */ 464static void 465m_reclaim() 466{ 467 register struct domain *dp; 468 register struct protosw *pr; 469 470 for (dp = domains; dp; dp = dp->dom_next) --- 720 unchanged lines hidden --- |