Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Apr 2002 08:20:41 -0700
From:      Terry Lambert <tlambert2@mindspring.com>
To:        paleph@pacbell.net
Cc:        freebsd-hackers@Freebsd.org
Subject:   Re: question on use of kernel memory allocation routines
Message-ID:  <3CC6CD49.19DE7AEA@mindspring.com>
References:  <200204241414.g3OEEhB02234@pacbell.net>

next in thread | previous in thread | raw e-mail | index | archive | help
paleph@pacbell.net wrote:
> --------------------------------
> 1. What is the correct (standard) way to add a new
>    system call to the kernel so it will be
>    compatible with 4.* and 5.* ?

You can't use the same code unmodified.  %.x requires locking
that is implicit in 4.x.

System calls are also "special".  THe closest you can get is
to use a loadable module that adds a system call into one of
the reserved slots.  For adding actual system calls statically,
you have to modify syscalls.master, and then run the per script
to recreate the necessary header files (these are checked into
the source tree, instead of recreated on each kernel build,
which is probably incredibly wrong).  You will also have to
rebuild libc, so that the stub gets compiled into a system call
stub in libc, and, if it deals with a file descriptor, you will
have to procide a wrapper for the call for libc_r, so that it
can lock the user space threading structure for the fd before
it mconverts the blocking call into a non-blocking call plus a
thread context switch.


> --------------------------------
> 2. I notice a large number of memory allocation routines that
>    are used through out the kernel.

Yes.  Incredibly annoying, isn't it?


>    I tried looking at the
>    FreeBSD archives and also did a google search to see what
>    I could find about their semantics. I did not have very good
>    success. The kernel file comments with these interfaces were
>    not very helpful in determining when they should be used.

They aren't very accurate, either.  The zone allocator comments,
in particular, are very wrong.  They obfuscate what's really going
on.  In many allocations, you can see that the code required to
obtain the backing page(s) recalculates values that you could
precalculate at zone definition time, making the allocation much
more expensive than it really has to be.

Most of this code is replaces in 5.x -current, using Jeff's SLAB
allocator code.

>    Is there any documentation on them and when they should be
>    used. I could probably get away with just using malloc() and
>    free(), however it would be nice to understand what these
>    memory allocation functions do in case they are more appropriate.

Use the SLAB code in code intended for use with 5.x, so you can
avoid most of the locking issues automatically.


>     vm_offset_t
>     kmem_alloc_pageable(map, size)

Allocate something that can be paged, and which you guarantee
will never be referenced at interrupt time and/or in the paging
path.  Use this routine, if you can, since it scales to the
largest footprint possible, as long as the amount of memory you
are using is not a significant fraction of the 32 bit address
space (if you have that much physical RAM, it's pretty much not
worth doing that, because it puts the allocated memory into
contention with user processes for swapping, and even if LRU'ing
were a good idea, having the LRU be the same for the UVA and KVA
is intrinsically a bad idea).


>     vm_offset_t
>     kmem_alloc_nofault(map, size)

Alloc such that you won't take a fault to satisfy it.  This is
for "fast path" allocations that aren't permitted to stall to
service the fault.


>     vm_offset_t
>     kmem_alloc(map, size)

Standard allocation.



>     void
>     kmem_free(map, addr, size)

Standard free.


>     vm_map_t
>     kmem_suballoc(parent, min, max, size)

Don't remember.


>     vm_offset_t
>     kmem_malloc(map, size, flags)

Standard malloc.


>     vm_offset_t
>     kmem_alloc_wait(map, size)

Allocate, and stall the caller to wait for it, if you have to.  Not
usable from interrupt mode or traps, useful for system calls; must
be done in the context of a current process, so that there is a sleep
address available.


>     void
>     kmem_free_wakeup(map, addr, size)

Wakeup people who are starving for this resource (if any).


>     void
>     kmem_init(start, end)

Obvious usage.


> Any help or pointers to documentation is appreciated

See section 9 of the manual page.  Don't expect to use the same
mechanisms in 4.x and 5.x.

-- Terry

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?3CC6CD49.19DE7AEA>