From owner-freebsd-net Thu Sep 14 8:19: 1 2000 Delivered-To: freebsd-net@freebsd.org Received: from hookie.cs.ndsu.NoDak.edu (hookie.cs.ndsu.NoDak.edu [134.129.125.253]) by hub.freebsd.org (Postfix) with ESMTP id 4C56A37B423 for ; Thu, 14 Sep 2000 08:18:57 -0700 (PDT) Received: (from tinguely@localhost) by hookie.cs.ndsu.NoDak.edu (8.9.3/8.9.3) id KAA67788; Thu, 14 Sep 2000 10:18:41 -0500 (CDT) (envelope-from tinguely) Date: Thu, 14 Sep 2000 10:18:41 -0500 (CDT) From: mark tinguely Message-Id: <200009141518.KAA67788@hookie.cs.ndsu.NoDak.edu> To: bmilekic@dsuper.net, wollman@khavrinen.lcs.mit.edu Subject: Re: Clusters larger than PAGE_SIZE and contigmalloc() Cc: freebsd-net@FreeBSD.ORG In-Reply-To: <200009140334.XAA05176@khavrinen.lcs.mit.edu> Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org 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