Skip to content
Snippets Groups Projects
Commit 22a3975c authored by Armin Luntzer's avatar Armin Luntzer
Browse files

repair brainfarts

parent 484ceb07
No related branches found
No related tags found
No related merge requests found
......@@ -41,7 +41,7 @@ static struct chunk_pool phys_mem_pool;
static void *bootmem_alloc_internal(size_t size)
{
#if (CONFIG_SPARC_BOOTMEM_REQUEST_NEW_ON_DEMAND)
#ifndef CONFIG_SPARC_BOOTMEM_REQUEST_NEW_ON_DEMAND
static int blocked;
if (blocked) {
......@@ -94,6 +94,9 @@ void *bootmem_alloc(size_t size)
{
void *ptr;
if (!size)
return NULL;
ptr = chunk_alloc(&phys_mem_pool, size);
if (!ptr) {
......@@ -247,7 +250,6 @@ void bootmem_init(void)
if (base_pfn == sp_banks[i].base_addr)
continue;
pg_node = MEM_PAGE_NODE(node);
node++;
......@@ -259,25 +261,18 @@ void bootmem_init(void)
/* let's assume we always have enough memory, because if we
* don't, there is a serious configuration problem anyways
*
* XXX this should be a function...
*/
(*pg_node) = (struct page_map_node *)
bootmem_alloc(sizeof(struct page_map_node));
(*pg_node)->pool = (struct mm_pool *)
bootmem_alloc(sizeof(struct mm_pool));
(*pg_node) = (struct page_map_node *) bootmem_alloc(sizeof(struct page_map_node));
(*pg_node)->pool = (struct mm_pool *) bootmem_alloc(sizeof(struct mm_pool));
bzero((*pg_node)->pool, sizeof(struct mm_pool));
(*pg_node)->pool->block_order = (struct list_head *)
bootmem_alloc(sizeof(struct list_head)
* MM_BLOCK_ORDER_MAX);
(*pg_node)->pool->alloc_order = (unsigned char *)
bootmem_alloc(MM_INIT_NUM_BLOCKS);
(*pg_node)->pool->blk_free = (unsigned long *)
bootmem_alloc(MM_INIT_LEN_BITMAP
* sizeof(unsigned long));
(*pg_node)->pool->block_order = (struct list_head *) bootmem_alloc(sizeof(struct list_head) * (MM_BLOCK_ORDER_MAX + 1));
(*pg_node)->pool->alloc_order = (unsigned char *) bootmem_alloc(MM_INIT_NUM_BLOCKS);
(*pg_node)->pool->blk_free = (unsigned long *) bootmem_alloc(MM_INIT_LEN_BITMAP * sizeof(unsigned long));
ret = page_map_add(sp_banks[i].base_addr,
sp_banks[i].base_addr + sp_banks[i].num_bytes,
......
......@@ -10,14 +10,19 @@
#include <list.h>
#include <kernel/kmem.h>
#include <kernel/sbrk.h>
#include <kernel/kernel.h>
#include <kernel/printk.h>
#ifdef CONFIG_MMU
#include <kernel/sbrk.h>
#else
#include <kernel/bootmem.h>
#endif /* CONFIG_MMU */
#define WORD_ALIGN(x) ALIGN((x), sizeof(unsigned long))
#define WORD_ALIGN(x) ALIGN((x), sizeof(unsigned long))
#ifdef CONFIG_MMU
struct kmem {
void *data;
size_t size;
......@@ -91,15 +96,31 @@ static void kmem_split(struct kmem *k, size_t size)
}
/**
* @brief merge a chunk with its neighbour
*/
static void kmem_merge(struct kmem *k)
{
k->size = k->size + k->next->size + sizeof(struct kmem);
k->next = k->next->next;
if (k->next)
k->next->prev = k;
}
#endif /* CONFIG_MMU */
/**
* @brief returns the initial kmem chunk
*
* @note call this once kernel_sbrk() works
* @returns pointer or NULL on error
*/
void *kmem_init(void)
{
#ifdef CONFIG_MMU
if (likely(_kmem_init))
return _kmem_init;
......@@ -122,22 +143,9 @@ void *kmem_init(void)
_kmem_last = _kmem_init;
return _kmem_init;
}
/**
* @brief merge a chunk with its neighbour
*/
static void kmem_merge(struct kmem *k)
{
k->size = k->size + k->next->size + sizeof(struct kmem);
k->next = k->next->next;
if (k->next)
k->next->prev = k;
#else
return (void *) -1; /* return something not NULL */
#endif
}
......@@ -152,6 +160,7 @@ static void kmem_merge(struct kmem *k)
void *kmalloc(size_t size)
{
#ifdef CONFIG_MMU
size_t len;
struct kmem *k_new;
......@@ -199,6 +208,10 @@ void *kmalloc(size_t size)
_kmem_last = k_new;
return k_new->data;
#else
return bootmem_alloc(size);
#endif /* CONFIG_MMU */
}
......@@ -258,13 +271,15 @@ void *krealloc(void *ptr, size_t size)
char *src;
void *ptr_new;
struct kmem *k;
#ifdef CONFIG_MMU
struct kmem *k;
#endif /* CONFIG_MMU */
if (!ptr)
return kmalloc(size);
#ifdef CONFIG_MMU
if (ptr < kmem_init()) {
pr_warning("KMEM: invalid krealloc() of addr %p below lower "
"bound of trackable memory in call from %p\n",
......@@ -289,17 +304,22 @@ void *krealloc(void *ptr, size_t size)
return NULL;
}
#endif /* CONFIG_MMU */
ptr_new = kmalloc(size);
if (!ptr_new)
return NULL;
#ifdef CONFIG_MMU
if (k->size > size)
len = size;
else
len = k->size;
#else
/* this WILL copy out of bounds if size < original */
len = size;
#endif /* CONFIG_MMU */
src = ptr;
dst = ptr_new;
......@@ -323,6 +343,7 @@ void *krealloc(void *ptr, size_t size)
void kfree(void *ptr)
{
#ifdef CONFIG_MMU
struct kmem *k;
......@@ -354,10 +375,9 @@ void kfree(void *ptr)
k->free = 1;
if (k->next && k->next->free)
if (k->next && k->next->free) {
kmem_merge(k);
if (k->prev->free) {
} else if (k->prev->free) {
k = k->prev;
kmem_merge(k);
}
......@@ -371,4 +391,7 @@ void kfree(void *ptr)
} else {
list_add_tail(&k->node, &_kmem_init->node);
}
#else
bootmem_free(ptr);
#endif /* CONFIG_MMU */
}
......@@ -74,7 +74,7 @@ struct chunk {
static inline void *chunk_align(struct chunk_pool *pool, void *p)
{
return (void *) (((unsigned long) p + pool->align) & ~pool->align);
return ALIGN_PTR(p, pool->align);
}
......@@ -108,8 +108,6 @@ static void chunk_setup(struct chunk_pool *pool, struct chunk *c)
c->mem = chunk_align(pool, (void *) (c + 1));
/* set the allocatable size of the cunk */
c->free = ((size_t) c + c->size) - (size_t) c->mem;
chunk_classify(pool, c);
}
......@@ -158,10 +156,11 @@ static struct chunk *chunk_grab_new(struct chunk_pool *pool, size_t size)
/* we have no references yet */
c->refcnt = 0;
chunk_setup(pool, c);
/* add new parent to full list by default */
list_add_tail(&c->node, &pool->full);
chunk_setup(pool, c);
return c;
......@@ -181,12 +180,12 @@ static struct chunk *chunk_grab_new(struct chunk_pool *pool, size_t size)
*/
static struct chunk *chunk_split(struct chunk_pool *pool,
struct chunk *c, size_t size)
struct chunk *c, size_t alloc_sz)
{
struct chunk *new;
if (c->free < size)
if (c->free < alloc_sz)
return NULL;
/* this chunk is now a child of a higher-order chunk */
......@@ -195,23 +194,26 @@ static struct chunk *chunk_split(struct chunk_pool *pool,
new->child = NULL;
new->sibling = c->child;
new->refcnt = 1;
new->free = 0;
new->size = size;
new->size = alloc_sz;
chunk_setup(pool, new);
/* the new node will be in use, add to empty list */
new->free = 0;
list_add_tail(&new->node, &pool->empty);
chunk_setup(pool, new);
/* track the youngest child in the parent */
c->child = new;
c->refcnt++;
/* align parent chunk to start of new memory subsegment */
c->mem = chunk_align(pool, (void *) ((size_t) c->mem + size));
c->mem = chunk_align(pool, (void *) ((size_t) c->mem + alloc_sz));
/* update free bytes with regard to actual alignment */
c->free = ((size_t) c + c->size) - ((size_t) new + new->size);
c->free = ((size_t) c + c->size - (size_t) c->mem);
chunk_classify(pool, c);
return new;
}
......@@ -233,7 +235,6 @@ void *chunk_alloc(struct chunk_pool *pool, size_t size)
struct chunk *c = NULL;
struct chunk *p_elem;
struct chunk *p_tmp;
......@@ -251,7 +252,8 @@ void *chunk_alloc(struct chunk_pool *pool, size_t size)
alloc_sz = (size_t) chunk_align(pool,
(void *) (size + sizeof(struct chunk)));
list_for_each_entry_safe(p_elem, p_tmp, &pool->full, node) {
list_for_each_entry(p_elem, &pool->full, node) {
if (p_elem->free >= alloc_sz) {
c = p_elem;
......@@ -396,7 +398,7 @@ void chunk_pool_init(struct chunk_pool *pool,
INIT_LIST_HEAD(&pool->full);
INIT_LIST_HEAD(&pool->empty);
pool->align = align - 1;
pool->align = align;
pool->alloc = alloc;
pool->free = free;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment