Пример #1
0
busdma_bufalloc_t 
busdma_bufalloc_create(const char *name, bus_size_t minimum_alignment,
    uma_alloc alloc_func, uma_free free_func, u_int32_t zcreate_flags)
{
	struct busdma_bufalloc *ba;
	struct busdma_bufzone *bz;
	int i;
	bus_size_t cursize;

	ba = malloc(sizeof(struct busdma_bufalloc), M_DEVBUF, 
	    M_ZERO | M_WAITOK);

	ba->min_size = MAX(MIN_ZONE_BUFSIZE, minimum_alignment);

	/*
	 * Each uma zone is created with an alignment of size-1, meaning that
	 * the alignment is equal to the size (I.E., 64 byte buffers are aligned
	 * to 64 byte boundaries, etc).  This allows for a fast efficient test
	 * when deciding whether a pool buffer meets the constraints of a given
	 * tag used for allocation: the buffer is usable if tag->alignment <=
	 * bufzone->size.
	 */
	for (i = 0, bz = ba->buf_zones, cursize = ba->min_size;
	    i < nitems(ba->buf_zones) && cursize <= MAX_ZONE_BUFSIZE;
	    ++i, ++bz, cursize <<= 1) {
		snprintf(bz->name, sizeof(bz->name), "dma %.10s %lu",
		    name, cursize);
		bz->size = cursize;
		bz->umazone = uma_zcreate(bz->name, bz->size,
		    NULL, NULL, NULL, NULL, bz->size - 1, zcreate_flags);
		if (bz->umazone == NULL) {
			busdma_bufalloc_destroy(ba);
			return (NULL);
		}
		if (alloc_func != NULL)
			uma_zone_set_allocf(bz->umazone, alloc_func);
		if (free_func != NULL)
			uma_zone_set_freef(bz->umazone, free_func);
		++ba->num_zones;
	}

	return (ba);
}
Пример #2
0
/*
 * Initialize FreeBSD Network buffer allocation.
 */
static void
mbuf_init(void *dummy)
{

	/*
	 * Configure UMA zones for Mbufs, Clusters, and Packets.
	 */
	zone_mbuf = uma_zcreate(MBUF_MEM_NAME, MSIZE,
	    mb_ctor_mbuf, mb_dtor_mbuf,
#ifdef INVARIANTS
	    trash_init, trash_fini,
#else
	    NULL, NULL,
#endif
	    MSIZE - 1, UMA_ZONE_MAXBUCKET);
	if (nmbufs > 0)
		nmbufs = uma_zone_set_max(zone_mbuf, nmbufs);

	zone_clust = uma_zcreate(MBUF_CLUSTER_MEM_NAME, MCLBYTES,
	    mb_ctor_clust, mb_dtor_clust,
#ifdef INVARIANTS
	    trash_init, trash_fini,
#else
	    NULL, NULL,
#endif
	    UMA_ALIGN_PTR, UMA_ZONE_REFCNT);
	if (nmbclusters > 0)
		nmbclusters = uma_zone_set_max(zone_clust, nmbclusters);

	zone_pack = uma_zsecond_create(MBUF_PACKET_MEM_NAME, mb_ctor_pack,
	    mb_dtor_pack, mb_zinit_pack, mb_zfini_pack, zone_mbuf);

	/* Make jumbo frame zone too. Page size, 9k and 16k. */
	zone_jumbop = uma_zcreate(MBUF_JUMBOP_MEM_NAME, MJUMPAGESIZE,
	    mb_ctor_clust, mb_dtor_clust,
#ifdef INVARIANTS
	    trash_init, trash_fini,
#else
	    NULL, NULL,
#endif
	    UMA_ALIGN_PTR, UMA_ZONE_REFCNT);
	if (nmbjumbop > 0)
		nmbjumbop = uma_zone_set_max(zone_jumbop, nmbjumbop);

	zone_jumbo9 = uma_zcreate(MBUF_JUMBO9_MEM_NAME, MJUM9BYTES,
	    mb_ctor_clust, mb_dtor_clust,
#ifdef INVARIANTS
	    trash_init, trash_fini,
#else
	    NULL, NULL,
#endif
	    UMA_ALIGN_PTR, UMA_ZONE_REFCNT);
	uma_zone_set_allocf(zone_jumbo9, mbuf_jumbo_alloc);
	if (nmbjumbo9 > 0)
		nmbjumbo9 = uma_zone_set_max(zone_jumbo9, nmbjumbo9);

	zone_jumbo16 = uma_zcreate(MBUF_JUMBO16_MEM_NAME, MJUM16BYTES,
	    mb_ctor_clust, mb_dtor_clust,
#ifdef INVARIANTS
	    trash_init, trash_fini,
#else
	    NULL, NULL,
#endif
	    UMA_ALIGN_PTR, UMA_ZONE_REFCNT);
	uma_zone_set_allocf(zone_jumbo16, mbuf_jumbo_alloc);
	if (nmbjumbo16 > 0)
		nmbjumbo16 = uma_zone_set_max(zone_jumbo16, nmbjumbo16);

	zone_ext_refcnt = uma_zcreate(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int),
	    NULL, NULL,
	    NULL, NULL,
	    UMA_ALIGN_PTR, UMA_ZONE_ZINIT);

	/* uma_prealloc() goes here... */

	/*
	 * Hook event handler for low-memory situation, used to
	 * drain protocols and push data back to the caches (UMA
	 * later pushes it back to VM).
	 */
