Merge branch 'svm' of git.lfbs.rwth-aachen.de:metalsvm into svm

Conflicts:
	arch/x86/mm/svm.c
This commit is contained in:
Stefan Lankes 2011-11-10 01:00:45 -08:00
commit e68568aa8f
6 changed files with 121 additions and 44 deletions

View file

@ -114,8 +114,9 @@ static int mail_noise(void*arg) {
return 0;
}
#define N 1024
//#define N 514
//#define N 1024
//#define N 512
#define N 128
#define LAZY
#define L2_ENABLE
@ -139,6 +140,8 @@ static int svm_test(void *arg)
int my_ue, num_ues;
register int tmp;
kputs("Start SVM test...\n");
RCCE_barrier(&RCCE_COMM_WORLD);
my_ue = RCCE_ue();
num_ues = RCCE_num_ues();
@ -191,9 +194,13 @@ static int svm_test(void *arg)
#ifdef LAZY
svm_flags = SVM_LAZYRELEASE;
kputs("Use Lazy Release consistency!\n");
#else
kputs("Use Strong Release consistency!\n");
#endif
#ifdef L2_ENABLE
kputs("Use Level 2 Cache!\n");
svm_flags |= SVM_L2;
#endif
@ -216,7 +223,7 @@ static int svm_test(void *arg)
}
}
svm_flush();
svm_flush(0);
RCCE_barrier(&RCCE_COMM_WORLD);
kputs("Start parallel calculation...\n");
@ -238,7 +245,7 @@ static int svm_test(void *arg)
}
}
svm_flush();
svm_flush(0);
RCCE_barrier(&RCCE_COMM_WORLD);
end = rdtsc();
@ -320,9 +327,9 @@ int test_init(void)
char* server_argv[] = {"/bin/server", "6789", NULL};
char* client_argv[] = {"/bin/client", "192.168.0.1", "6789", NULL};
sem_init(&producing, 1);
sem_init(&consuming, 0);
mailbox_int32_init(&mbox);
//sem_init(&producing, 1);
//sem_init(&consuming, 0);
//mailbox_int32_init(&mbox);
//create_kernel_task(NULL, foo, "Hello from foo1", NORMAL_PRIO);
//create_kernel_task(NULL, join_test, NULL, NORMAL_PRIO);
@ -330,7 +337,7 @@ int test_init(void)
//create_kernel_task(NULL, consumer, NULL, NORMAL_PRIO);
//create_kernel_task(NULL, mail_ping, NULL, NORMAL_PRIO);
//create_kernel_task(NULL, mail_noise, NULL, NORMAL_PRIO);
//create_kernel_task(NULL, svm_test, NULL, NORMAL_PRIO);
create_kernel_task(NULL, svm_test, NULL, NORMAL_PRIO);
//create_kernel_task(NULL, pi, NULL, NORMAL_PRIO);
create_kernel_task(NULL, laplace, NULL, NORMAL_PRIO);
//create_user_task(NULL, "/bin/hello", argv);

View file

@ -67,6 +67,7 @@
/// Pattern flag
#define PG_PAT (1 << _PAGE_BIT_PAT)
/// This virtual address range is used by SVM system as marked
#define PG_SVM PG_SVM_STRONG
#define PG_SVM_STRONG (1 << _PAGE_BIT_SVM_STRONG)
/// This virtual address range is used by SVM system as marked
#define PG_SVM_LAZYRELEASE (1 << _PAGE_BIT_SVM_LAZYRELEASE)

View file

@ -31,6 +31,8 @@ extern "C" {
#ifdef CONFIG_ROCKCREEK
#define SVM_WB
#define SVM_STRONG (1 << 0)
#define SVM_LAZYRELEASE (1 << 1)
#define SVM_L2 (1 << 4)
@ -93,7 +95,7 @@ static inline void svm_flush(void)
*(int *)RCCE_fool_write_combine_buffer = 1;
}
#else
void svm_flush(void);
void svm_flush(size_t addr);
#endif
#endif

View file

@ -784,7 +784,7 @@ int arch_paging_init(void)
kprintf("Map configuration registers at 0x%x\n", viraddr);
// map SCC's message passing buffers
viraddr = map_region(MPB_X0_Y0, MPB_X0_Y0, (MPB_OWN-MPB_X0_Y0+16*1024*1024) >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_MPE);
viraddr = map_region(MPB_X0_Y0, MPB_X0_Y0, (MPB_OWN-MPB_X0_Y0+64*1024*1024) >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_MPE);
kprintf("Map message passing buffers at 0x%x\n", viraddr);
// map the FPGA registers

View file

