DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
SCO OpenServer

kmem_alloc(D3oddi)


kmem_alloc, kmem_zalloc -- allocate kernel memory

Synopsis

   #include <sys/types.h>
   #include <sys/param.h>
   #include <sys/kmem.h>
   

void *kmem_alloc(size_t nbytes, int flags);

void *kmem_zalloc(size_t nbytes, int flags);

Description

The kmem_alloc( ) and kmem_zalloc( ) functions allocate extents of kernel memory dynamically from a set of memory pools. The extent returned is at least nbytes bytes long and is aligned on a 4-byte boundary. The address of the start of the extent is returned.

The actual size of the memory allocated may be larger than requested. Callers should act as if precisely nbytes were returned. The implementation reserves the right to change the underlying details of the allocator.

kmem_zalloc( ) is identical to kmem_alloc( ), with the additional feature of setting the contents of the allocated buffer to all zeros before returning. kmem_zalloc( ) is a special case of kmem_alloc( ); for the rest of this document, information about kmem_alloc( ) also applies to kmem_zalloc( ).

Arguments


nbytes
minimum required size of the memory extent, in bytes.

flags
specifes a bitmask of flags that control the characteristics of the allocation. The supported flags are:

KM_SLEEP and KM_NOSLEEP
Specify whether or not the caller is willing to sleep to allocate memory. The flags are mutually exclusive and at least one of them must be provided. If KM_SLEEP is used, then the function will not return to the caller until the requested memory extent has been allocated. If KM_NOSLEEP is used, then the function will fail and return NULL if memory is not immediately available.

The KM_NOSLEEP flag must be used when kmem_alloc( ) is called from interrupt or initialization context.


KM_NO_DMA
Specify that the memory extent returned may be above 16MB and so not accessible by the system's ISA DMA controller. This flag should be set unless the memory obtained will actually be used as an ISA DMA buffer, which can only be located in the lower 16MB of memory

Return values

kmem_alloc( ) returns the address of the beginning of the requested memory extent. If KM_NOSLEEP is specified and the memory can not be allocated without sleeping, NULL is returned.

Usage

The kmem_alloc( ) and kmem_zalloc( ) functions are fast and lightweight so that drivers do not need to maintain local freelists. See ``Memory allocation'' in HDK Technical Reference for a full discussion of considerations related to memory allocation.

In most cases, kmem_alloc( ) should pass the KM_NO_DMA flag so that the memory can be allocated above the 16MB boundary. Memory that is allocated without this flag comes from the ISA DMA-able memory pool of memory below 16MB. This is an extremely limited resource that should be consumed only when absolutely necessary, such as when you will be performing ISA DMA to or from the allocated memory. PCI DMA and other newer forms of DMA do not require memory allocation in the lower 16MB range.

The following implementation details are subject to change and are provided only to help developers understand current behavior.

kmem_alloc( ) allocates memory from pools of power-of-2 chunk sizes from 16 to 8192 bytes. The sizes of these pools are determined by the psz[] values in the /etc/conf/pack.d/kernel/space.c file. A kernel daemon, kmdaemon, runs periodically to replenish pools that are close to exhaustion. This asynchronous allocation reduces the probability that a specific caller of kmem_alloc( ) will have to wait for an underlying allocation.

When allocations are made quickly, it is possible for the pools to be exhausted before kmdaemon can run. In that case, kmem_alloc( ) calls the underlying allocator, sptalloc(D3oddi), directly. This happens only if the pool is completely empty and must be replenished to satisfy the call.

If a pool must be replenished from a kmem_alloc( ) call that was passed with the KM_NOSLEEP flag specified, The similar NOSLEEP flag is passed to sptalloc( ). As a result, allocation can fail, causing the overall kmem_alloc( ) to fail. In this event, a flag is set that causes kmdaemon to run as soon as possible, without waiting for its next periodic timer event.

A call to kmem_alloc( ) with the KM_SLEEP flag never returns NULL. If memory is not immediately available, it sleeps until the memory is available. If it returns at all, the returned pointer is a valid pointer to valid memory of the desired variety and does not need to be checked. The length of the sleep( ) is not bounded; under extreme and persistent shortages of memory, a caller could sleep ``forever'', meaning until the system is shutdown. This should not be a matter of great concern to a driver writer; it is a condition that can occur only when the memory allocation subsystem is so compromised that the system can only recover by being rebooted.

When kmem_alloc( ) is passed the KM_NOSLEEP flag, it will occasionally return a NULL pointer. The caller must check for this and behave correctly.

If an allocation fails, this implies that a pool was exhausted and the calling process was not allowed to sleep until memory was available. In order for a subsequent allocation to succeed, the allocator must be allowed to run in its own context. For example, if a caller is trying to allocate memory from an interrupt context, a failure will persist until the caller returns from its interrupt, allowing kmdaemon to run. Drivers should deal with this by (1) minimizing the need to allocate memory at interrupt time and (2) having a strategy that allows activity to be deferred until a later time (after returning from the interrupt and allowing kmdaemon to run).

Context and synchronization

If flag contains KM_SLEEP, user or blockable context only.

If flag contains KM_NOSLEEP, any context.

Hardware applicability

All

Version applicability

oddi: 3, 3mp, 4, 4mp, 5, 5mp, 6, 6mp

Differences between versions

The calling sequence and behavior of kmem_alloc( ) and kmem_zalloc( ) is the same for all ODDI versions, but the internal behavior of the memory pool allocator changes slightly for ODDI 6 and later versions. In earlier versions, kmem_alloc( ) tries to allocate memory from the existing pools and, if called with the KM_NOSLEEP flag, fail immediately when the pool of the requisite size is exhausted. In ODDI 6 and later versons, kmem_alloc( ) can call the underlying allocator with the NOSLEEP flag so is more likely to return memory than in earlier releases. However, it can still fail and return NULL if the memory pool is exhausted and the KM_NOSLEEP flag is set.

SVR5 compatibility notes

The DDI kmem_alloc(D3) and kmem_zalloc(D3) functions have the same syntax, but, for DDI 6 and later, the memory allocated is seldom located in the lower 16MB range and the KM_NO_DMA flag is not supported. When porting drivers from SVR5 to SCO OpenServer, most calls to kmem_alloc( ) and kmem_zalloc( ) should be modified to set the KM_NO_DMA flag.

To allocate ISA DMA-able memory in DDI 6/6mp and later, use the kmem_alloc_phys(D3), kmem_alloc_physreq(D3), or kmem_zalloc_physreq(D3) function. For DDI 5/5mp and earlier, memory allocated with kmem_alloc(D3) is always below the 16MB boundary and no mechanism is provided for allocating memory above the 16MB boundary.

References

kmem_free(D3oddi) sptalloc(D3oddi)

``Memory allocation'' in HDK Technical Reference


19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 5 HDK - June 2005