add SVM demo example and redesign of the SVM system

This commit is contained in:
Stefan Lankes 2011-08-15 07:16:12 -07:00
parent 7980fd5bd7
commit 62e7ead997
5 changed files with 138 additions and 10 deletions

View file

@ -26,6 +26,8 @@
extern "C" {
#endif
#ifdef CONFIG_ROCKCREEK
/** @brief Memory allocator of the SVM subsystem.
*
* Like RCCE function, belongs svmmalloc to the synchronous
@ -39,7 +41,9 @@ void* svmmalloc(size_t size);
*
* Like RCCE function, belongs svmfree to the synchronous function.
*/
void svmfree(void* addr);
void svmfree(void* addr, size_t size);
#endif
#ifdef __cplusplus
}

View file

@ -354,6 +354,10 @@ size_t map_region(size_t viraddr, size_t phyaddr, uint32_t npages, uint32_t flag
if (flags & MAP_MPE)
pgt->entries[index] |= PG_MPE;
#endif
if (flags & MAP_SVM)
pgt->entries[index] |= PG_SVM;
if (flags & MAP_NO_ACCESS)
pgt->entries[index] &= ~(PG_PRESENT|PG_RW);
if (flags & MAP_USER_SPACE)
atomic_int32_inc(&task->user_usage);
@ -395,6 +399,9 @@ int change_page_permissions(size_t start, size_t end, uint32_t flags)
phyaddr = pgt->entries[index2] & 0xFFFFF000;
newflags = pgt->entries[index2] & 0xFFF; // get old flags
if ((newflags & PG_SVM) && !(newflags & PG_PRESENT) && (flags & (VMA_WRITE|VMA_READ)))
newflags |= PG_PRESENT;
// update flags
if (!(flags & VMA_WRITE))
newflags &= ~PG_RW;

View file

@ -20,19 +20,61 @@
#include <metalsvm/stddef.h>
#include <metalsvm/stdio.h>
#include <metalsvm/stdlib.h>
#include <asm/svm.h>
#include <metalsvm/mmu.h>
#include <metalsvm/page.h>
#include <asm/irqflags.h>
#ifdef CONFIG_ROCKCREEK
#include <asm/RCCE_lib.h>
#include <asm/SCC_API.h>
#include <asm/icc.h>
#endif
#include <asm/svm.h>
void* svmmalloc(size_t size)
{
return (void*) RCCE_shmalloc(size);
size_t phyaddr;
size_t viraddr;
uint32_t flags;
uint32_t map_flags = MAP_KERNEL_SPACE|MAP_MPE|MAP_SVM;
// currently, we allocate memory in page size granulation
size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
// iRCCE is not thread save => disable interrupts
flags = irq_nested_disable();
phyaddr = (size_t) RCCE_shmalloc(size);
if (RCCE_ue())
map_flags |= MAP_NO_ACCESS;
irq_nested_enable(flags);
viraddr = map_region(0, phyaddr, size >> PAGE_SHIFT, map_flags);
//kprintf("shmmalloc: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr, size);
return (void*) viraddr;
}
void svmfree(void* addr)
void svmfree(void* addr, size_t size)
{
RCCE_free((t_vcharp) addr);
size_t phyaddr;
uint32_t flags;
if (BUILTIN_EXPECT(!addr || !size, 0))
return;
phyaddr = virt_to_phys((size_t) addr);
// 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);
unmap_region((size_t) addr, size >> PAGE_SHIFT);
// iRCCE is not thread save => disable interrupts
flags = irq_nested_disable();
RCCE_shfree((t_vcharp) phyaddr);
irq_nested_enable(flags);
}
#endif

View file

@ -48,6 +48,9 @@ extern "C" {
#ifdef CONFIG_ROCKCREEK
#define MAP_MPE (1 << 8)
#endif
#define MAP_SVM (1 << 9)
#define MAP_NO_ACCESS (1 << 10)
void NORETURN abort(void);
/** @brief Kernel's memory allocator function.

View file

@ -24,12 +24,14 @@
#include <metalsvm/semaphore.h>
#include <metalsvm/mailbox.h>
#include <metalsvm/syscall.h>
#include <metalsvm/vma.h>
#ifdef CONFIG_ROCKCREEK
#include <asm/icc.h>
#include <asm/RCCE.h>
#include <asm/RCCE_lib.h>
#include <asm/iRCCE.h>
#include <asm/iRCCE_lib.h>
#include <asm/svm.h>
#include <asm/SCC_API.h>
#include <lwip/sockets.h>
@ -111,6 +113,75 @@ 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];
volatile static int* B[N];
volatile static int* C[N];
static int svm_test(void *arg)
{
uint32_t i, j, k, flags;
int my_ue, num_ues;
// iRCCE is not thread save => disable interrupts
flags = irq_nested_disable();
RCCE_barrier(&RCCE_COMM_WORLD);
my_ue = RCCE_ue();
num_ues = RCCE_num_ues();
irq_nested_enable(flags);
// allocate and initialize SVM region
A[0] = (int*) svmmalloc(3*N*N*sizeof(int));
if (!my_ue)
memset((void*) A[0], 0x00, 3*N*N*sizeof(int));
// 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;
}
if (!my_ue) {
for(i=0; i<N; i++) {
A[i][i] = 1;
for(j=0; j<N; j++)
B[i][j] = j;
}
}
// CL1FLUSH
cache_invalidate();
// Now, we need only read access on A and B
change_page_permissions(A[0], A[0]+2*N*N, VMA_CACHEABLE|VMA_READ);
// iRCCE is not thread save => disable interrupts
flags = irq_nested_disable();
RCCE_barrier(&RCCE_COMM_WORLD);
irq_nested_enable(flags);
// 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];
// iRCCE is not thread save => disable interrupts
flags = irq_nested_disable();
RCCE_barrier(&RCCE_COMM_WORLD);
irq_nested_enable(flags);
svmfree(A[0], 3*N*sizeof(int));
return 0;
}
#endif
static int join_test(void* arg)
@ -273,16 +344,17 @@ int test_init(void)
// create_kernel_task(NULL,client_task,NULL);
#endif
create_kernel_task(NULL, foo, "Hello from foo1");
create_kernel_task(NULL, join_test, NULL);
//create_kernel_task(NULL, foo, "Hello from foo1");
//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_user_task(NULL, "/bin/hello", argv);
create_user_task(NULL, "/bin/tests", argv);
//create_user_task(NULL, "/bin/tests", argv);
//create_user_task(NULL, "/bin/jacobi", argv);
//create_user_task(NULL, "/bin/jacobi", argv);
create_user_task(NULL, "/bin/server", server_argv);
//create_user_task(NULL, "/bin/server", server_argv);
//sleep(5);
//create_user_task(NULL, "/bin/client", client_argv);