/* * Operating System Memory Functions * * There are 2 interesting aspects of resource manager memory allocations * that need special consideration on Linux: * * 1. They are typically very large, (e.g. single allocations of 164KB) * * 2. The resource manager assumes that it can safely allocate memory in * interrupt handlers. * * The first requires that we call vmalloc, the second kmalloc. We decide * which one to use at run time, based on the size of the request and the * context. Allocations larger than 128KB require vmalloc, in the context * of an ISR they fail. */ #define KMALLOC_LIMIT 131072 RM_STATUS os_alloc_mem( VOID **address, U032 size ) { if (in_interrupt()) { if (size <= KMALLOC_LIMIT) { /* * The allocation request can be serviced with the Linux slab * allocator; the likelyhood of failure is still fairly high, * since kmalloc can't sleep. */ *address = kmalloc(size, GFP_ATOMIC); } else { /* * If the requested amount of memory exceeds kmalloc's limit, * we can't fulfill the request, as vmalloc can not be called * from an interrupt context (bottom-half, ISR). */ *address = NULL; } } else { if (size <= KMALLOC_LIMIT) { *address = kmalloc(size, GFP_KERNEL); // kmalloc may fail for larger allocations if memory is fragmented // in this case, vmalloc stands a better chance of making the // allocation, so give it a shot. if (*address == NULL) *address = vmalloc(size); } else { *address = vmalloc(size); } } return *address ? RM_OK : RM_ERR_NO_FREE_MEM; }