void
*
kmem_alloc(
size_t size
, km_flag_t kmflags
)
)
allocates kernel wired memory.
It takes the following arguments.
size
kmflags
Use of
KM_NOSLEEP
is strongly discouraged as it can create transient, hard to debug failures
that occur when the system is under memory pressure.
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.
The contents of allocated memory are uninitialized.
Unlike Solaris, kmem_alloc(0, flags) is illegal.
Making
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.
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:
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));
}
)
returns a pointer to allocated memory.
Otherwise, it returns
NULL
.
)
cannot be used from interrupt context, from a soft interrupt, or from
a callout.
Use
pool_cache(9)
in these situations.