add code to evaluate the performance of our SVM system

This commit is contained in:
Stefan Lankes 2011-11-07 11:28:44 -08:00
parent 0c5fddeeb3
commit 4c2525c0b3

View file

@ -34,7 +34,7 @@
#include <asm/icc.h>
#include <asm/svm.h>
#define SHARED_PAGES (RCCE_SHM_SIZE_MAX >> PAGE_SHIFT)
#define SHARED_PAGES ((4*RCCE_SHM_SIZE_MAX) >> PAGE_SHIFT)
#define OWNER_SIZE ((SHARED_PAGES * sizeof(uint8_t) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
t_vcharp RC_SHM_BUFFER_START();
@ -52,6 +52,11 @@ static size_t shmbegin = 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};
static uint64_t request_ticks = 0;
static uint64_t emit_ticks = 0;
static uint64_t wait_ticks = 0;
static uint64_t max_wait = 0;
static uint64_t min_wait = (uint64_t) -1;
int svm_init(void)
{
@ -99,10 +104,12 @@ int svm_init(void)
*/
int svm_access_request(size_t addr)
{
uint64_t start = rdtsc();
size_t phyaddr = virt_to_phys(addr);
uint32_t pageid;
int remote_rank;
uint8_t payload[iRCCE_MAIL_HEADER_PAYLOAD];
int ret;
if (phyaddr < shmbegin)
return -EINVAL;
@ -110,25 +117,33 @@ int svm_access_request(size_t addr)
return -EINVAL;
pageid = (phyaddr-shmbegin) >> PAGE_SHIFT;
if (page_owner[pageid] == RCCE_IAM)
remote_rank = page_owner[pageid];
if (remote_rank == RCCE_IAM)
return 0;
remote_rank = page_owner[pageid];
((size_t*) payload)[0] = RCCE_IAM;
((size_t*) payload)[1] = phyaddr;
/* send ping request */
iRCCE_mail_send(2*sizeof(size_t), SVM_REQUEST, 0, payload, remote_rank);
icc_send_gic_irq(remote_rank);
request[remote_rank]++;
icc_send_gic_irq(remote_rank);
while (page_owner[pageid] != RCCE_IAM) {
icc_mail_check();
NOP8;
}
uint64_t wait_start = rdtsc();
// wait for response
icc_wait(SVM_RESP);
uint64_t res = rdtsc() - wait_start;
wait_ticks += res;
if (min_wait > res)
min_wait = res;
if (max_wait < res)
max_wait = res;
return change_page_permissions(addr, addr+PAGE_SIZE, VMA_READ|VMA_WRITE|VMA_CACHEABLE);
ret = change_page_permissions(addr, addr+PAGE_SIZE, VMA_READ|VMA_WRITE|VMA_CACHEABLE);
request_ticks += rdtsc() - start;
return ret;
}
static atomic_int32_t size_counter = ATOMIC_INIT(0);
@ -148,7 +163,7 @@ 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
#if 1 // Workaround for our MARC paper
// iRCCE is not thread save => disable interrupts
flags = irq_nested_disable();
@ -253,8 +268,10 @@ void svmfree(void* addr, size_t size)
* => Interrupt flag is alread cleared.
*/
int svm_emit_page(size_t phyaddr, int ue)
{
{
uint64_t start = rdtsc();
uint32_t pageid;
int remote_rank;
//kprintf("Try to emit page 0x%x to %d\n", phyaddr, ue);
@ -264,14 +281,13 @@ int svm_emit_page(size_t phyaddr, int ue)
return -EINVAL;
pageid = (phyaddr-shmbegin) >> PAGE_SHIFT;
if (page_owner[pageid] != RCCE_IAM) {
remote_rank = page_owner[pageid];
if (remote_rank != 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", RCCE_IAM, phyaddr);
remote_rank = page_owner[pageid];
((size_t*) payload)[0] = ue;
((size_t*) payload)[1] = phyaddr;
@ -285,13 +301,19 @@ int svm_emit_page(size_t phyaddr, int ue)
size_t viraddr;
svm_flush();
page_owner[pageid] = ue;
// send response back to ue
// ue is polling for the response => no irq is needed
iRCCE_mail_send(0, SVM_RESP, 0, NULL, ue);
emit[ue]++;
viraddr = phys2virt[(phyaddr - shmbegin) >> PAGE_SHIFT];
viraddr = phys2virt[pageid];
page_owner[pageid] = ue;
change_page_permissions(viraddr, viraddr+PAGE_SIZE, VMA_NOACCESS|VMA_READ|VMA_CACHEABLE);
}
emit_ticks += rdtsc() - start;
return 0;
}
@ -333,6 +355,11 @@ int svm_statistics(void)
for(i=0; i<RCCE_MAXNP; i++)
kprintf("\t%u", forward[i]);
kputs("\n");
kprintf("request ticks: %llu\n", request_ticks);
kprintf("wait ticks: %llu\n", wait_ticks);
kprintf("emit ticks: %llu\n", emit_ticks);
kprintf("max wait: %llu\n", max_wait);
kprintf("min wait: %llu\n", min_wait);
return 0;
}