#ifndef __rtems__
	EVENTHANDLER_REGISTER(vm_lowmem, mb_reclaim, NULL,
	    EVENTHANDLER_PRI_FIRST);
#endif /* __rtems__ */

	/*
	 * [Re]set counters and local statistics knobs.
	 * XXX Some of these should go and be replaced, but UMA stat
	 * gathering needs to be revised.
	 */
	mbstat.m_mbufs = 0;
	mbstat.m_mclusts = 0;
	mbstat.m_drain = 0;
	mbstat.m_msize = MSIZE;
	mbstat.m_mclbytes = MCLBYTES;
	mbstat.m_minclsize = MINCLSIZE;
	mbstat.m_mlen = MLEN;
	mbstat.m_mhlen = MHLEN;
	mbstat.m_numtypes = MT_NTYPES;

	mbstat.m_mcfail = mbstat.m_mpfail = 0;
	mbstat.sf_iocnt = 0;
	mbstat.sf_allocwait = mbstat.sf_allocfail = 0;
}
Пример #3
0
/*
 * Initialize FreeBSD Network buffer allocation.
 */
static void
mbuf_init(void *dummy)
{

	/*
	 * Configure UMA zones for Mbufs, Clusters, and Packets.
	 */
	zone_mbuf = uma_zcreate(MBUF_MEM_NAME, MSIZE,
	    mb_ctor_mbuf, mb_dtor_mbuf,
#ifdef INVARIANTS
	    trash_init, trash_fini,
#else
	    NULL, NULL,
#endif
	    MSIZE - 1, UMA_ZONE_MAXBUCKET);
	if (nmbufs > 0)
		nmbufs = uma_zone_set_max(zone_mbuf, nmbufs);
	uma_zone_set_warning(zone_mbuf, "kern.ipc.nmbufs limit reached");
	uma_zone_set_maxaction(zone_mbuf, mb_reclaim);

	zone_clust = uma_zcreate(MBUF_CLUSTER_MEM_NAME, MCLBYTES,
	    mb_ctor_clust,
#ifdef INVARIANTS
	    trash_dtor, trash_init, trash_fini,
#else
	    NULL, NULL, NULL,
#endif
	    UMA_ALIGN_PTR, 0);
	if (nmbclusters > 0)
		nmbclusters = uma_zone_set_max(zone_clust, nmbclusters);
	uma_zone_set_warning(zone_clust, "kern.ipc.nmbclusters limit reached");
	uma_zone_set_maxaction(zone_clust, mb_reclaim);

	zone_pack = uma_zsecond_create(MBUF_PACKET_MEM_NAME, mb_ctor_pack,
	    mb_dtor_pack, mb_zinit_pack, mb_zfini_pack, zone_mbuf);

	/* Make jumbo frame zone too. Page size, 9k and 16k. */
	zone_jumbop = uma_zcreate(MBUF_JUMBOP_MEM_NAME, MJUMPAGESIZE,
	    mb_ctor_clust,
#ifdef INVARIANTS
	    trash_dtor, trash_init, trash_fini,
#else
	    NULL, NULL, NULL,
#endif
	    UMA_ALIGN_PTR, 0);
	if (nmbjumbop > 0)
		nmbjumbop = uma_zone_set_max(zone_jumbop, nmbjumbop);
	uma_zone_set_warning(zone_jumbop, "kern.ipc.nmbjumbop limit reached");
	uma_zone_set_maxaction(zone_jumbop, mb_reclaim);

	zone_jumbo9 = uma_zcreate(MBUF_JUMBO9_MEM_NAME, MJUM9BYTES,
	    mb_ctor_clust,
#ifdef INVARIANTS
	    trash_dtor, trash_init, trash_fini,
#else
	    NULL, NULL, NULL,
#endif
	    UMA_ALIGN_PTR, 0);
	uma_zone_set_allocf(zone_jumbo9, mbuf_jumbo_alloc);
	if (nmbjumbo9 > 0)
		nmbjumbo9 = uma_zone_set_max(zone_jumbo9, nmbjumbo9);
	uma_zone_set_warning(zone_jumbo9, "kern.ipc.nmbjumbo9 limit reached");
	uma_zone_set_maxaction(zone_jumbo9, mb_reclaim);

	zone_jumbo16 = uma_zcreate(MBUF_JUMBO16_MEM_NAME, MJUM16BYTES,
	    mb_ctor_clust,
#ifdef INVARIANTS
	    trash_dtor, trash_init, trash_fini,
#else
	    NULL, NULL, NULL,
#endif
	    UMA_ALIGN_PTR, 0);
	uma_zone_set_allocf(zone_jumbo16, mbuf_jumbo_alloc);
	if (nmbjumbo16 > 0)
		nmbjumbo16 = uma_zone_set_max(zone_jumbo16, nmbjumbo16);
	uma_zone_set_warning(zone_jumbo16, "kern.ipc.nmbjumbo16 limit reached");
	uma_zone_set_maxaction(zone_jumbo16, mb_reclaim);

	/*
	 * Hook event handler for low-memory situation, used to
	 * drain protocols and push data back to the caches (UMA
	 * later pushes it back to VM).
	 */
	EVENTHANDLER_REGISTER(vm_lowmem, mb_reclaim, NULL,
	    EVENTHANDLER_PRI_FIRST);
}