@ -51,7 +51,7 @@ static volatile atomic_increg_t *incregs = NULL;
static RCCE_FLAG release;
/*
* Information to realize L2 flush
* Details on L2 cache (nedded for flushing)
*/
#define OWN_MPB 0xd8000000
@ -80,36 +80,6 @@ __attribute__((always_inline)) static inline void svm_purge_set(const size_t set
static size_t dummy_base = OWN_MPB + L2_CAPACITY;
static size_t dummy_offset = 0;
/*
* Function to flush one page with L2 cache enabled!
*/
void svm_flush_page(const size_t address)
{
size_t line;
size_t dummy = dummy_base + dummy_offset;
size_t addr;
uint32_t flags;
/* toggle between dummy areas */
if(dummy_offset)
dummy_offset = 0;
else
dummy_offset = L2_CAPACITY;
/* align the address to page boundaries */
addr &= ~(PAGE_SIZE-1);
/* disable iterrupts due to pseudo LRU behavior of L2 cache*/
flags = irq_nested_disable();
/* for exact one page */
for( line = 0; line < PAGE_SIZE; line += L2_LINESIZE )
svm_purge_set( ( ( addr + line ) % L2_WBSTRIDE ) + dummy );
irq_nested_enable(flags);
}
/*
* This array describes the owner of a specific page.
* Only the owner of a page is able to change the possession.
@ -239,17 +209,22 @@ int svm_access_request(size_t addr)
return ret;
}
#if 0
static atomic_int32_t size_counter = ATOMIC_INIT(0);
#endif
void* svm_malloc(size_t size, uint32_t consistency)
{
size_t viraddr;
//size_t phyaddr, viraddr, i;
//uint32_t flags;
task_t* task = per_core(current_task);
uint32_t map_flags = MAP_KERNEL_SPACE;
if( !(consistency & SVM_L2) )
map_flags |= MAP_MPE;
else
task->flags |= TASK_L2;
if (consistency & SVM_STRONG)
map_flags |= MAP_SVM_STRONG;
@ -411,7 +386,7 @@ int svm_emit_page(size_t phyaddr, int ue)
} else {
size_t viraddr;
svm_flush();
svm_flush(phyaddr);
// send response back to ue
// ue is polling for the response => no irq is needed
@ -428,7 +403,7 @@ int svm_emit_page(size_t phyaddr, int ue)
return 0;
}
#ifdef SVM_WB
#if 0
void svm_flush(void)
{
int z, tmp;
@ -452,6 +427,97 @@ void svm_flush(void)
}
#endif
/*
* Function to flush one page or entire cache.
*/
#ifdef SVM_WB
void svm_flush( size_t phyaddr )
{
task_t* task = per_core(current_task);
page_dir_t* pgd = task->pgd;
page_table_t* pgt = NULL;
size_t step = 0;
size_t stride = L2_LINESIZE;
size_t range = L2_WBSTRIDE;
size_t viraddr;
uint32_t index1, index2;
uint32_t flags;
/* flush entire Cache if phyaddr == 0 */
if(!phyaddr) {
if( task->flags & TASK_L2 ){
goto flush_l2;
} else {
goto flush_l1;
}
/* flush one page */
} else {
/* align the address to page boundaries */
phyaddr &= ~(PAGE_SIZE-1);
/* lookup pgt to check if L2 is enabled */
viraddr = phys2virt[(phyaddr - shmbegin) >> PAGE_SHIFT];
index1 = viraddr >> 22;
index2 = (viraddr >> 12) & 0x3FF;
/* check if pgt is present */
if (!pgd || !(pgd->entries[index1] & 0xFFFFF000))
goto wrong_addr;
pgt = (page_table_t*)((KERNEL_SPACE - 1024 * PAGE_SIZE + index1 * PAGE_SIZE) & 0xFFFFF000);
if( pgt->entries[index2] & PG_MPE ) {
goto flush_l1;
} else {
phyaddr = phyaddr % L2_WBSTRIDE;
range = PAGE_SIZE;
goto flush_l2;
}
}
/*
* FLUSH L1 CACHE:
*/
flush_l1:
kputs("flush L1\n");
*(int *)RCCE_fool_write_combine_buffer = 1;
//__asm__ volatile ( "wbinvd;\n\t" );
flush_cache();
return;
flush_l2:
/*
* FLUSH L2 CACHE:
* disable iterrupts due to pseudo LRU behavior of L2 cache
*/
flags = irq_nested_disable();
/* toggle between dummy areas */
phyaddr += dummy_base + dummy_offset;
kprintf("flush-l2: phyaddr 0x%x\n", phyaddr);
if(dummy_offset)
dummy_offset = 0;
else
dummy_offset = L2_CAPACITY;
flush_cache();
for( step = 0; step < range; step += stride )
svm_purge_set( phyaddr + step );
irq_nested_enable(flags);
return;
wrong_addr:
kputs("svm flush error: address not valid!\n");
return;
}
#endif
int svm_barrier(uint32_t type)
{
int i;
@ -459,7 +525,7 @@ int svm_barrier(uint32_t type)
static int index = 0;
if (type == SVM_LAZYRELEASE) {
svm_flush();
svm_flush(0);
svm_invalidate();
}

View file

@ -59,6 +59,7 @@ extern "C" {
#define TASK_FPU_INIT (1 << 0)
#define TASK_FPU_USED (1 << 1)
#define TASK_TIMER (1 << 2)
#define TASK_L2 (1 << 3)
typedef int (*entry_point_t)(void*);
typedef int (STDCALL *internal_entry_point_t)(void*);