2009-08-03 23:30:32 +04:00
|
|
|
.\" $NetBSD: kmem_alloc.9,v 1.11 2009/08/03 19:30:32 rmind Exp $
|
2006-06-25 17:07:49 +04:00
|
|
|
.\"
|
|
|
|
.\" Copyright (c)2006 YAMAMOTO Takashi,
|
|
|
|
.\" All rights reserved.
|
|
|
|
.\"
|
|
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
|
|
.\" modification, are permitted provided that the following conditions
|
|
|
|
.\" are met:
|
|
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
|
|
.\"
|
|
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
.\" SUCH DAMAGE.
|
|
|
|
.\"
|
|
|
|
.\" ------------------------------------------------------------
|
2009-03-29 14:51:53 +04:00
|
|
|
.Dd March 29, 2009
|
2006-06-25 17:07:49 +04:00
|
|
|
.Dt KMEM_ALLOC 9
|
|
|
|
.Os
|
|
|
|
.\" ------------------------------------------------------------
|
|
|
|
.Sh NAME
|
|
|
|
.Nm kmem_alloc
|
2006-06-25 17:24:45 +04:00
|
|
|
.Nd allocate kernel wired memory
|
2006-06-25 17:07:49 +04:00
|
|
|
.\" ------------------------------------------------------------
|
|
|
|
.Sh SYNOPSIS
|
|
|
|
.In sys/kmem.h
|
|
|
|
.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
.Ft void *
|
|
|
|
.Fn kmem_alloc \
|
|
|
|
"size_t size" "km_flag_t kmflags"
|
|
|
|
.\" ------------------------------------------------------------
|
2009-03-29 14:51:53 +04:00
|
|
|
.Pp
|
|
|
|
.Cd "options DEBUG"
|
2006-06-25 17:07:49 +04:00
|
|
|
.Sh DESCRIPTION
|
|
|
|
.Fn kmem_alloc
|
|
|
|
allocates kernel wired memory.
|
|
|
|
It takes the following arguments.
|
|
|
|
.Bl -tag -width kmflags
|
|
|
|
.It Fa size
|
|
|
|
Specify the size of allocation in bytes.
|
|
|
|
.It Fa kmflags
|
2006-06-25 17:24:45 +04:00
|
|
|
Either of the following:
|
2008-12-29 15:43:47 +03:00
|
|
|
.Bl -tag -width KM_NOSLEEP
|
2006-06-25 17:07:49 +04:00
|
|
|
.It KM_SLEEP
|
2009-03-29 15:26:05 +04:00
|
|
|
If the allocation cannot be satisfied immediately, sleep until enough
|
2008-12-29 15:43:47 +03:00
|
|
|
memory is available.
|
2006-06-25 17:07:49 +04:00
|
|
|
.It KM_NOSLEEP
|
|
|
|
Don't sleep.
|
2008-12-29 18:57:01 +03:00
|
|
|
Immediately return
|
|
|
|
.Dv NULL
|
2006-06-25 17:24:45 +04:00
|
|
|
if there is not enough memory available.
|
2008-12-29 15:43:47 +03:00
|
|
|
It should only be used when failure to allocate will not have harmful,
|
|
|
|
user-visible effects.
|
|
|
|
.Pp
|
|
|
|
.Bf -symbolic
|
|
|
|
Use of
|
|
|
|
.Dv KM_NOSLEEP
|
|
|
|
is strongly discouraged as it can create transient, hard to debug failures
|
|
|
|
that occur when the system is under memory pressure.
|
|
|
|
.Ef
|
|
|
|
.Pp
|
|
|
|
In situations where it is not possible to sleep, for example because locks
|
|
|
|
are held by the caller, the code path should be restructured to allow the
|
|
|
|
allocation to be made in another place.
|
2006-06-25 17:07:49 +04:00
|
|
|
.El
|
|
|
|
.El
|
|
|
|
.Pp
|
2006-06-25 17:24:45 +04:00
|
|
|
The contents of allocated memory are uninitialized.
|
2008-01-03 18:59:57 +03:00
|
|
|
.Pp
|
|
|
|
Unlike Solaris, kmem_alloc(0, flags) is illegal.
|
2009-08-03 23:30:32 +04:00
|
|
|
.Sh NOTES
|
2008-12-29 15:43:47 +03:00
|
|
|
Making
|
|
|
|
.Dv KM_SLEEP
|
|
|
|
allocations while holding mutexes or reader/writer locks is discouraged, as the
|
|
|
|
caller can sleep for an unbounded amount of time in order to satisfy the
|
|
|
|
allocation.
|
|
|
|
This can in turn block other threads that wish to acquire locks held by the
|
|
|
|
caller.
|
|
|
|
.Pp
|
|
|
|
For some locks this is permissible or even unavoidable.
|
|
|
|
For others, particularly locks that may be taken from soft interrupt context,
|
|
|
|
it is a serious problem.
|
|
|
|
As a general rule it is better not to allow this type of situation to develop.
|
|
|
|
One way to circumvent the problem is to make allocations speculative and part
|
|
|
|
of a retryable sequence.
|
|
|
|
For example:
|
|
|
|
.Bd -literal
|
|
|
|
retry:
|
|
|
|
/* speculative unlocked check */
|
|
|
|
if (need to allocate) {
|
|
|
|
new_item = kmem_alloc(sizeof(*new_item), KM_SLEEP);
|
|
|
|
} else {
|
|
|
|
new_item = NULL;
|
|
|
|
}
|
|
|
|
mutex_enter(lock);
|
|
|
|
/* check while holding lock for true status */
|
|
|
|
if (need to allocate) {
|
|
|
|
if (new_item == NULL) {
|
|
|
|
mutex_exit(lock);
|
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
consume(new_item);
|
|
|
|
new_item = NULL;
|
|
|
|
}
|
|
|
|
mutex_exit(lock);
|
|
|
|
if (new_item != NULL) {
|
|
|
|
/* did not use it after all */
|
|
|
|
kmem_free(new_item, sizeof(*new_item));
|
|
|
|
}
|
|
|
|
.Ed
|
2006-06-25 17:07:49 +04:00
|
|
|
.\" ------------------------------------------------------------
|
2009-03-29 14:51:53 +04:00
|
|
|
.Sh OPTIONS
|
|
|
|
Kernels compiled with the
|
|
|
|
.Dv DEBUG
|
|
|
|
option perform CPU intensive sanity checks on kmem operations,
|
|
|
|
and include the
|
|
|
|
.Dv kmguard
|
|
|
|
facility which can be enabled at runtime.
|
|
|
|
.Pp
|
|
|
|
.Dv kmguard
|
|
|
|
adds additional, very high overhead runtime verification to kmem operations.
|
|
|
|
To enable it, boot the system with the
|
|
|
|
.Fl d
|
|
|
|
option, which causes the debugger to be entered early during the kernel
|
|
|
|
boot process.
|
|
|
|
Issue commands such as the following:
|
|
|
|
.Bd -literal
|
|
|
|
db\*[Gt] w kmem_guard_depth 0t30000
|
|
|
|
db\*[Gt] c
|
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
This instructs
|
|
|
|
.Dv kmguard
|
|
|
|
to queue up to 60000 (30000*2) pages of unmapped KVA to catch
|
|
|
|
use-after-free type errors.
|
|
|
|
When
|
|
|
|
.Fn kmem_free
|
|
|
|
is called, memory backing a freed item is unmapped and the kernel VA
|
|
|
|
space pushed onto a FIFO.
|
|
|
|
The VA space will not be reused until another 30k items have been freed.
|
2009-03-29 15:26:05 +04:00
|
|
|
Until reused the kernel will catch invalid accesses and panic with a page fault.
|
2009-03-29 14:51:53 +04:00
|
|
|
Limitations:
|
|
|
|
.Bl -bullet
|
|
|
|
.It
|
|
|
|
It has a severe impact on performance.
|
|
|
|
.It
|
|
|
|
It is best used on a 64-bit machine with lots of RAM.
|
|
|
|
.It
|
|
|
|
Allocations larger than PAGE_SIZE bypass the
|
|
|
|
.Dv kmguard
|
|
|
|
facility.
|
|
|
|
.El
|
|
|
|
.Pp
|
|
|
|
kmguard tries to catch the following types of bugs:
|
|
|
|
.Bl -bullet
|
|
|
|
.It
|
2009-03-29 15:26:05 +04:00
|
|
|
Overflow at time of occurrence, by means of a guard page.
|
2009-03-29 14:51:53 +04:00
|
|
|
.It
|
|
|
|
Underflow at
|
|
|
|
.Fn kmem_free ,
|
|
|
|
by using a canary value.
|
|
|
|
.It
|
|
|
|
Invalid pointer or size passed, at
|
|
|
|
.Fn kmem_free .
|
|
|
|
.El
|
2006-06-25 17:07:49 +04:00
|
|
|
.Sh RETURN VALUES
|
2006-11-04 15:39:50 +03:00
|
|
|
On success,
|
2006-06-25 17:07:49 +04:00
|
|
|
.Fn kmem_alloc
|
2006-11-04 15:39:50 +03:00
|
|
|
returns a pointer to allocated memory.
|
2006-06-25 17:07:49 +04:00
|
|
|
Otherwise, it returns
|
|
|
|
.Dv NULL .
|
|
|
|
.\" ------------------------------------------------------------
|
|
|
|
.Sh SEE ALSO
|
|
|
|
.Xr intro 9 ,
|
|
|
|
.Xr kmem_free 9 ,
|
|
|
|
.Xr kmem_zalloc 9 ,
|
2007-02-17 11:50:04 +03:00
|
|
|
.Xr malloc 9 ,
|
2007-02-17 02:13:05 +03:00
|
|
|
.Xr memoryallocators 9
|
2006-06-25 17:07:49 +04:00
|
|
|
.\" ------------------------------------------------------------
|
|
|
|
.Sh CAVEATS
|
|
|
|
.Fn kmem_alloc
|
2008-12-29 15:43:47 +03:00
|
|
|
cannot be used from interrupt context, from a soft interrupt, or from
|
|
|
|
a callout.
|
|
|
|
Use
|
|
|
|
.Xr pool_cache 9
|
|
|
|
in these situations.
|
2006-06-25 17:07:49 +04:00
|
|
|
.\" ------------------------------------------------------------
|
|
|
|
.Sh SECURITY CONSIDERATION
|
|
|
|
As the allocated memory is uninitialized, it can contain security-sensitive
|
|
|
|
data left by its previous user.
|
2006-06-25 17:24:45 +04:00
|
|
|
It's the caller's responsibility not to expose it to the world.
|