Deleted Added
full compact
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 ---