467 lines
15 KiB
C
467 lines
15 KiB
C
|
/* **********************************************************
|
||
|
* Copyright 1998 - 2010 VMware, Inc. All rights reserved.
|
||
|
* **********************************************************/
|
||
|
|
||
|
/*
|
||
|
* @VMKAPIMOD_LICENSE@
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* Slabs */ /**
|
||
|
* \defgroup Slab Slab Allocation
|
||
|
* @{
|
||
|
*
|
||
|
* ESX Server supports slab allocation for high performance driver/stack
|
||
|
* implementations:
|
||
|
* - Reduces memory fragmentation, especially for smaller data structures
|
||
|
* allocated in high volume.
|
||
|
* - Reduces CPU consumption for data structure initialization/teardown.
|
||
|
* - Improves CPU hardware cache performance.
|
||
|
* - Provides finer grained control of memory consumption.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
|
||
|
#ifndef _VMKAPI_SLAB_H_
|
||
|
#define _VMKAPI_SLAB_H_
|
||
|
|
||
|
/** \cond never */
|
||
|
#ifndef VMK_HEADER_INCLUDED_FROM_VMKAPI_H
|
||
|
#error This vmkapi file should never be included directly but only via vmkapi.h
|
||
|
#endif
|
||
|
/** \endcond never */
|
||
|
|
||
|
/**
|
||
|
* \brief Opaque handle for a slab cache.
|
||
|
*/
|
||
|
typedef struct vmk_SlabIDInt *vmk_SlabID;
|
||
|
|
||
|
#define VMK_INVALID_SLAB_ID ((vmk_SlabID)NULL)
|
||
|
|
||
|
/**
|
||
|
* \brief Constant for specifying an unlimited number of slab objects.
|
||
|
*/
|
||
|
#define VMK_SLAB_MAX_UNLIMITED ((vmk_ByteCountSmall) -1)
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_SlabItemConstructor -- */ /**
|
||
|
*
|
||
|
* \brief Item constructor - optional user defined function. Runs for
|
||
|
* each object when a cluster of memory is
|
||
|
* allocated from the heap.
|
||
|
*
|
||
|
* \note When the control structure is placed inside the free object,
|
||
|
* then the constructor must take care not to modify the control
|
||
|
* structure.
|
||
|
*
|
||
|
* \note A callback of this type must not block or call any API
|
||
|
* functions that may block.
|
||
|
*
|
||
|
* \param[in] object Object to be constructed.
|
||
|
* \param[in] size Size of buffer (possibly greater than objSize).
|
||
|
* \param[in] arg constructorArg (see vmk_SlabCreateProps).
|
||
|
* \param[in] flags Currently unused (reserved for future use).
|
||
|
*
|
||
|
* \retval VMK_OK to indicate object construction has succeded.
|
||
|
* \return Other To indicate failure.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
typedef VMK_ReturnStatus (*vmk_SlabItemConstructor)(void *object,
|
||
|
vmk_ByteCountSmall size,
|
||
|
vmk_AddrCookie arg,
|
||
|
int flags);
|
||
|
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_SlabItemDestructor -- */ /**
|
||
|
*
|
||
|
* \brief Item destructor - optional user defined function. Runs for
|
||
|
* each buffer just before a cluster of memory
|
||
|
* is returned to the heap.
|
||
|
*
|
||
|
* \note When the control structure is placed inside the free object,
|
||
|
* then the destructor must take care not to modify the control
|
||
|
* structure.
|
||
|
*
|
||
|
* \note A callback of this type must not block or call any API
|
||
|
* functions that may block.
|
||
|
*
|
||
|
* \param[in] object Object to be destroyed.
|
||
|
* \param[in] size Size of buffer (possibly greater than objSize).
|
||
|
* \param[in] arg constructorArg (see vmk_SlabCreateProps).
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
typedef void (*vmk_SlabItemDestructor)(void *object, vmk_ByteCountSmall size,
|
||
|
vmk_AddrCookie arg);
|
||
|
|
||
|
/**
|
||
|
* \brief Memory requirements for slabs.
|
||
|
*/
|
||
|
typedef struct vmk_SlabMemSize {
|
||
|
/** \brief Minimum number of memory pages this slab will occupy. */
|
||
|
vmk_uint32 minPages;
|
||
|
|
||
|
/** \brief Maximum number of memory pages this slab will occupy. */
|
||
|
vmk_uint32 maxPages;
|
||
|
} vmk_SlabMemSize;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* \brief Types of slab
|
||
|
*/
|
||
|
typedef enum vmk_SlabType {
|
||
|
/**
|
||
|
* \brief Slabs that get their own memory pool.
|
||
|
*
|
||
|
* Slabs of type VMK_SLAB_TYPE_SIMPLE get a contiguity of
|
||
|
* VMK_MEM_PHYS_ANY_CONTIGUITY and a physical address constraint
|
||
|
* of VMK_PHYS_ADDR_ANY. For slabs with different constraints,
|
||
|
* use type VMK_SLAB_TYPE_CUSTOM or VMK_SLAB_TYPE_MEMPOOL.
|
||
|
*/
|
||
|
VMK_SLAB_TYPE_SIMPLE = 0,
|
||
|
|
||
|
/** \brief Slabs with custom memory properties. */
|
||
|
VMK_SLAB_TYPE_CUSTOM = 1,
|
||
|
|
||
|
/** \brief Slabs whose memory comes from an existing memPool. */
|
||
|
VMK_SLAB_TYPE_MEMPOOL = 2,
|
||
|
|
||
|
} vmk_SlabType;
|
||
|
|
||
|
/**
|
||
|
* \brief Properties of a slab allocator
|
||
|
*/
|
||
|
typedef struct vmk_SlabCreateProps {
|
||
|
/** \brief Type of slab */
|
||
|
vmk_SlabType type;
|
||
|
|
||
|
/**
|
||
|
* \brief Name of the slab.
|
||
|
*/
|
||
|
vmk_Name name;
|
||
|
|
||
|
/** \brief Module ID of the module creating this slab. */
|
||
|
vmk_ModuleID module;
|
||
|
|
||
|
/**
|
||
|
* \brief Byte Size of each object
|
||
|
*
|
||
|
* objSize must be at least 1 byte and not more than 28608 bytes.
|
||
|
**/
|
||
|
vmk_ByteCountSmall objSize;
|
||
|
|
||
|
/**
|
||
|
* \brief Byte alignment for each object
|
||
|
*
|
||
|
* The alignment must be a power of 2, and it must be less than or
|
||
|
* equal to VMK_L1_CACHELINE_SIZE.
|
||
|
*/
|
||
|
vmk_ByteCountSmall alignment;
|
||
|
|
||
|
/** \brief Called after an object is allocated (or NULL for no action) */
|
||
|
vmk_SlabItemConstructor constructor;
|
||
|
|
||
|
/** \brief Called before an object is freed (or NULL for no action) */
|
||
|
vmk_SlabItemDestructor destructor;
|
||
|
|
||
|
/** \brief Argument for constructor/destructor calls */
|
||
|
vmk_AddrCookie constructorArg;
|
||
|
|
||
|
/**
|
||
|
* \brief Offset in allocation for slab control structure.
|
||
|
* \sa vmk_SlabControlSize
|
||
|
*/
|
||
|
vmk_ByteCountSmall ctrlOffset;
|
||
|
|
||
|
/** \brief Minimum number of objects allocatable from this slab. */
|
||
|
vmk_uint32 minObj;
|
||
|
|
||
|
/** \brief Maximum number of objects allocatable from this slab. */
|
||
|
vmk_uint32 maxObj;
|
||
|
|
||
|
/** \brief How long to wait for memory during slab creation. */
|
||
|
vmk_uint32 creationTimeoutMS;
|
||
|
|
||
|
/** \brief Type-specific slab properties */
|
||
|
union {
|
||
|
/** \brief Properties for VMK_SLAB_TYPE_CUSTOM. */
|
||
|
struct {
|
||
|
/** \brief Physical contiguity of objects allocated from this slab. */
|
||
|
vmk_MemPhysContiguity physContiguity;
|
||
|
|
||
|
/** \brief Physical address restrictions. */
|
||
|
vmk_MemPhysAddrConstraint physRange;
|
||
|
} custom;
|
||
|
|
||
|
/** \brief Properties for VMK_SLAB_TYPE_MEMPOOL. */
|
||
|
struct {
|
||
|
/** \brief Physical contiguity allocated from this slab. */
|
||
|
vmk_MemPhysContiguity physContiguity;
|
||
|
|
||
|
/** \brief Physical address restrictions. */
|
||
|
vmk_MemPhysAddrConstraint physRange;
|
||
|
|
||
|
/** \brief Memory pool. */
|
||
|
vmk_MemPool memPool;
|
||
|
} memPool;
|
||
|
|
||
|
} typeSpecific;
|
||
|
} vmk_SlabCreateProps;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* \brief Properties structure for querying a slab allocator.
|
||
|
*/
|
||
|
typedef struct vmk_SlabGetProps {
|
||
|
/** \brief Name of the slab. */
|
||
|
vmk_Name name;
|
||
|
|
||
|
/** \brief Module ID of the module creating this slab. */
|
||
|
vmk_ModuleID module;
|
||
|
|
||
|
/** \brief Byte Size of each object. */
|
||
|
vmk_ByteCountSmall objSize;
|
||
|
|
||
|
/**
|
||
|
* \brief Byte alignment for each object
|
||
|
*/
|
||
|
vmk_ByteCountSmall alignment;
|
||
|
|
||
|
/** \brief Called after an object is allocated (or NULL for no action) */
|
||
|
vmk_SlabItemConstructor constructor;
|
||
|
|
||
|
/** \brief Called before an object is freed (or NULL for no action) */
|
||
|
vmk_SlabItemDestructor destructor;
|
||
|
|
||
|
/** \brief Argument for constructor/destructor calls */
|
||
|
vmk_AddrCookie constructorArg;
|
||
|
|
||
|
/** \brief Offset in allocation for slab control structure. */
|
||
|
vmk_ByteCountSmall ctrlOffset;
|
||
|
|
||
|
/** \brief Minimum number of objects allocatable from this slab. */
|
||
|
vmk_uint32 minObj;
|
||
|
|
||
|
/** \brief Maximum number of objects allocatable from this slab. */
|
||
|
vmk_uint32 maxObj;
|
||
|
|
||
|
/** \brief Physical contiguity allocated from this slab. */
|
||
|
vmk_MemPhysContiguity physContiguity;
|
||
|
|
||
|
/** \brief Physical address restrictions. */
|
||
|
vmk_MemPhysAddrConstraint physRange;
|
||
|
|
||
|
/** \brief Memory pool. */
|
||
|
vmk_MemPool memPool;
|
||
|
} vmk_SlabGetProps;
|
||
|
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_SlabCreate -- */ /**
|
||
|
*
|
||
|
* \brief Create a slab allocator cache.
|
||
|
*
|
||
|
* A slab is created with the specified creation properties. Enough
|
||
|
* memory is allocated for props->minObj to be created. Slab creation
|
||
|
* will fail if enough memory cannot be allocated.
|
||
|
*
|
||
|
* \note This function may block if creationTimeoutMS is not
|
||
|
* VMK_TIMEOUT_NONBLOCKING.
|
||
|
*
|
||
|
* \param [in] props Properties of the new cache.
|
||
|
* \param [out] cache For use with vmk_SlabAlloc, etc.
|
||
|
*
|
||
|
* \retval VMK_OK indicates that the slab was created.
|
||
|
* \retval VMK_BAD_PARAM indicates that some slab parameters were
|
||
|
* invalid.
|
||
|
* \retval VMK_NO_MEMORY indicates that insufficient memory was
|
||
|
* available.
|
||
|
* \retval VMK_TIMEOUT indicates that the timeout was reached before
|
||
|
* enough memory could be allocated.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_SlabCreate(vmk_SlabCreateProps *props,
|
||
|
vmk_SlabID *cache);
|
||
|
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_SlabAlloc -- */ /**
|
||
|
*
|
||
|
* \brief Allocate an item from a slab.
|
||
|
*
|
||
|
* The vmk_SlabItemConstructor (if defined) was previously called,
|
||
|
* or the object was previously freed via vmk_SlabFree().
|
||
|
*
|
||
|
* If the slab is not yet at maximum size, this function may attempt to
|
||
|
* allocate additional physical memory to satisfy the allocation request.
|
||
|
* If physical memory is not currently available, this function will not
|
||
|
* block to wait for memory to become available.
|
||
|
*
|
||
|
* \note When the control structure is placed inside the free object,
|
||
|
* the caller of vmk_SlabAlloc() must assume this portion of
|
||
|
* the object is uninitialized.
|
||
|
*
|
||
|
* \note This function will not block.
|
||
|
*
|
||
|
* \param[in] cache Slab from which allocation will take place.
|
||
|
*
|
||
|
* \retval NULL Memory could not be allocated.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
void *vmk_SlabAlloc(vmk_SlabID cache);
|
||
|
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_SlabAllocWithTimeout -- */ /**
|
||
|
*
|
||
|
* \brief Allocate an item, possibly waiting for physical memory.
|
||
|
*
|
||
|
* The vmk_SlabItemConstructor (if defined) was previously called,
|
||
|
* or the object was previously freed via vmk_SlabFree().
|
||
|
*
|
||
|
* If the slab is not yet at maximum size, this function may attempt to
|
||
|
* allocate additional physical memory to satisfy the allocation request.
|
||
|
* If physical memory is not currently available, this function will use
|
||
|
* the value of timeout to determine if it may block until memory is
|
||
|
* available, and if so, for how long.
|
||
|
*
|
||
|
* \note When the control structure is placed inside the free object,
|
||
|
* the caller of vmk_SlabAlloc() must assume this portion of
|
||
|
* the object is uninitialized.
|
||
|
*
|
||
|
* \note This function may block.
|
||
|
*
|
||
|
* \param[in] cache Slab from which allocation will take place.
|
||
|
* \param[in] timeoutMS Timeout specifying how long the call may wait.
|
||
|
*
|
||
|
* \retval NULL Memory could not be allocated.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
void *vmk_SlabAllocWithTimeout(
|
||
|
vmk_SlabID cache,
|
||
|
vmk_uint32 timeoutMS);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_SlabFree -- */ /**
|
||
|
*
|
||
|
* \brief Free memory allocated by vmk_SlabAlloc.
|
||
|
*
|
||
|
* The memory object will be retained by the slab. If at some point
|
||
|
* the slab chooses to give the memory back to the system, the
|
||
|
* vmk_SlabItemDestructor (if defined) will be called.
|
||
|
*
|
||
|
* \note This function will not block.
|
||
|
*
|
||
|
* \param[in] cache Slab from which the item was allocated.
|
||
|
* \param[in] object object to be freed.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
void vmk_SlabFree(
|
||
|
vmk_SlabID cache,
|
||
|
void *object);
|
||
|
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_SlabDestroy -- */ /**
|
||
|
*
|
||
|
* \brief Destroy a slab cache previously created by vmk_SlabCreate.
|
||
|
*
|
||
|
* \note This function will not block.
|
||
|
*
|
||
|
* \param[in] cache The cache to be destroyed.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_SlabDestroy(vmk_SlabID cache);
|
||
|
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_SlabControlSize -- */ /**
|
||
|
*
|
||
|
* \brief Get the size of the per-object "control" structure.
|
||
|
*
|
||
|
* The slab maintains a control structure for each free object
|
||
|
* cached by the slab. When VMK_SLAB_TYPE_SIMPLE properties are
|
||
|
* used to create the slab, the control structure will be tacked
|
||
|
* past the end of the client's object. To save space, the control
|
||
|
* structure can be placed within the user's free object using the
|
||
|
* ctrlOffset paramter to VMK_SLAB_TYPE_NOMINAL properties.
|
||
|
*
|
||
|
* \note For best performance, it is recommended that the control structure
|
||
|
* offset is a multiple of sizeof (void *), but this is not a
|
||
|
* requirement.
|
||
|
*
|
||
|
* \note See vmk_SlabItemConstructor, vmk_SlabItemDestructor and
|
||
|
* and vmk_SlabAlloc for the constraints that must be obeyed
|
||
|
* when the control structure is placed inside the object.
|
||
|
*
|
||
|
* \note This function will not block.
|
||
|
*
|
||
|
* \return Size of the control structure in bytes.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
vmk_ByteCountSmall vmk_SlabControlSize(void);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_SlabGetMemSize -- */ /**
|
||
|
*
|
||
|
* \brief Returns the memory requirements for a slab.
|
||
|
*
|
||
|
* This function computes the minimum and maximum required
|
||
|
* memory for a slab with the provided characteristics.
|
||
|
*
|
||
|
* For a slab of type VMK_SLAB_TYPE_MEMPOOL, the provided memPool
|
||
|
* may be VMK_MEMPOOL_LEGACY_INVALID, so this function can be used
|
||
|
* to compute needed sizes for constructing a memory pool.
|
||
|
*
|
||
|
* \note This function will not block.
|
||
|
*
|
||
|
* \return VMK_BAD_PARAM minObj and maxObj were inconsistent,
|
||
|
* or maxObj was VMK_SLAB_MAX_UNLIMITED
|
||
|
* for a slab of type VMK_SLAB_TYPE_SIMPLE or
|
||
|
* VMK_SLAB_TYPE_CUSTOM.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_SlabGetMemSize(vmk_SlabCreateProps *props,
|
||
|
vmk_SlabMemSize *size);
|
||
|
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_SlabGetProperties -- */ /**
|
||
|
*
|
||
|
* \brief Returns the allocation properties for a slab.
|
||
|
*
|
||
|
* \note This function will not block.
|
||
|
*
|
||
|
* \return VMK_OK Properties is filled in.
|
||
|
* \return VMK_NOT_FOUND slab was not a valid slab handle.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
|
||
|
VMK_ReturnStatus
|
||
|
vmk_SlabGetProperties(vmk_SlabID slab, vmk_SlabGetProps *props);
|
||
|
|
||
|
|
||
|
#endif /* _VMKAPI_SLAB_H_ */
|
||
|
/** @} */
|