mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-13 22:06:49 +00:00
hv: remove dynamic memory allocation APIs
This patch removes dynamic memory allocation APIs, including: - calloc - malloc - free The corresponding data structures, MACROs, and Kconfig items are also removed. v1 -> v2: no change Tracked-On: #861 Signed-off-by: Shiqing Gao <shiqing.gao@intel.com>
This commit is contained in:
parent
773889bb65
commit
dbb41575e7
@ -147,15 +147,6 @@ config COM_IRQ
|
|||||||
help
|
help
|
||||||
IRQ of the vuart port.
|
IRQ of the vuart port.
|
||||||
|
|
||||||
config MALLOC_ALIGN
|
|
||||||
int "Block size in the heap for malloc()"
|
|
||||||
range 8 32
|
|
||||||
default 16
|
|
||||||
|
|
||||||
config HEAP_SIZE
|
|
||||||
hex "Capacity of the heap for malloc()"
|
|
||||||
default 0x100000
|
|
||||||
|
|
||||||
config CONSOLE_LOGLEVEL_DEFAULT
|
config CONSOLE_LOGLEVEL_DEFAULT
|
||||||
int "Default loglevel on the serial console"
|
int "Default loglevel on the serial console"
|
||||||
depends on !RELEASE
|
depends on !RELEASE
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include <host_pm.h>
|
#include <host_pm.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <spinlock.h>
|
#include <spinlock.h>
|
||||||
#include <mem_mgt.h>
|
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
#include "vtd.h"
|
#include "vtd.h"
|
||||||
#include "acpi_priv.h"
|
#include "acpi_priv.h"
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MEM_MGT_H
|
|
||||||
#define MEM_MGT_H
|
|
||||||
|
|
||||||
/* Macros */
|
|
||||||
#define BITMAP_WORD_SIZE 32U
|
|
||||||
|
|
||||||
struct mem_pool {
|
|
||||||
void *start_addr; /* Start Address of Memory Pool */
|
|
||||||
spinlock_t spinlock; /* To protect Memory Allocation */
|
|
||||||
uint32_t size; /* Size of Memory Pool in Bytes */
|
|
||||||
uint32_t buff_size; /* Size of one Buffer in Bytes */
|
|
||||||
uint32_t total_buffs; /* Total Buffers in Memory Pool */
|
|
||||||
uint32_t bmp_size; /* Size of Bitmap Array */
|
|
||||||
uint32_t *bitmap; /* Pointer to allocation bitmap */
|
|
||||||
uint32_t *contiguity_bitmap; /* Pointer to contiguity bitmap */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* APIs exposing memory allocation/deallocation abstractions */
|
|
||||||
void *malloc(uint32_t num_bytes);
|
|
||||||
void *calloc(uint32_t num_elements, uint32_t element_size);
|
|
||||||
void free(const void *ptr);
|
|
||||||
|
|
||||||
#endif /* MEM_MGT_H */
|
|
@ -3,252 +3,6 @@
|
|||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <util.h>
|
|
||||||
#include <bits.h>
|
|
||||||
#include <spinlock.h>
|
|
||||||
#include <page.h>
|
|
||||||
#include <mem_mgt.h>
|
|
||||||
#include <logmsg.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Memory pool declaration (block size = CONFIG_MALLOC_ALIGN)
|
|
||||||
*/
|
|
||||||
#define __bss_noinit __attribute__((__section__(".bss_noinit")))
|
|
||||||
|
|
||||||
static uint8_t __bss_noinit malloc_heap[CONFIG_HEAP_SIZE] __aligned(CONFIG_MALLOC_ALIGN);
|
|
||||||
|
|
||||||
#define MALLOC_HEAP_BUFF_SIZE CONFIG_MALLOC_ALIGN
|
|
||||||
#define MALLOC_HEAP_TOTAL_BUFF (CONFIG_HEAP_SIZE/MALLOC_HEAP_BUFF_SIZE)
|
|
||||||
#define MALLOC_HEAP_BITMAP_SIZE INT_DIV_ROUNDUP(MALLOC_HEAP_TOTAL_BUFF, BITMAP_WORD_SIZE)
|
|
||||||
static uint32_t malloc_heap_bitmap[MALLOC_HEAP_BITMAP_SIZE];
|
|
||||||
static uint32_t malloc_heap_contiguity_bitmap[MALLOC_HEAP_BITMAP_SIZE];
|
|
||||||
|
|
||||||
static struct mem_pool memory_pool = {
|
|
||||||
.start_addr = malloc_heap,
|
|
||||||
.spinlock = {.head = 0U, .tail = 0U},
|
|
||||||
.size = CONFIG_HEAP_SIZE,
|
|
||||||
.buff_size = MALLOC_HEAP_BUFF_SIZE,
|
|
||||||
.total_buffs = MALLOC_HEAP_TOTAL_BUFF,
|
|
||||||
.bmp_size = MALLOC_HEAP_BITMAP_SIZE,
|
|
||||||
.bitmap = malloc_heap_bitmap,
|
|
||||||
.contiguity_bitmap = malloc_heap_contiguity_bitmap
|
|
||||||
};
|
|
||||||
|
|
||||||
static void *allocate_mem(struct mem_pool *pool, uint32_t num_bytes)
|
|
||||||
{
|
|
||||||
void *memory = NULL;
|
|
||||||
uint32_t idx;
|
|
||||||
uint16_t bit_idx;
|
|
||||||
uint32_t requested_buffs;
|
|
||||||
|
|
||||||
/* Check if provided memory pool exists */
|
|
||||||
if (pool == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Acquire the pool lock */
|
|
||||||
spinlock_obtain(&pool->spinlock);
|
|
||||||
|
|
||||||
/* Calculate number of buffers to be allocated from memory pool */
|
|
||||||
requested_buffs = INT_DIV_ROUNDUP(num_bytes, pool->buff_size);
|
|
||||||
|
|
||||||
for (idx = 0U; idx < pool->bmp_size; idx++) {
|
|
||||||
/* Find the first occurrence of requested_buffs number of free
|
|
||||||
* buffers. The 0th bit in bitmap represents a free buffer.
|
|
||||||
*/
|
|
||||||
for (bit_idx = ffz64(pool->bitmap[idx]); bit_idx < BITMAP_WORD_SIZE; bit_idx++) {
|
|
||||||
/* Check if selected buffer is free */
|
|
||||||
if ((pool->bitmap[idx] & (1U << bit_idx)) != 0U) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Declare temporary variables to be used locally in this block */
|
|
||||||
uint32_t i;
|
|
||||||
uint16_t tmp_bit_idx = bit_idx;
|
|
||||||
uint32_t tmp_idx = idx;
|
|
||||||
|
|
||||||
/* Check requested_buffs number of buffers availability
|
|
||||||
* in memory-pool right after selected buffer
|
|
||||||
*/
|
|
||||||
for (i = 1U; i < requested_buffs; i++) {
|
|
||||||
/* Check if tmp_bit_idx is out-of-range */
|
|
||||||
tmp_bit_idx++;
|
|
||||||
if (tmp_bit_idx == BITMAP_WORD_SIZE) {
|
|
||||||
/* Break the loop if tmp_idx is
|
|
||||||
* out-of-range
|
|
||||||
*/
|
|
||||||
tmp_idx++;
|
|
||||||
if (tmp_idx == pool->bmp_size) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Reset tmp_bit_idx */
|
|
||||||
tmp_bit_idx = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Break if selected buffer is not free */
|
|
||||||
if ((pool->bitmap[tmp_idx] & (1U << tmp_bit_idx)) != 0U) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if requested_buffs number of free contiguous
|
|
||||||
* buffers are found in memory pool
|
|
||||||
*/
|
|
||||||
if (i == requested_buffs) {
|
|
||||||
/* Get start address of first buffer among
|
|
||||||
* selected free contiguous buffer in the
|
|
||||||
* memory pool
|
|
||||||
*/
|
|
||||||
memory = pool->start_addr + pool->buff_size * (idx * BITMAP_WORD_SIZE + bit_idx);
|
|
||||||
|
|
||||||
/* Update allocation bitmaps information for
|
|
||||||
* selected buffers
|
|
||||||
*/
|
|
||||||
for (i = 0U; i < requested_buffs; i++) {
|
|
||||||
/* Set allocation bit in bitmap for
|
|
||||||
* this buffer
|
|
||||||
*/
|
|
||||||
pool->bitmap[idx] |= (1U << bit_idx);
|
|
||||||
|
|
||||||
/* Set contiguity information for this
|
|
||||||
* buffer in contiguity-bitmap
|
|
||||||
*/
|
|
||||||
if (i < (requested_buffs - 1U)) {
|
|
||||||
/* Set contiguity bit to 1 if
|
|
||||||
* this buffer is not the last
|
|
||||||
* of selected contiguous
|
|
||||||
* buffers array
|
|
||||||
*/
|
|
||||||
pool->contiguity_bitmap[idx] |= (1U << bit_idx);
|
|
||||||
} else {
|
|
||||||
/* Set contiguity bit to 0 if
|
|
||||||
* this buffer is not the last
|
|
||||||
* of selected contiguous
|
|
||||||
* buffers array
|
|
||||||
*/
|
|
||||||
pool->contiguity_bitmap[idx] &= ~(1U << bit_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if bit_idx is out-of-range */
|
|
||||||
bit_idx++;
|
|
||||||
if (bit_idx == BITMAP_WORD_SIZE) {
|
|
||||||
/* Increment idx */
|
|
||||||
idx++;
|
|
||||||
/* Reset bit_idx */
|
|
||||||
bit_idx = 0U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Release the pool lock. */
|
|
||||||
spinlock_release(&pool->spinlock);
|
|
||||||
|
|
||||||
return memory;
|
|
||||||
}
|
|
||||||
/* Update bit_idx and idx */
|
|
||||||
bit_idx = tmp_bit_idx;
|
|
||||||
idx = tmp_idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Release the pool lock. */
|
|
||||||
spinlock_release(&pool->spinlock);
|
|
||||||
|
|
||||||
return (void *)NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void deallocate_mem(struct mem_pool *pool, const void *ptr)
|
|
||||||
{
|
|
||||||
uint32_t *bitmask, *contiguity_bitmask;
|
|
||||||
uint32_t bmp_idx, bit_idx, buff_idx;
|
|
||||||
|
|
||||||
if ((pool != NULL) && (ptr != NULL)) {
|
|
||||||
/* Acquire the pool lock */
|
|
||||||
spinlock_obtain(&pool->spinlock);
|
|
||||||
|
|
||||||
/* Map the buffer address to its index. */
|
|
||||||
buff_idx = (ptr - pool->start_addr) / pool->buff_size;
|
|
||||||
|
|
||||||
/* De-allocate all allocated contiguous memory buffers */
|
|
||||||
while (buff_idx < pool->total_buffs) {
|
|
||||||
/* Translate the buffer index to bitmap index. */
|
|
||||||
bmp_idx = buff_idx / BITMAP_WORD_SIZE;
|
|
||||||
bit_idx = buff_idx % BITMAP_WORD_SIZE;
|
|
||||||
|
|
||||||
/* Get bitmap's reference for this buffer */
|
|
||||||
bitmask = &pool->bitmap[bmp_idx];
|
|
||||||
contiguity_bitmask = &pool->contiguity_bitmap[bmp_idx];
|
|
||||||
|
|
||||||
/* Mark the buffer as free */
|
|
||||||
if ((*bitmask & (1U << bit_idx)) != 0U) {
|
|
||||||
*bitmask ^= (1U << bit_idx);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset the Contiguity bit of buffer */
|
|
||||||
if ((*contiguity_bitmask & (1U << bit_idx)) != 0U) {
|
|
||||||
*contiguity_bitmask ^= (1U << bit_idx);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increment buff_idx */
|
|
||||||
buff_idx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Release the pool lock. */
|
|
||||||
spinlock_release(&pool->spinlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The return address will be PAGE_SIZE aligned if 'num_bytes' is greater
|
|
||||||
* than PAGE_SIZE.
|
|
||||||
*/
|
|
||||||
void *malloc(uint32_t num_bytes)
|
|
||||||
{
|
|
||||||
void *memory = NULL;
|
|
||||||
|
|
||||||
/* Check if bytes requested extend page-size */
|
|
||||||
if (num_bytes < PAGE_SIZE) {
|
|
||||||
/*
|
|
||||||
* Request memory allocation from smaller segmented memory pool
|
|
||||||
*/
|
|
||||||
memory = allocate_mem(&memory_pool, num_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if memory allocation is successful */
|
|
||||||
if (memory == NULL) {
|
|
||||||
pr_err("%s: failed to alloc 0x%x Bytes", __func__, num_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return memory pointer to caller */
|
|
||||||
return memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *calloc(uint32_t num_elements, uint32_t element_size)
|
|
||||||
{
|
|
||||||
void *memory = malloc(num_elements * element_size);
|
|
||||||
|
|
||||||
/* Determine if memory was allocated */
|
|
||||||
if (memory != NULL) {
|
|
||||||
/* Zero all the memory */
|
|
||||||
(void)memset(memory, 0U, num_elements * element_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return pointer to memory */
|
|
||||||
return memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free(const void *ptr)
|
|
||||||
{
|
|
||||||
/* Check if ptr belongs to 16-Bytes aligned Memory Pool */
|
|
||||||
if ((memory_pool.start_addr < ptr) &&
|
|
||||||
(ptr < (memory_pool.start_addr + memory_pool.total_buffs * memory_pool.buff_size))) {
|
|
||||||
/* Free buffer in 16-Bytes aligned Memory Pool */
|
|
||||||
deallocate_mem(&memory_pool, ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void memcpy_erms(void *d, const void *s, size_t slen)
|
static inline void memcpy_erms(void *d, const void *s, size_t slen)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user