From 2db441bc176107ba2348c19a6361508a96a212c6 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Fri, 21 Oct 2011 14:17:54 -0700 Subject: [PATCH] add temporary workaround to distribute shared pages over all memory controllers --- arch/x86/mm/svm.c | 79 ++++++++++++++++++++++++++++++++++++---------- arch/x86/scc/icc.c | 12 +++---- 2 files changed, 69 insertions(+), 22 deletions(-) diff --git a/arch/x86/mm/svm.c b/arch/x86/mm/svm.c index a757bc2c..6a0449b2 100644 --- a/arch/x86/mm/svm.c +++ b/arch/x86/mm/svm.c @@ -49,7 +49,6 @@ static volatile uint8_t* page_owner = NULL; // helper array to convert a physical to a virtual address static size_t phys2virt[SHARED_PAGES] = {[0 ... SHARED_PAGES-1] = 0}; static size_t shmbegin = 0; -static int my_ue = 0; static uint32_t emit[RCCE_MAXNP] = {[0 ... RCCE_MAXNP-1] = 0}; static uint32_t request[RCCE_MAXNP] = {[0 ... RCCE_MAXNP-1] = 0}; static uint32_t forward[RCCE_MAXNP] = {[0 ... RCCE_MAXNP-1] = 0}; @@ -61,7 +60,6 @@ int svm_init(void) // iRCCE is not thread save => disable interrupts flags = irq_nested_disable(); - my_ue = RCCE_ue(); shmbegin = (size_t)RC_SHM_BUFFER_START(); phyaddr = (size_t) RCCE_shmalloc(OWNER_SIZE); irq_nested_enable(flags); @@ -84,7 +82,7 @@ int svm_init(void) } // per default is core 0 owner - if (!my_ue) + if (!RCCE_IAM) memset((void*)page_owner, 0x00, OWNER_SIZE); // iRCCE is not thread save => disable interrupts @@ -112,32 +110,29 @@ int svm_access_request(size_t addr) return -EINVAL; pageid = (phyaddr-shmbegin) >> PAGE_SHIFT; - //svm_flush(); - if (page_owner[pageid] == my_ue) + if (page_owner[pageid] == RCCE_IAM) return 0; remote_rank = page_owner[pageid]; - ((size_t*) payload)[0] = my_ue; + ((size_t*) payload)[0] = RCCE_IAM; ((size_t*) payload)[1] = phyaddr; - //kprintf("send access request to %d of 0x%x\n", remote_rank, phyaddr); /* send ping request */ iRCCE_mail_send(2*sizeof(size_t), SVM_REQUEST, 0, payload, remote_rank); request[remote_rank]++; - NOP8; icc_send_gic_irq(remote_rank); - /* check for incoming messages */ - icc_mail_check(); - - while (page_owner[pageid] != my_ue) { - check_workqueues(); + while (page_owner[pageid] != RCCE_IAM) { + icc_mail_check(); + NOP8; } return change_page_permissions(addr, addr+PAGE_SIZE, VMA_READ|VMA_WRITE|VMA_CACHEABLE); } +static atomic_int32_t size_counter = ATOMIC_INIT(0); + void* svmmalloc(size_t size, uint32_t consistency) { size_t phyaddr, viraddr, i; @@ -153,11 +148,61 @@ void* svmmalloc(size_t size, uint32_t consistency) // currently, we allocate memory in page size granulation size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); +#if 0 // Workaround for our MARC paper + // iRCCE is not thread save => disable interrupts + flags = irq_nested_disable(); + + kprintf("Entering shmmalloc: size 0x%x, owner_size 0x%x\n", size, OWNER_SIZE); + if (RCCE_IAM && (consistency & SVM_STRONG)) + map_flags |= MAP_NO_ACCESS; + + viraddr = vm_alloc(size >> PAGE_SHIFT, map_flags); + kprintf("vm_alloc returns 0x%x\n", viraddr); + + static uint32_t last = 0; + // get memory on MC0 + if (last) + phyaddr = last + size/4; + else + last = phyaddr = (size_t) RCCE_shmalloc(size/4); + map_region(viraddr, phyaddr, (size/4) >> PAGE_SHIFT, map_flags|MAP_REMAP); + for(i=0; i> PAGE_SHIFT] = viraddr + i; + kprintf("svmmalloc on MC0: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr, size); + + // get memory on MC1 + phyaddr = shmbegin + 0x1000000 + atomic_int32_read(&size_counter); + map_region(viraddr + size/4, phyaddr, (size/4) >> PAGE_SHIFT, map_flags|MAP_REMAP); + for(i=0; i> PAGE_SHIFT] = viraddr + size/4 + i; + kprintf("svmmalloc on MC1: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr+size/4, size); + + // get memory on MC2 + phyaddr = shmbegin + 0x2000000 + atomic_int32_read(&size_counter); + map_region(viraddr + 2 * size/4, phyaddr, (size/4) >> PAGE_SHIFT, map_flags|MAP_REMAP); + for(i=0; i> PAGE_SHIFT] = viraddr + 2 * size/4 + i; + kprintf("svmmalloc on MC2: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr+2*size/4, size); + + // get memory on MC3 + phyaddr = shmbegin + 0x3000000 + atomic_int32_read(&size_counter); + map_region(viraddr + 3 * size/4, phyaddr, (size/4) >> PAGE_SHIFT, map_flags|MAP_REMAP); + for(i=0; i> PAGE_SHIFT] = viraddr + 3 * size/4 + i; + kprintf("svmmalloc on MC3: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr+3*size/4, size); + + atomic_int32_add(&size_counter, size/4); + irq_nested_enable(flags); + + kprintf("shmmalloc returns 0x%x\n", viraddr); + + return (void*) viraddr; +#else // iRCCE is not thread save => disable interrupts flags = irq_nested_disable(); phyaddr = (size_t) RCCE_shmalloc(size); - if (RCCE_ue() && (consistency & SVM_STRONG)) + if (RCCE_IAM && (consistency & SVM_STRONG)) map_flags |= MAP_NO_ACCESS; irq_nested_enable(flags); @@ -175,6 +220,7 @@ void* svmmalloc(size_t size, uint32_t consistency) kprintf("svmmalloc: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr, size); return (void*) viraddr; +#endif } void svmfree(void* addr, size_t size) @@ -218,12 +264,12 @@ int svm_emit_page(size_t phyaddr, int ue) return -EINVAL; pageid = (phyaddr-shmbegin) >> PAGE_SHIFT; - if (page_owner[pageid] != my_ue) { + if (page_owner[pageid] != RCCE_IAM) { // Core is nor owner => forward request to new owner int remote_rank; uint8_t payload[iRCCE_MAIL_HEADER_PAYLOAD]; - kprintf("Ups, core %d is not owner of page 0x%x\n", my_ue, phyaddr); + kprintf("Ups, core %d is not owner of page 0x%x\n", RCCE_IAM, phyaddr); remote_rank = page_owner[pageid]; ((size_t*) payload)[0] = ue; @@ -258,6 +304,7 @@ void svm_flush(void) *(int *)RCCE_fool_write_combine_buffer = 1; flush_cache(); +#error Currently not supported #if 0 // try to flush L2 cache z = Z_PID(RC_COREID[my_ue]); diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 81258250..97796658 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -161,7 +161,7 @@ static void icc_handler(struct state *s) /* empty mail queue */ while( iRCCE_mail_recv(&header) == iRCCE_SUCCESS ) { icc_mail_check_tag(header); - iRCCE_mail_release( &header ); + iRCCE_mail_release(&header); NOP8; NOP8; NOP8; @@ -331,7 +331,7 @@ int icc_mail_ping(void) /* leave function if not participating in pingpong */ if( (RCCE_IAM != CORE_A) && (RCCE_IAM != CORE_B) ) return -1; - kprintf( "my_ue = %d\n", RCCE_IAM); + kprintf( "my rank = %d\n", RCCE_IAM); kprintf( "Hello from mail_ping ... \n" ); kprintf( "rounds = %d\n", ROUNDS ); @@ -401,7 +401,7 @@ int icc_mail_ping_irq(void) int res; iRCCE_MAIL_HEADER* recv_header = NULL; - kprintf( "my_rank = %d\n", RCCE_IAM ); + kprintf( "my rank = %d\n", RCCE_IAM ); kprintf( "rem_rank = %d\n", CORE_B ); kprintf( "rounds = %d\n", ROUNDS ); @@ -503,9 +503,6 @@ void icc_mail_check(void) iRCCE_mail_check(iRCCE_MAILBOX_ALL); - /* enable interrupts */ - irq_nested_enable(flags); - /* empty mail queue */ while( iRCCE_mail_recv(&header) == iRCCE_SUCCESS ) { icc_mail_check_tag(header); @@ -514,6 +511,9 @@ void icc_mail_check(void) NOP8; NOP8; } + + /* enable interrupts */ + irq_nested_enable(flags); } #endif