add first running version of our svm system
This commit is contained in:
parent
1f178b99cc
commit
9c15383d2c
6 changed files with 115 additions and 44 deletions
|
@ -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"); }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<N; i++) {
|
||||
A[i] = A[0] + i*N;
|
||||
B[i] = A[0] + i*N + N*N;
|
||||
C[i] = A[0] + i*N + 2*N*N;
|
||||
B[i] = A[0] + (i*N + N*N);
|
||||
C[i] = A[0] + (i*N + 2*N*N);
|
||||
}
|
||||
if (!my_ue) {
|
||||
for(i=0; i<N; i++) {
|
||||
A[i][i] = 1;
|
||||
for(j=0; j<N; j++)
|
||||
B[i][j] = j;
|
||||
B[i][j] = i+j;
|
||||
}
|
||||
}
|
||||
|
||||
// CL1FLUSH
|
||||
invalidate_cl1();
|
||||
svm_flush();
|
||||
|
||||
// Now, we need only read access on A and B
|
||||
//change_page_permissions((size_t) A[0], (size_t) (A[0]+2*N*N), VMA_CACHEABLE|VMA_READ);
|
||||
|
||||
// iRCCE is not thread save => 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<N; i++)
|
||||
for(j=0; j<N; j++)
|
||||
for(k=0; k<N; k++)
|
||||
C[i][j] += A[i][k] * B[k][j];
|
||||
}
|
||||
|
||||
|
||||
end = rdtsc();
|
||||
|
||||
if (!my_ue) {
|
||||
memset(C[0], 0x00, N*N*sizeof(int));
|
||||
// CL1FLUSH
|
||||
svm_flush();
|
||||
|
||||
kprintf("Calculation time (seq): %llu\n", end-start);
|
||||
}
|
||||
|
||||
|
||||
// iRCCE is not thread save => 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<N; j++)
|
||||
for(k=0; k<N; k++)
|
||||
C[i][j] = A[i][k] * B[k][j];
|
||||
C[i][j] += A[i][k] * B[k][j];
|
||||
|
||||
svm_flush();
|
||||
|
||||
end = rdtsc();
|
||||
|
||||
// iRCCE is not thread save => 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<N) && (err < 10); i++) {
|
||||
for(j=0; (j<N) && (err < 10); j++) {
|
||||
if (C[i][j] != i+j) {
|
||||
err++;
|
||||
kprintf("Wrong value at C[%u][%u] = %u, B[%u][%u] = %u\n", i, j, C[i][j], i, j, B[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iRCCE is not thread save => 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);
|
||||
|
|
Loading…
Add table
Reference in a new issue