kmalloc()/kfree(): allow CPU cores to kfree() a piece of memory that was kmalloc()ed by another core through embedding CPU id into malloc_header

This commit is contained in:
Balazs Gerofi bgerofi@riken.jp
2014-09-14 23:22:43 +09:00
parent 225509786f
commit f7780cfe93
2 changed files with 13 additions and 9 deletions

View File

@ -21,6 +21,7 @@
struct malloc_header { struct malloc_header {
struct malloc_header *next; struct malloc_header *next;
unsigned int cpu_id;
unsigned long size; unsigned long size;
}; };
@ -36,6 +37,7 @@ extern ihk_spinlock_t cpu_status_lock;
struct cpu_local_var { struct cpu_local_var {
/* malloc */ /* malloc */
struct malloc_header free_list; struct malloc_header free_list;
ihk_spinlock_t free_list_lock;
struct process idle; struct process idle;
struct process_vm idle_vm; struct process_vm idle_vm;

View File

@ -641,6 +641,7 @@ void kmalloc_init(void)
{ {
struct cpu_local_var *v = get_this_cpu_local_var(); struct cpu_local_var *v = get_this_cpu_local_var();
struct malloc_header *h = &v->free_list; struct malloc_header *h = &v->free_list;
ihk_mc_spinlock_init(&v->free_list_lock);
h->next = &v->free_list; h->next = &v->free_list;
h->size = 0; h->size = 0;
@ -662,7 +663,7 @@ void *kmalloc(int size, enum ihk_mc_ap_flag flag)
u = (size + sizeof(*h) - 1) / sizeof(*h); u = (size + sizeof(*h) - 1) / sizeof(*h);
flags = cpu_disable_interrupt_save(); flags = ihk_mc_spinlock_lock(&v->free_list_lock);
prev = h; prev = h;
h = h->next; h = h->next;
@ -687,16 +688,18 @@ void *kmalloc(int size, enum ihk_mc_ap_flag flag)
if (h->size >= u) { if (h->size >= u) {
if (h->size == u || h->size == u + 1) { if (h->size == u || h->size == u + 1) {
prev->next = h->next; prev->next = h->next;
h->cpu_id = ihk_mc_get_processor_id();
cpu_restore_interrupt(flags); ihk_mc_spinlock_unlock(&v->free_list_lock, flags);
return h + 1; return h + 1;
} else { /* Divide */ } else { /* Divide */
h->size -= u + 1; h->size -= u + 1;
p = h + h->size + 1; p = h + h->size + 1;
p->size = u; p->size = u;
p->cpu_id = ihk_mc_get_processor_id();
cpu_restore_interrupt(flags); ihk_mc_spinlock_unlock(&v->free_list_lock, flags);
return p + 1; return p + 1;
} }
} }
@ -707,16 +710,15 @@ void *kmalloc(int size, enum ihk_mc_ap_flag flag)
void kfree(void *ptr) void kfree(void *ptr)
{ {
struct cpu_local_var *v = get_this_cpu_local_var(); struct malloc_header *p = (struct malloc_header *)ptr;
struct malloc_header *h = &v->free_list, *p = ptr; struct cpu_local_var *v = get_cpu_local_var((--p)->cpu_id);
struct malloc_header *h = &v->free_list;
int combined = 0; int combined = 0;
unsigned long flags; unsigned long flags;
flags = cpu_disable_interrupt_save(); flags = ihk_mc_spinlock_lock(&v->free_list_lock);
h = h->next; h = h->next;
p--;
while ((p < h || p > h->next) && h != &v->free_list) { while ((p < h || p > h->next) && h != &v->free_list) {
h = h->next; h = h->next;
} }
@ -738,7 +740,7 @@ void kfree(void *ptr)
p->next = h->next; p->next = h->next;
h->next = p; h->next = p;
} }
cpu_restore_interrupt(flags); ihk_mc_spinlock_unlock(&v->free_list_lock, flags);
} }
void print_free_list(void) void print_free_list(void)