Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Sep 2000 10:18:41 -0500 (CDT)
From:      mark tinguely <tinguely@hookie.cs.ndsu.NoDak.edu>
To:        bmilekic@dsuper.net, wollman@khavrinen.lcs.mit.edu
Cc:        freebsd-net@FreeBSD.ORG
Subject:   Re: Clusters larger than PAGE_SIZE and contigmalloc()
Message-ID:  <200009141518.KAA67788@hookie.cs.ndsu.NoDak.edu>
In-Reply-To: <200009140334.XAA05176@khavrinen.lcs.mit.edu>

next in thread | previous in thread | raw e-mail | index | archive | help

my IDT NICStAR ATM card driver allocates contiguous memory for
mbuf external buffers. the card can use buffers larger than a physical
page, but I don't use it that way. there were a couple problems that
helped manually allocating buffers contiguously; one is in a couple
occasions, such as raw cell processing, I had the physical address of
the external buffer from the card but I need to use the kernel virtual
address.

The ATM card needs to have external buffers programed into a queue to
be used when the data arrives. Instead allocating and deallocating mbufs
as packets came in and were processed, as an experiment, I am mucked up
the MBUF even more by making the mbuf structure and the external buffer
permanent connected:

#define M_PERM		0x8000	/* permanently allocated */

/*
 * MFREE(struct mbuf *m, struct mbuf *n)
 * Free a single mbuf and associated external storage.
 * Place the successor, if any, in n.
 */
#define MFREE(m, n) MBUFLOCK(						\
	struct mbuf *_mm = (m);						\
									\
	KASSERT(_mm->m_type != MT_FREE, ("freeing free mbuf"));		\
	mbstat.m_mtypes[_mm->m_type]--;					\
	if (_mm->m_flags & M_EXT)					\
		MEXTFREE1(m);						\
	(n) = _mm->m_next;						\
	if (_mm->m_flags & M_PERM) {					\
		_mm->m_next = (struct mbuf *) 0;			\
	} else {							\
		_mm->m_type = MT_FREE;					\
		mbstat.m_mtypes[MT_FREE]++;				\
		_mm->m_next = mmbfree;					\
		mmbfree = _mm;						\
		MMBWAKEUP();						\
	}								\
)

when the packet fills a buffer, I can have it return the kernel virtual
address of the mbuf holding the external buffer, and link up the new
mbuf to the chain that was come in so far. I haven't actually counted
how much this really saves vs. the extra space required for the permanently
allocated mbufs.

the downside with having your own pool of mbuf is that you are at the
mercy of other code that may overwrite your ext_free() routine and you
never get your buffers back. I suspect this is happening to one person
using my driver.

--mark tinguely.


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200009141518.KAA67788>