From 9c15383d2cf95181d4c3356dd153f44a738ca061 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Fri, 19 Aug 2011 00:11:36 -0700 Subject: [PATCH] add first running version of our svm system --- arch/x86/include/asm/processor.h | 7 --- arch/x86/include/asm/svm.h | 14 +++++ arch/x86/mm/page.c | 4 ++ arch/x86/mm/svm.c | 36 +++++++----- arch/x86/scc/icc.c | 2 +- kernel/tests.c | 96 ++++++++++++++++++++++++-------- 6 files changed, 115 insertions(+), 44 deletions(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 5d79e4ac..82393d13 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -123,13 +123,6 @@ inline static int get_return_value(void) { return ret; } -#ifdef CONFIG_ROCKCREEK -static inline void invalidate_cl1(void) -{ - asm volatile ( ".byte 0x0f; .byte 0x0a;\n" ); // CL1FLUSHMB -} -#endif - /* Force strict CPU ordering */ #ifdef CONFIG_ROCKCREEK inline static void mb(void) { asm volatile ("lock; addl $0,0(%%esp)" ::: "memory"); } diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 667d10a2..1b0b3c1d 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -65,6 +65,20 @@ int svm_access_request(size_t addr); */ int svm_emit_page(size_t addr, int ue); +static inline void svm_invalidate(void) +{ + asm volatile ( ".byte 0x0f; .byte 0x0a;\n" ); // CL1FLUSHMB +} + +static inline void svm_flush(void) +{ + mb(); +#ifndef SVM_WT + flush_cache(); +#endif + //asm volatile ( ".byte 0x0f; .byte 0x0a;\n" ); // CL1FLUSHMB +} + #endif #ifdef __cplusplus diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index ee9e5f83..2bde433c 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -356,7 +356,11 @@ size_t map_region(size_t viraddr, size_t phyaddr, uint32_t npages, uint32_t flag pgt->entries[index] |= PG_MPE; #endif if (flags & MAP_SVM) +#ifdef SVM_WT + pgt->entries[index] |= PG_SVM|PG_PWT; +#else pgt->entries[index] |= PG_SVM; +#endif if (flags & MAP_NO_ACCESS) pgt->entries[index] &= ~PG_PRESENT; diff --git a/arch/x86/mm/svm.c b/arch/x86/mm/svm.c index 3c3f8458..cf1868ad 100644 --- a/arch/x86/mm/svm.c +++ b/arch/x86/mm/svm.c @@ -60,8 +60,13 @@ int svm_init(void) shmbegin = (size_t)RC_SHM_BUFFER_START(); phyaddr = (size_t) RCCE_shmalloc(OWNER_SIZE); irq_nested_enable(flags); + if (BUILTIN_EXPECT(!phyaddr, 0)) return -ENOMEM; + if (BUILTIN_EXPECT(phyaddr & 0xFFF, 0)) { + kprintf("RCCE_shmalloc returns not a page aligned physiacl address: 0x%x\n", phyaddr); + return -ENOMEM; + } kprintf("Shared memory starts at the physical address 0x%x\n", shmbegin); @@ -96,15 +101,14 @@ int svm_access_request(size_t addr) int remote_rank; uint8_t payload[iRCCE_MAIL_HEADER_PAYLOAD]; - kprintf("enter svm_access_request\n"); - if (phyaddr < shmbegin) return -EINVAL; if (phyaddr >= shmbegin + RCCE_SHM_SIZE_MAX) return -EINVAL; pageid = (phyaddr-shmbegin) >> PAGE_SHIFT; - invalidate_cl1(); + svm_flush(); + svm_invalidate(); if (page_owner[pageid] == my_ue) return 0; @@ -112,7 +116,7 @@ int svm_access_request(size_t addr) ((size_t*) payload)[0] = my_ue; ((size_t*) payload)[1] = phyaddr; - kprintf("send access request to %d of 0x%x\n", remote_rank, phyaddr); + //kprintf("send access request to %d of 0x%x\n", remote_rank, phyaddr); /* send ping request */ iRCCE_mail_send(2*sizeof(size_t), ICC_TAG_SVMREQUEST, 0, payload, remote_rank); @@ -122,12 +126,12 @@ int svm_access_request(size_t addr) /* check for incoming messages */ icc_mail_check(); - invalidate_cl1(); + svm_invalidate(); while (page_owner[pageid] != my_ue) { NOP4; - invalidate_cl1(); - }; + svm_invalidate(); + } return change_page_permissions(addr, addr+PAGE_SIZE, VMA_READ|VMA_WRITE|VMA_CACHEABLE); } @@ -149,13 +153,18 @@ void* svmmalloc(size_t size) if (RCCE_ue()) map_flags |= MAP_NO_ACCESS; irq_nested_enable(flags); + if (BUILTIN_EXPECT(!phyaddr, 0)) return NULL; + if (BUILTIN_EXPECT(phyaddr & 0xFFF, 0)) { + kprintf("RCCE_shmalloc returns not a page aligned physiacl address: 0x%x\n", phyaddr); + return NULL; + } viraddr = map_region(0, phyaddr, size >> PAGE_SHIFT, map_flags); phys2virt[(phyaddr - shmbegin) >> PAGE_SHIFT] = viraddr; - //kprintf("shmmalloc: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr, size); + kprintf("svmmalloc: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr, size); return (void*) viraddr; } @@ -173,7 +182,7 @@ void svmfree(void* addr, size_t size) // currently, we allocate memory in page size granulation size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); - //kprintf("shmmalloc: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, addr, size); + kprintf("svmfree: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, addr, size); unmap_region((size_t) addr, size >> PAGE_SHIFT); phys2virt[(phyaddr - shmbegin) >> PAGE_SHIFT] = 0; @@ -192,7 +201,7 @@ int svm_emit_page(size_t phyaddr, int ue) { uint32_t pageid; - kprintf("Try to emit page 0x%x to %d\n", phyaddr, ue); + //kprintf("Try to emit page 0x%x to %d\n", phyaddr, ue); if (phyaddr < shmbegin) return -EINVAL; @@ -200,7 +209,6 @@ int svm_emit_page(size_t phyaddr, int ue) return -EINVAL; pageid = (phyaddr-shmbegin) >> PAGE_SHIFT; - invalidate_cl1(); if (page_owner[pageid] != my_ue) { // Core is nor owner => forward request to new owner int remote_rank; @@ -220,12 +228,12 @@ int svm_emit_page(size_t phyaddr, int ue) } else { size_t viraddr = phys2virt[(phyaddr - shmbegin) >> PAGE_SHIFT]; + svm_flush(); change_page_permissions(viraddr, viraddr+PAGE_SIZE, VMA_NOACCESS|VMA_READ|VMA_CACHEABLE); - invalidate_cl1(); + svm_invalidate(); page_owner[pageid] = ue; - mb(); - invalidate_cl1(); + svm_flush(); } return 0; diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 06d7beb5..79ca128e 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -132,7 +132,7 @@ int icc_init(void) return -ENODEV; // enable additional outputs - RCCE_debug_set(RCCE_DEBUG_ALL); + //RCCE_debug_set(RCCE_DEBUG_ALL); my_ue = RCCE_ue(); num_ues = RCCE_num_ues(); diff --git a/kernel/tests.c b/kernel/tests.c index e5e1a8fe..61e1f38b 100644 --- a/kernel/tests.c +++ b/kernel/tests.c @@ -115,11 +115,6 @@ int mail_ping(void* arg) { return 0; } -static inline void cache_invalidate(void) -{ - asm volatile ( ".byte 0x0f; .byte 0x0a;\n" ); // CL1FLUSHMB -} - #define N 1024 volatile static int* A[N]; @@ -128,15 +123,16 @@ volatile static int* C[N]; static int svm_test(void *arg) { - uint32_t i, j, k, flags; + uint64_t start, end; + uint32_t i, j, k;//, flags; int my_ue, num_ues; // iRCCE is not thread save => disable interrupts - flags = irq_nested_disable(); + //flags = irq_nested_disable(); RCCE_barrier(&RCCE_COMM_WORLD); my_ue = RCCE_ue(); num_ues = RCCE_num_ues(); - irq_nested_enable(flags); + //irq_nested_enable(flags); // allocate and initialize SVM region A[0] = (int*) svmmalloc(3*N*N*sizeof(int)); @@ -146,42 +142,98 @@ static int svm_test(void *arg) // initialize matrices for(i=0; i disable interrupts - flags = irq_nested_disable(); + //flags = irq_nested_disable(); RCCE_barrier(&RCCE_COMM_WORLD); - irq_nested_enable(flags); + //irq_nested_enable(flags); - kputs("Start calculation...\n"); + kputs("Start sequentiell calculation...\n"); + + start = rdtsc(); + start = rdtsc(); + + // start calculation + if (!my_ue) { + for(i=0; i disable interrupts + //flags = irq_nested_disable(); + RCCE_barrier(&RCCE_COMM_WORLD); + //irq_nested_enable(flags); + + kputs("Start parallel calculation...\n"); + + start = rdtsc(); + start = rdtsc(); // start calculation for(i=my_ue*(N/num_ues); i<(my_ue+1)*(N/num_ues); i++) for(j=0; j disable interrupts - flags = irq_nested_disable(); + //flags = irq_nested_disable(); RCCE_barrier(&RCCE_COMM_WORLD); - irq_nested_enable(flags); + //irq_nested_enable(flags); - kputs("Calculation finished...\n"); + kputs("Check results...\n"); + + if (!my_ue) { + uint32_t err = 0; + + for(i=0; (i disable interrupts + //flags = irq_nested_disable(); + RCCE_barrier(&RCCE_COMM_WORLD); + //irq_nested_enable(flags); + + kprintf("Calculation time (par): %llu\n", end-start); svmfree((void*) A[0], 3*N*sizeof(int)); @@ -353,8 +405,8 @@ int test_init(void) //create_kernel_task(NULL, join_test, NULL); //create_kernel_task(NULL, producer, NULL); //create_kernel_task(NULL, consumer, NULL); - create_kernel_task(NULL, mail_ping, NULL); - //create_kernel_task(NULL, svm_test, NULL); + //create_kernel_task(NULL, mail_ping, NULL); + create_kernel_task(NULL, svm_test, NULL); //create_user_task(NULL, "/bin/hello", argv); //create_user_task(NULL, "/bin/tests", argv); //create_user_task(NULL, "/bin/jacobi", argv);