sandbox: vm: add synchronisation using spinlocks
This commit is contained in:
@@ -140,6 +140,9 @@ static unsigned int pointer_to_slot(vm_slab_t *slab, void *p)
|
|||||||
|
|
||||||
void *vm_cache_alloc(vm_cache_t *cache, vm_flags_t flags)
|
void *vm_cache_alloc(vm_cache_t *cache, vm_flags_t flags)
|
||||||
{
|
{
|
||||||
|
unsigned long irq_flags;
|
||||||
|
spin_lock_irqsave(&cache->c_lock, &irq_flags);
|
||||||
|
|
||||||
vm_slab_t *slab = NULL;
|
vm_slab_t *slab = NULL;
|
||||||
if (!queue_empty(&cache->c_slabs_partial)) {
|
if (!queue_empty(&cache->c_slabs_partial)) {
|
||||||
/* prefer using up partially-full slabs before taking a fresh one */
|
/* prefer using up partially-full slabs before taking a fresh one */
|
||||||
@@ -156,6 +159,7 @@ void *vm_cache_alloc(vm_cache_t *cache, vm_flags_t flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!slab) {
|
if (!slab) {
|
||||||
|
spin_unlock_irqrestore(&cache->c_lock, irq_flags);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +171,8 @@ void *vm_cache_alloc(vm_cache_t *cache, vm_flags_t flags)
|
|||||||
} else {
|
} else {
|
||||||
queue_push_back(&cache->c_slabs_partial, &slab->s_list);
|
queue_push_back(&cache->c_slabs_partial, &slab->s_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&cache->c_lock, irq_flags);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <socks/types.h>
|
#include <socks/types.h>
|
||||||
#include <socks/status.h>
|
#include <socks/status.h>
|
||||||
#include <socks/queue.h>
|
#include <socks/queue.h>
|
||||||
|
#include <socks/locks.h>
|
||||||
|
|
||||||
/* maximum number of NUMA nodes */
|
/* maximum number of NUMA nodes */
|
||||||
#define VM_MAX_NODES 64
|
#define VM_MAX_NODES 64
|
||||||
@@ -106,6 +107,7 @@ typedef struct vm_zone_descriptor {
|
|||||||
|
|
||||||
typedef struct vm_zone {
|
typedef struct vm_zone {
|
||||||
vm_zone_descriptor_t z_info;
|
vm_zone_descriptor_t z_info;
|
||||||
|
spin_lock_t z_lock;
|
||||||
|
|
||||||
queue_t z_free_pages[VM_MAX_PAGE_ORDERS];
|
queue_t z_free_pages[VM_MAX_PAGE_ORDERS];
|
||||||
unsigned long z_size;
|
unsigned long z_size;
|
||||||
@@ -130,6 +132,8 @@ typedef struct vm_cache {
|
|||||||
queue_t c_slabs_partial;
|
queue_t c_slabs_partial;
|
||||||
queue_t c_slabs_empty;
|
queue_t c_slabs_empty;
|
||||||
|
|
||||||
|
spin_lock_t c_lock;
|
||||||
|
|
||||||
/* number of objects that can be stored in a single slab */
|
/* number of objects that can be stored in a single slab */
|
||||||
unsigned int c_obj_count;
|
unsigned int c_obj_count;
|
||||||
/* the size of object kept in the cache */
|
/* the size of object kept in the cache */
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "socks/queue.h"
|
#include <socks/locks.h>
|
||||||
|
#include <socks/queue.h>
|
||||||
#include <socks/types.h>
|
#include <socks/types.h>
|
||||||
#include <socks/vm.h>
|
#include <socks/vm.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -96,6 +97,10 @@ void vm_zone_init(vm_zone_t *z, const vm_zone_descriptor_t *zone_info)
|
|||||||
zone_info->zd_name, zone_info->zd_base, zone_info->zd_limit);
|
zone_info->zd_name, zone_info->zd_base, zone_info->zd_limit);
|
||||||
memset(z, 0x0, sizeof *z);
|
memset(z, 0x0, sizeof *z);
|
||||||
memcpy(&z->z_info, zone_info, sizeof *zone_info);
|
memcpy(&z->z_info, zone_info, sizeof *zone_info);
|
||||||
|
z->z_lock = SPIN_LOCK_INIT;
|
||||||
|
|
||||||
|
unsigned long flags;
|
||||||
|
spin_lock_irqsave(&z->z_lock, &flags);
|
||||||
|
|
||||||
phys_addr_t block_start = zone_info->zd_base, block_end = zone_info->zd_limit;
|
phys_addr_t block_start = zone_info->zd_base, block_end = zone_info->zd_limit;
|
||||||
int this_page_reserved = 0, last_page_reserved = -1;
|
int this_page_reserved = 0, last_page_reserved = -1;
|
||||||
@@ -126,6 +131,8 @@ void vm_zone_init(vm_zone_t *z, const vm_zone_descriptor_t *zone_info)
|
|||||||
if (block_start != block_end) {
|
if (block_start != block_end) {
|
||||||
convert_region_to_blocks(z, block_start, block_end + VM_PAGE_SIZE - 1, this_page_reserved);
|
convert_region_to_blocks(z, block_start, block_end + VM_PAGE_SIZE - 1, this_page_reserved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&z->z_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int replenish_free_page_list(vm_zone_t *z, vm_page_order_t order)
|
static int replenish_free_page_list(vm_zone_t *z, vm_page_order_t order)
|
||||||
@@ -179,8 +186,12 @@ static int replenish_free_page_list(vm_zone_t *z, vm_page_order_t order)
|
|||||||
|
|
||||||
vm_page_t *vm_zone_alloc_page(vm_zone_t *z, vm_page_order_t order, vm_flags_t flags)
|
vm_page_t *vm_zone_alloc_page(vm_zone_t *z, vm_page_order_t order, vm_flags_t flags)
|
||||||
{
|
{
|
||||||
|
unsigned long irq_flags;
|
||||||
|
spin_lock_irqsave(&z->z_lock, &irq_flags);
|
||||||
|
|
||||||
int result = replenish_free_page_list(z, order);
|
int result = replenish_free_page_list(z, order);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
|
spin_unlock_irqrestore(&z->z_lock, irq_flags);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,11 +201,15 @@ vm_page_t *vm_zone_alloc_page(vm_zone_t *z, vm_page_order_t order, vm_flags_t fl
|
|||||||
i->p_flags |= VM_PAGE_ALLOC;
|
i->p_flags |= VM_PAGE_ALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&z->z_lock, irq_flags);
|
||||||
return pg;
|
return pg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vm_zone_free_page(vm_zone_t *z, vm_page_t *pg)
|
void vm_zone_free_page(vm_zone_t *z, vm_page_t *pg)
|
||||||
{
|
{
|
||||||
|
unsigned long irq_flags;
|
||||||
|
spin_lock_irqsave(&z->z_lock, &irq_flags);
|
||||||
|
|
||||||
pg->p_flags &= ~VM_PAGE_ALLOC;
|
pg->p_flags &= ~VM_PAGE_ALLOC;
|
||||||
queue_push_back(&z->z_free_pages[pg->p_order], &pg->p_list);
|
queue_push_back(&z->z_free_pages[pg->p_order], &pg->p_list);
|
||||||
|
|
||||||
@@ -211,4 +226,6 @@ void vm_zone_free_page(vm_zone_t *z, vm_page_t *pg)
|
|||||||
|
|
||||||
pg = huge;
|
pg = huge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&z->z_lock, irq_flags);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user