Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 28 Jul 2001 19:47:27 -0400
From:      Bosko Milekic <bmilekic@technokratis.com>
To:        Terry Lambert <tlambert2@mindspring.com>
Cc:        Zhihui Zhang <zzhang@cs.binghamton.edu>, Alfred Perlstein <bright@mu.org>, vishwanath pargaonkar <vishubp@yahoo.com>, freebsd-hackers@FreeBSD.ORG
Subject:   Re: cluster size
Message-ID:  <20010728194727.A54256@technokratis.com>
In-Reply-To: <3B632429.D3FA2EB0@mindspring.com>; from tlambert2@mindspring.com on Sat, Jul 28, 2001 at 01:44:25PM -0700
References:  <Pine.SOL.4.21.0107272018280.13783-100000@opal> <3B632429.D3FA2EB0@mindspring.com>

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

On Sat, Jul 28, 2001 at 01:44:25PM -0700, Terry Lambert wrote:
> Zhihui Zhang wrote:
> > I thought doing a memory free is always safe in an interrupt context. Now
> > it seems doing an allocation of memory is safe too.  Does MCLGET() call
> > vm_page_alloc() or malloc() eventually?  If so, it might block.
> 
> The mbuf allocator uses the zone allocator.

	No, it doesn't. When it needs to dip into the VM code (which is
rare), it uses kmem_malloc() and so vm_page_alloc()-ates via the kmem_object.
Since kmem_map is scaled accordingly to accomodate the mbuf maps (mbuf_map and
clust_map), which are submaps of the former, this works out similarily to
the zone allocator. Note that the mbuf allocations were NEVER done with the
zone allocator.
	The cool thing about managing mbufs via a map is that it *does* allow
for us to unwire associated pages in case we decide to actually free back to
the map. Previously, this was never implemented but with the new allocator,
the framework is present to allow for freeing of pages to be implemented. If
implemented properly, this could allow for the system to re-adapt even if
the character of the load changes with time, without affecting allocation
performance.
 
> The reason this works at interupt is that the page table
> entries for the memory are already in place in the kernel,
> but the actual allocations have not taken place.
>
> When you are running with less than a full complement of
> RAM (e.g. 4G on a 32 bit Intel machine), this will permit
> you to do the allocations of physical RAM later, and have
> a KVA (kernel virtual address) space that exceeds the amount
> of physical memory.
>
> In practice, this means that your system is not specifically
> tuned for particular loading, until the memory is committed
> (when that happens, say, by using all possible mbufs, then
> you are unable to recover the memory to the system memory
> pool: it has become type stable).  This lets you have a mostly
> general system that then commits resources based on the
> character of its load, yet which does not permit the character
> of the load to change over time.

	See previous paragraph.
 
> When you have all the memory you can address in physical
> space, then the problem changes somewhat, and you basically do
> not overcommit resources.
> 
> The upshot of having the page descriptors preallocated,
> however, is that you can allocate in interrupt context, and
> the zone headers are statically allocated at compile time,
> instead of being malloc'ed later in the kernel boot cycle.
> 
> You should look at the "ziniti" and "zalloci" code: the zone
> allocator code.  The mbuf issue has recently been a bit
> obfuscated by the -current commit of a replacement allocator,
> which is mbuf specific.  I think this new allocator has some
> unforgivable drawbacks; you yould be better off looking at
> the 4.3 kernel source code to get an idea of why interrupt
> allocations work.

	Again, the actual allocation code has LITTLE changed even in the new
allocator. I simply don't understand where you get the idea that mbufs were
ever allocated with the zone allocator but I suspect that if you went ahead
and read the new code, you'd realize that for what concerns actually memory
allocation, very little has changed vis-a-vis the older allocator.

> So, in general:
> 
> 1)	Only some allocators can be used at interrupt time
> 2)	If they can, they must precommit kernel address space
> 	to the task
> 3)	Once memory is allocated from one of these pools, it
> 	is never returned to the system for reuse

	This (3) only applies to the zone allocator. With maps, you *can* free
back to the map and unwire the wired pages (freeing physical memory).

> 4)	The general malloc() code _can not_ be used at interrupt
> 	time in FreeBSD (but SVR4's allocator can).

	Huh? Do you realize that in much much earlier versions of FreeBSD
(not long after the import from 4.4BSD, or whatever it was uipc_mbuf.c was
initially imported from) all _MBUFS_ were allocated directly with malloc()?
Obviously, mbufs are allocatable at interrupt time (and always were, afaic
remember). All that you have to make sure to do, when allocating at interrupt
time is to allocate with the M_NOWAIT flag.

> -- Terry

-- 
 Bosko Milekic
 bmilekic@technokratis.com


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




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