mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
The patch removes broken, and very complicated malloc in
favour of much simpler (and working) Xen's allocator (xmalloc by Rusty). Signed-off-by: Grzegorz Milos <gm281@cam.ac.uk>
This commit is contained in:
1 parent
4fb2acfb09
commit
393415f09c
7 files changed
+261
-5735
No files matched your search
@@ -79,36 +79,4 @@ char *strchr(const char *s, int c);
|
||||
char *strstr(const char *s1, const char *s2);
|
||||
|
||||
|
||||
/* dlmalloc functions */
|
||||
struct mallinfo {
|
||||
int arena; /* non-mmapped space allocated from system */
|
||||
int ordblks; /* number of free chunks */
|
||||
int smblks; /* number of fastbin blocks */
|
||||
int hblks; /* number of mmapped regions */
|
||||
int hblkhd; /* space in mmapped regions */
|
||||
int usmblks; /* maximum total allocated space */
|
||||
int fsmblks; /* space available in freed fastbin blocks */
|
||||
int uordblks; /* total allocated space */
|
||||
int fordblks; /* total free space */
|
||||
int keepcost; /* top-most, releasable (via malloc_trim) space */
|
||||
};
|
||||
|
||||
void *malloc(size_t n);
|
||||
void *calloc(size_t n_elements, size_t element_size);
|
||||
void free(void* p);
|
||||
void *realloc(void* p, size_t n);
|
||||
void *memalign(size_t alignment, size_t n);
|
||||
void *valloc(size_t n);
|
||||
struct mallinfo mallinfo(void);
|
||||
int mallopt(int parameter_number, int parameter_value);
|
||||
|
||||
void **independent_calloc(size_t n_elements, size_t size, void* chunks[]);
|
||||
void **independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);
|
||||
void *pvalloc(size_t n);
|
||||
void cfree(void* p);
|
||||
int malloc_trim(size_t pad);
|
||||
size_t malloc_usable_size(void* p);
|
||||
void malloc_stats(void);
|
||||
|
||||
|
||||
#endif /* _LIB_H_ */
|
||||
@@ -126,6 +126,18 @@ static __inline__ unsigned long machine_to_phys(unsigned long machine)
|
||||
|
||||
void init_mm(void);
|
||||
unsigned long alloc_pages(int order);
|
||||
int is_mfn_mapped(unsigned long mfn);
|
||||
#define alloc_page() alloc_pages(0);
|
||||
void free_pages(void *pointer, int order);
|
||||
//int is_mfn_mapped(unsigned long mfn);
|
||||
|
||||
static __inline__ int get_order(unsigned long size)
|
||||
{
|
||||
int order;
|
||||
size = (size-1) >> PAGE_SHIFT;
|
||||
for ( order = 0; size; order++ )
|
||||
size >>= 1;
|
||||
return order;
|
||||
}
|
||||
|
||||
|
||||
#endif /* _MM_H_ */
|
||||
@@ -49,4 +49,6 @@ typedef long quad_t;
|
||||
typedef unsigned long u_quad_t;
|
||||
typedef unsigned long uintptr_t;
|
||||
#endif
|
||||
|
||||
#define UINT_MAX (~0U)
|
||||
#endif /* _TYPES_H_ */
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef __XMALLOC_H__
|
||||
#define __XMALLOC_H__
|
||||
|
||||
/* Allocate space for typed object. */
|
||||
#define xmalloc(_type) ((_type *)_xmalloc(sizeof(_type), __alignof__(_type)))
|
||||
|
||||
/* Allocate space for array of typed objects. */
|
||||
#define xmalloc_array(_type, _num) ((_type *)_xmalloc_array(sizeof(_type), __alignof__(_type), _num))
|
||||
|
||||
/* Free any of the above. */
|
||||
extern void xfree(const void *);
|
||||
|
||||
/* Underlying functions */
|
||||
extern void *_xmalloc(size_t size, size_t align);
|
||||
static inline void *_xmalloc_array(size_t size, size_t align, size_t num)
|
||||
{
|
||||
/* Check for overflow. */
|
||||
if (size && num > UINT_MAX / size)
|
||||
return NULL;
|
||||
return _xmalloc(size * num, align);
|
||||
}
|
||||
|
||||
#endif /* __XMALLOC_H__ */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
****************************************************************************
|
||||
* (C) 2005 - Grzegorz Milos - Intel Research Cambridge
|
||||
****************************************************************************
|
||||
*
|
||||
* File: xmaloc.c
|
||||
* Author: Grzegorz Milos (gm281@cam.ac.uk)
|
||||
* Changes:
|
||||
*
|
||||
* Date: Aug 2005
|
||||
*
|
||||
* Environment: Xen Minimal OS
|
||||
* Description: simple memory allocator
|
||||
*
|
||||
****************************************************************************
|
||||
* Simple allocator for Mini-os. If larger than a page, simply use the
|
||||
* page-order allocator.
|
||||
*
|
||||
* Copy of the allocator for Xen by Rusty Russell:
|
||||
* Copyright (C) 2005 Rusty Russell IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <os.h>
|
||||
#include <mm.h>
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <list.h>
|
||||
|
||||
static LIST_HEAD(freelist);
|
||||
/* static spinlock_t freelist_lock = SPIN_LOCK_UNLOCKED; */
|
||||
|
||||
struct xmalloc_hdr
|
||||
{
|
||||
/* Total including this hdr. */
|
||||
size_t size;
|
||||
struct list_head freelist;
|
||||
} __cacheline_aligned;
|
||||
|
||||
static void maybe_split(struct xmalloc_hdr *hdr, size_t size, size_t block)
|
||||
{
|
||||
struct xmalloc_hdr *extra;
|
||||
size_t leftover = block - size;
|
||||
|
||||
/* If enough is left to make a block, put it on free list. */
|
||||
if ( leftover >= (2 * sizeof(struct xmalloc_hdr)) )
|
||||
{
|
||||
extra = (struct xmalloc_hdr *)((unsigned long)hdr + size);
|
||||
extra->size = leftover;
|
||||
list_add(&extra->freelist, &freelist);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = block;
|
||||
}
|
||||
|
||||
hdr->size = size;
|
||||
/* Debugging aid. */
|
||||
hdr->freelist.next = hdr->freelist.prev = NULL;
|
||||
}
|
||||
|
||||
static void *xmalloc_new_page(size_t size)
|
||||
{
|
||||
struct xmalloc_hdr *hdr;
|
||||
/* unsigned long flags; */
|
||||
|
||||
hdr = (struct xmalloc_hdr *)alloc_page();
|
||||
if ( hdr == NULL )
|
||||
return NULL;
|
||||
|
||||
/* spin_lock_irqsave(&freelist_lock, flags); */
|
||||
maybe_split(hdr, size, PAGE_SIZE);
|
||||
/* spin_unlock_irqrestore(&freelist_lock, flags); */
|
||||
|
||||
return hdr+1;
|
||||
}
|
||||
|
||||
/* Big object? Just use the page allocator. */
|
||||
static void *xmalloc_whole_pages(size_t size)
|
||||
{
|
||||
struct xmalloc_hdr *hdr;
|
||||
unsigned int pageorder = get_order(size);
|
||||
|
||||
hdr = (struct xmalloc_hdr *)alloc_pages(pageorder);
|
||||
if ( hdr == NULL )
|
||||
return NULL;
|
||||
|
||||
hdr->size = (1 << (pageorder + PAGE_SHIFT));
|
||||
/* Debugging aid. */
|
||||
hdr->freelist.next = hdr->freelist.prev = NULL;
|
||||
|
||||
return hdr+1;
|
||||
}
|
||||
|
||||
/* Return size, increased to alignment with align. */
|
||||
static inline size_t align_up(size_t size, size_t align)
|
||||
{
|
||||
return (size + align - 1) & ~(align - 1);
|
||||
}
|
||||
|
||||
void *_xmalloc(size_t size, size_t align)
|
||||
{
|
||||
struct xmalloc_hdr *i;
|
||||
/* unsigned long flags; */
|
||||
|
||||
/* Add room for header, pad to align next header. */
|
||||
size += sizeof(struct xmalloc_hdr);
|
||||
size = align_up(size, __alignof__(struct xmalloc_hdr));
|
||||
|
||||
/* For big allocs, give them whole pages. */
|
||||
if ( size >= PAGE_SIZE )
|
||||
return xmalloc_whole_pages(size);
|
||||
|
||||
/* Search free list. */
|
||||
/* spin_lock_irqsave(&freelist_lock, flags); */
|
||||
list_for_each_entry( i, &freelist, freelist )
|
||||
{
|
||||
if ( i->size < size )
|
||||
continue;
|
||||
list_del(&i->freelist);
|
||||
maybe_split(i, size, i->size);
|
||||
/* spin_unlock_irqrestore(&freelist_lock, flags); */
|
||||
return i+1;
|
||||
}
|
||||
/* spin_unlock_irqrestore(&freelist_lock, flags); */
|
||||
|
||||
/* Alloc a new page and return from that. */
|
||||
return xmalloc_new_page(size);
|
||||
}
|
||||
|
||||
void xfree(const void *p)
|
||||
{
|
||||
/* unsigned long flags; */
|
||||
struct xmalloc_hdr *i, *tmp, *hdr;
|
||||
|
||||
if ( p == NULL )
|
||||
return;
|
||||
|
||||
hdr = (struct xmalloc_hdr *)p - 1;
|
||||
|
||||
/* We know hdr will be on same page. */
|
||||
if(((long)p & PAGE_MASK) != ((long)hdr & PAGE_MASK))
|
||||
{
|
||||
printk("Header should be on the same page\n");
|
||||
*(int*)0=0;
|
||||
}
|
||||
|
||||
/* Not previously freed. */
|
||||
if(hdr->freelist.next || hdr->freelist.prev)
|
||||
{
|
||||
printk("Should not be previously freed\n");
|
||||
*(int*)0=0;
|
||||
}
|
||||
|
||||
/* Big allocs free directly. */
|
||||
if ( hdr->size >= PAGE_SIZE )
|
||||
{
|
||||
free_pages(hdr, get_order(hdr->size));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Merge with other free block, or put in list. */
|
||||
/* spin_lock_irqsave(&freelist_lock, flags); */
|
||||
list_for_each_entry_safe( i, tmp, &freelist, freelist )
|
||||
{
|
||||
unsigned long _i = (unsigned long)i;
|
||||
unsigned long _hdr = (unsigned long)hdr;
|
||||
|
||||
/* Do not merge across page boundaries. */
|
||||
if ( ((_i ^ _hdr) & PAGE_MASK) != 0 )
|
||||
continue;
|
||||
|
||||
/* We follow this block? Swallow it. */
|
||||
if ( (_i + i->size) == _hdr )
|
||||
{
|
||||
list_del(&i->freelist);
|
||||
i->size += hdr->size;
|
||||
hdr = i;
|
||||
}
|
||||
|
||||
/* We precede this block? Swallow it. */
|
||||
if ( (_hdr + hdr->size) == _i )
|
||||
{
|
||||
list_del(&i->freelist);
|
||||
hdr->size += i->size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we merge an entire page? */
|
||||
if ( hdr->size == PAGE_SIZE )
|
||||
{
|
||||
if((((unsigned long)hdr) & (PAGE_SIZE-1)) != 0)
|
||||
{
|
||||
printk("Bug\n");
|
||||
*(int*)0=0;
|
||||
}
|
||||
free_pages(hdr, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
list_add(&hdr->freelist, &freelist);
|
||||
}
|
||||
|
||||
/* spin_unlock_irqrestore(&freelist_lock, flags); */
|
||||
}
|
||||
|
||||
+4
-5
@@ -1,6 +1,7 @@
|
||||
/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
|
||||
/*
|
||||
****************************************************************************
|
||||
* (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
|
||||
* (C) 2005 - Grzegorz Milos - Intel Research Cambridge
|
||||
****************************************************************************
|
||||
*
|
||||
* File: mm.c
|
||||
@@ -14,8 +15,6 @@
|
||||
* contains buddy page allocator from Xen.
|
||||
*
|
||||
****************************************************************************
|
||||
* $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
@@ -40,7 +39,7 @@
|
||||
#include <mm.h>
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
|
||||
#include <xmalloc.h>
|
||||
|
||||
#ifdef MM_DEBUG
|
||||
#define DEBUG(_f, _a...) \
|
||||
@@ -505,6 +504,6 @@ void init_mm(void)
|
||||
(u_long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn));
|
||||
init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));
|
||||
#endif
|
||||
|
||||
|
||||
printk("MM: done\n");
|
||||
}
|
||||