uipc_mbuf.c (268530) | uipc_mbuf.c (268535) |
---|---|
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 --- 16 unchanged lines hidden (view full) --- 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 30 */ 31 32#include <sys/cdefs.h> | 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 --- 16 unchanged lines hidden (view full) --- 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/kern/uipc_mbuf.c 268530 2014-07-11 14:34:29Z glebius $"); | 33__FBSDID("$FreeBSD: head/sys/kern/uipc_mbuf.c 268535 2014-07-11 19:40:50Z glebius $"); |
34 35#include "opt_param.h" 36#include "opt_mbuf_stress_test.h" 37#include "opt_mbuf_profiling.h" 38 39#include <sys/param.h> 40#include <sys/systm.h> 41#include <sys/kernel.h> --- 240 unchanged lines hidden (view full) --- 282 283/* 284 * Non-directly-exported function to clean up after mbufs with M_EXT 285 * storage attached to them if the reference count hits 1. 286 */ 287void 288mb_free_ext(struct mbuf *m) 289{ | 34 35#include "opt_param.h" 36#include "opt_mbuf_stress_test.h" 37#include "opt_mbuf_profiling.h" 38 39#include <sys/param.h> 40#include <sys/systm.h> 41#include <sys/kernel.h> --- 240 unchanged lines hidden (view full) --- 282 283/* 284 * Non-directly-exported function to clean up after mbufs with M_EXT 285 * storage attached to them if the reference count hits 1. 286 */ 287void 288mb_free_ext(struct mbuf *m) 289{ |
290 int skipmbuf; | 290 int freembuf; |
291 | 291 |
292 KASSERT((m->m_flags & M_EXT) == M_EXT, ("%s: M_EXT not set", __func__)); 293 KASSERT(m->m_ext.ext_cnt != NULL, ("%s: ext_cnt not set", __func__)); | 292 KASSERT(m->m_flags & M_EXT, ("%s: M_EXT not set on %p", __func__, m)); |
294 295 /* | 293 294 /* |
296 * check if the header is embedded in the cluster | 295 * Check if the header is embedded in the cluster. |
297 */ | 296 */ |
298 skipmbuf = (m->m_flags & M_NOFREE); | 297 freembuf = (m->m_flags & M_NOFREE) ? 0 : 1; |
299 | 298 |
300 /* Free attached storage if this mbuf is the only reference to it. */ 301 if (*(m->m_ext.ext_cnt) == 1 || 302 atomic_fetchadd_int(m->m_ext.ext_cnt, -1) == 1) { | 299 switch (m->m_ext.ext_type) { 300 case EXT_SFBUF: 301 sf_ext_free(m->m_ext.ext_arg1, m->m_ext.ext_arg2); 302 break; 303 default: 304 KASSERT(m->m_ext.ext_cnt != NULL, 305 ("%s: no refcounting pointer on %p", __func__, m)); 306 /* 307 * Free attached storage if this mbuf is the only 308 * reference to it. 309 */ 310 if (*(m->m_ext.ext_cnt) != 1) { 311 if (atomic_fetchadd_int(m->m_ext.ext_cnt, -1) != 1) 312 break; 313 } 314 |
303 switch (m->m_ext.ext_type) { 304 case EXT_PACKET: /* The packet zone is special. */ 305 if (*(m->m_ext.ext_cnt) == 0) 306 *(m->m_ext.ext_cnt) = 1; 307 uma_zfree(zone_pack, m); 308 return; /* Job done. */ 309 case EXT_CLUSTER: 310 uma_zfree(zone_clust, m->m_ext.ext_buf); 311 break; 312 case EXT_JUMBOP: 313 uma_zfree(zone_jumbop, m->m_ext.ext_buf); 314 break; 315 case EXT_JUMBO9: 316 uma_zfree(zone_jumbo9, m->m_ext.ext_buf); 317 break; 318 case EXT_JUMBO16: 319 uma_zfree(zone_jumbo16, m->m_ext.ext_buf); 320 break; | 315 switch (m->m_ext.ext_type) { 316 case EXT_PACKET: /* The packet zone is special. */ 317 if (*(m->m_ext.ext_cnt) == 0) 318 *(m->m_ext.ext_cnt) = 1; 319 uma_zfree(zone_pack, m); 320 return; /* Job done. */ 321 case EXT_CLUSTER: 322 uma_zfree(zone_clust, m->m_ext.ext_buf); 323 break; 324 case EXT_JUMBOP: 325 uma_zfree(zone_jumbop, m->m_ext.ext_buf); 326 break; 327 case EXT_JUMBO9: 328 uma_zfree(zone_jumbo9, m->m_ext.ext_buf); 329 break; 330 case EXT_JUMBO16: 331 uma_zfree(zone_jumbo16, m->m_ext.ext_buf); 332 break; |
321 case EXT_SFBUF: | |
322 case EXT_NET_DRV: 323 case EXT_MOD_TYPE: 324 case EXT_DISPOSABLE: 325 *(m->m_ext.ext_cnt) = 0; 326 uma_zfree(zone_ext_refcnt, __DEVOLATILE(u_int *, 327 m->m_ext.ext_cnt)); 328 /* FALLTHROUGH */ 329 case EXT_EXTREF: 330 KASSERT(m->m_ext.ext_free != NULL, 331 ("%s: ext_free not set", __func__)); 332 (*(m->m_ext.ext_free))(m, m->m_ext.ext_arg1, 333 m->m_ext.ext_arg2); 334 break; 335 default: 336 KASSERT(m->m_ext.ext_type == 0, 337 ("%s: unknown ext_type", __func__)); 338 } 339 } | 333 case EXT_NET_DRV: 334 case EXT_MOD_TYPE: 335 case EXT_DISPOSABLE: 336 *(m->m_ext.ext_cnt) = 0; 337 uma_zfree(zone_ext_refcnt, __DEVOLATILE(u_int *, 338 m->m_ext.ext_cnt)); 339 /* FALLTHROUGH */ 340 case EXT_EXTREF: 341 KASSERT(m->m_ext.ext_free != NULL, 342 ("%s: ext_free not set", __func__)); 343 (*(m->m_ext.ext_free))(m, m->m_ext.ext_arg1, 344 m->m_ext.ext_arg2); 345 break; 346 default: 347 KASSERT(m->m_ext.ext_type == 0, 348 ("%s: unknown ext_type", __func__)); 349 } 350 } |
340 if (skipmbuf) 341 return; | |
342 | 351 |
343 /* 344 * Free this mbuf back to the mbuf zone with all m_ext 345 * information purged. 346 */ 347 m->m_ext.ext_buf = NULL; 348 m->m_ext.ext_free = NULL; 349 m->m_ext.ext_arg1 = NULL; 350 m->m_ext.ext_arg2 = NULL; 351 m->m_ext.ext_cnt = NULL; 352 m->m_ext.ext_size = 0; 353 m->m_ext.ext_type = 0; 354 m->m_ext.ext_flags = 0; 355 m->m_flags &= ~M_EXT; 356 uma_zfree(zone_mbuf, m); | 352 if (freembuf) 353 uma_zfree(zone_mbuf, m); |
357} 358 359/* 360 * Attach the cluster from *m to *n, set up m_ext in *n 361 * and bump the refcount of the cluster. 362 */ 363static void 364mb_dupcl(struct mbuf *n, struct mbuf *m) 365{ | 354} 355 356/* 357 * Attach the cluster from *m to *n, set up m_ext in *n 358 * and bump the refcount of the cluster. 359 */ 360static void 361mb_dupcl(struct mbuf *n, struct mbuf *m) 362{ |
366 KASSERT((m->m_flags & M_EXT) == M_EXT, ("%s: M_EXT not set", __func__)); 367 KASSERT(m->m_ext.ext_cnt != NULL, ("%s: ext_cnt not set", __func__)); 368 KASSERT((n->m_flags & M_EXT) == 0, ("%s: M_EXT set", __func__)); | |
369 | 363 |
370 if (*(m->m_ext.ext_cnt) == 1) 371 *(m->m_ext.ext_cnt) += 1; 372 else 373 atomic_add_int(m->m_ext.ext_cnt, 1); 374 n->m_ext.ext_buf = m->m_ext.ext_buf; 375 n->m_ext.ext_free = m->m_ext.ext_free; 376 n->m_ext.ext_arg1 = m->m_ext.ext_arg1; 377 n->m_ext.ext_arg2 = m->m_ext.ext_arg2; 378 n->m_ext.ext_size = m->m_ext.ext_size; 379 n->m_ext.ext_cnt = m->m_ext.ext_cnt; 380 n->m_ext.ext_type = m->m_ext.ext_type; 381 n->m_ext.ext_flags = m->m_ext.ext_flags; | 364 KASSERT(m->m_flags & M_EXT, ("%s: M_EXT not set on %p", __func__, m)); 365 KASSERT(!(n->m_flags & M_EXT), ("%s: M_EXT set on %p", __func__, n)); 366 367 switch (m->m_ext.ext_type) { 368 case EXT_SFBUF: 369 sf_ext_ref(m->m_ext.ext_arg1, m->m_ext.ext_arg2); 370 break; 371 default: 372 KASSERT(m->m_ext.ext_cnt != NULL, 373 ("%s: no refcounting pointer on %p", __func__, m)); 374 if (*(m->m_ext.ext_cnt) == 1) 375 *(m->m_ext.ext_cnt) += 1; 376 else 377 atomic_add_int(m->m_ext.ext_cnt, 1); 378 } 379 380 bcopy(&m->m_ext, &n->m_ext, sizeof(m->m_ext)); |
382 n->m_flags |= M_EXT; 383 n->m_flags |= m->m_flags & M_RDONLY; 384} 385 386/* 387 * Clean up mbuf (chain) from any tags and packet headers. 388 * If "all" is set then the first mbuf in the chain will be 389 * cleaned too. --- 1793 unchanged lines hidden --- | 381 n->m_flags |= M_EXT; 382 n->m_flags |= m->m_flags & M_RDONLY; 383} 384 385/* 386 * Clean up mbuf (chain) from any tags and packet headers. 387 * If "all" is set then the first mbuf in the chain will be 388 * cleaned too. --- 1793 unchanged lines hidden --- |