1/** 2 * \file 3 * \brief Test program for large page code 4 */ 5 6/* 7 * Copyright (c) 2013, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <barrelfish/barrelfish.h> 16#include <stdio.h> 17#include <stdlib.h> 18#include <string.h> 19#include <assert.h> 20#include <inttypes.h> 21#include <barrelfish/nameservice_client.h> 22#include <barrelfish/sys_debug.h> 23#include <bench/bench.h> 24 25#define SAFE_VADDR (genvaddr_t)(8ULL<<39) 26#define SAFE_PMAP_ADDR (genvaddr_t)(9ULL<<39) 27//0b 0000 0000 0000 0000 0000 0100 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 28#define SAFE_PMAP_ADDR_L ((genvaddr_t) (12ULL<<39)) 29// 40M 30#define DEFAULT_SIZE 30*X86_64_LARGE_PAGE_SIZE 31 32#define LARGE_PAGE_SIZE X86_64_LARGE_PAGE_SIZE 33 34#define RUN_COUNT 50 35 36unsigned long mean4k; 37unsigned long mean2m; 38unsigned long min4k; 39unsigned long min2m; 40unsigned long mean4krand; 41unsigned long mean2mrand; 42unsigned long min4krand; 43unsigned long min2mrand; 44unsigned long max4krand; 45unsigned long max2mrand; 46unsigned long max4k; 47unsigned long max2m; 48 49unsigned long mean4kshort; 50unsigned long mean2mshort; 51unsigned long mean4kshortrand; 52unsigned long mean2mshortrand; 53unsigned long min4kshort; 54unsigned long min2mshort; 55unsigned long min4kshortrand; 56unsigned long min2mshortrand; 57unsigned long max4kshort; 58unsigned long max2mshort; 59unsigned long max4kshortrand; 60unsigned long max2mshortrand; 61/*static paging_x86_64_flags_t PAGE_DEFAULT_ACCESS = 62 PTABLE_USER_SUPERVISOR | 63 PTABLE_EXECUTE_DISABLE | 64 PTABLE_READ_WRITE; 65 */ 66static vregion_flags_t PMAP_DEFAULT_ACCESS = 67 VREGION_FLAGS_READ_WRITE; 68 69static void test_region(uint32_t *buf, size_t size, bool large, bool area) 70{ 71 cycles_t runs[RUN_COUNT]; 72 cycles_t start, end; 73 uint64_t mean = 0; 74 unsigned long min = 0; 75 unsigned long max = 0; 76 printf("base address: %lx\n", (uint64_t) buf); 77 78 //sequential access 79 for (int j = 0; j < RUN_COUNT; j++) { 80 81 start = bench_tsc()/1000; 82 for (unsigned long i = 0; i < size; i+=4) { 83 84 buf[i/4] = i; 85 } 86 for (unsigned long i = 0; i < size; i+=4) { 87 assert(buf[i/4] == i); 88 } 89 end = bench_tsc()/1000; 90 runs[j] = end-start; 91 mean += (unsigned int) runs[j]; 92 if (runs[j] < min || j == 0) {min = runs[j];} 93 if (runs[j] > max) {max = runs[j];} 94 printf("run: %u, cycles: %u\n", j, (unsigned int) runs[j]); 95 } 96 mean = mean/RUN_COUNT; 97 printf("\naverage cycles to write the whole area: %u\n", (unsigned int) mean); 98 if(!large && !area) { 99 mean4k = mean; 100 min4k = min; 101 max4k = max; 102 } 103 else if (large && !area) { 104 mean2m = mean; 105 min2m = min; 106 max2m = max; 107 } 108 else if (!large && area) { 109 mean4kshort = mean; 110 min4kshort = min; 111 max4kshort = max; 112 } else { 113 mean2mshort = mean; 114 min2mshort = min; 115 max2mshort = max; 116 } 117 118 //random access 119 //generate 1M random number array 120 unsigned int* addrs; 121 min = 0; 122 max = 0; 123 mean = 0; 124 addrs = malloc(2000000*sizeof(unsigned int)); 125 printf("malloc'd\n"); 126 for (int i = 0; i<2000000; i++) 127 { 128 addrs[i] = (rand() % (size/4)); 129 } 130 printf("randomised\n"); 131 for (int j = 0; j < RUN_COUNT; j++) { 132 133 start = bench_tsc()/1000; 134 for (int i = 0; i < 2000000; i++) { 135 buf[addrs[i]] = addrs[i]; 136 } 137 for (unsigned long i = 0; i < 2000000; i++) { 138 assert(buf[addrs[i]] == addrs[i]); 139 } 140 end = bench_tsc()/1000; 141 runs[j] = end-start; 142 mean += (unsigned int) runs[j]; 143 if (runs[j] < min || j == 0) {min = runs[j];} 144 if (runs[j] > max) {max = runs[j];} 145 printf("run: %u, cycles: %u\n", j, (unsigned int) runs[j]); 146 } 147 mean = mean/RUN_COUNT; 148 printf("\naverage cycles to write the whole area randomly: %u\n", (unsigned int) mean); 149 if(!large && !area) { 150 mean4krand = mean; 151 min4krand = min; 152 max4krand = max; 153 } 154 else if (large && !area){ 155 mean2mrand = mean; 156 min2mrand = min; 157 max2mrand = max; 158 }else if (!large && area) { 159 mean4kshortrand = mean; 160 min4kshortrand = min; 161 max4kshortrand = max; 162 } else { 163 mean2mshortrand = mean; 164 min2mshortrand = min; 165 max2mshortrand = max; 166 } 167 168} 169 170int main(void) 171{ 172 struct capref frame; 173 size_t bytes = DEFAULT_SIZE; 174 errval_t err; 175 mean4k = 0; 176 mean2m = 0; 177 genvaddr_t address; 178 179 180 //normal pages via pmap interface 181 printf("\nstart 4k map with pmap\n"); 182 err = frame_alloc(&frame, bytes, &bytes); 183 if (err_is_fail(err)) 184 { 185 printf("error in frame_alloc: %s\n", err_getstring(err)); 186 exit(1); 187 } 188 assert(bytes >= DEFAULT_SIZE); 189 printf(" get pmap\n"); 190 struct pmap *pmap = get_current_pmap(); 191 192 printf(" obtain address\n"); 193 err = pmap->f.determine_addr_raw(pmap, bytes, X86_64_BASE_PAGE_SIZE, &address); 194 if (err_is_fail(err)) 195 { 196 printf("error in determine_addr_raw: %s\n", err_getstring(err)); 197 exit(1); 198 } 199 200 printf(" map\n"); 201 err = pmap->f.map(pmap, address, frame, 0, bytes, PMAP_DEFAULT_ACCESS, NULL, &bytes); 202 if (err_is_fail(err)) 203 { 204 printf("error in pmap: %s\n", err_getstring(err)); 205 exit(1); 206 } 207 printf("addr: %lx\n", address); 208 test_region((uint32_t*)address, DEFAULT_SIZE, false, false); 209 210 printf("\tunmap\n"); 211 err = pmap->f.unmap(pmap, address, bytes, NULL); 212 if (err_is_fail(err)) 213 { 214 printf("error in unmap: %s\n", err_getstring(err)); 215 exit(1); 216 } 217 218 //large page via pmap interface 219 printf("start 2m map with pmap\n"); 220 bytes = DEFAULT_SIZE; 221 struct capref frame2; 222 err = frame_alloc(&frame2, bytes, &bytes); 223 if (err_is_fail(err)) 224 { 225 printf("error in frame_alloc: %s\n", err_getstring(err)); 226 exit(1); 227 } 228 assert(bytes >= DEFAULT_SIZE); 229 pmap = get_current_pmap(); 230 231 printf("determine address\n"); 232 err = pmap->f.determine_addr_raw(pmap, bytes, X86_64_LARGE_PAGE_SIZE, &address); 233 if (err_is_fail(err)) 234 { 235 printf("error in determine_addr_raw: %s\n", err_getstring(err)); 236 exit(1); 237 } 238 239 printf("map\n"); 240 err = pmap->f.map(pmap, address, frame, 0, bytes, PMAP_DEFAULT_ACCESS | 0x0100, NULL, &bytes); 241 if (err_is_fail(err)) 242 { 243 printf("error in pmap: %s\n", err_getstring(err)); 244 exit(1); 245 } 246 printf("addr: %lx\n", address); 247 test_region((uint32_t*)address, DEFAULT_SIZE, true, false); 248 249 err = pmap->f.unmap(pmap, address, bytes, NULL); 250 if (err_is_fail(err)) 251 { 252 printf("error in unmap: %s\n", err_getstring(err)); 253 exit(1); 254 } 255 //small area 4k 256 bytes = LARGE_PAGE_SIZE; 257 err = frame_alloc(&frame, bytes, &bytes); 258 if (err_is_fail(err)) 259 { 260 printf("error in frame_alloc: %s\n", err_getstring(err)); 261 exit(1); 262 } 263 assert(bytes >= LARGE_PAGE_SIZE); 264 pmap = get_current_pmap(); 265 err = pmap->f.map(pmap, SAFE_PMAP_ADDR, frame, 0, bytes, PMAP_DEFAULT_ACCESS, NULL, &bytes); 266 if (err_is_fail(err)) 267 { 268 printf("error in pmap small 4k\n"); 269 exit(1); 270 } 271 test_region((uint32_t*) SAFE_PMAP_ADDR, LARGE_PAGE_SIZE, false, true); 272 273 //small area 2m 274 bytes = LARGE_PAGE_SIZE; 275 err = frame_alloc(&frame, bytes, &bytes); 276 if (err_is_fail(err)) 277 { 278 printf("error in frame_alloc: %s\n", err_getstring(err)); 279 exit(1); 280 } 281 assert(bytes >= LARGE_PAGE_SIZE); 282 pmap = get_current_pmap(); 283 284 printf("map\n"); 285 err = pmap->f.map(pmap, SAFE_PMAP_ADDR_L, frame, 0, bytes, PMAP_DEFAULT_ACCESS | 0x0100, NULL, &bytes); 286 if (err_is_fail(err)) 287 { 288 printf("error in pmap: %s\n", err_getstring(err)); 289 exit(1); 290 } 291 printf("addr: %lx\n", SAFE_PMAP_ADDR_L); 292 test_region((uint32_t*)SAFE_PMAP_ADDR_L, LARGE_PAGE_SIZE, true, true); 293 294 295 296 printf("large area\n"); 297 printf("average 4k: %lu, average 2m: %lu\n", mean4k, mean2m); 298 printf("minimal 4k: %lu, minimal 2m: %lu\n", min4k, min2m); 299 printf("maximal 4k: %lu, maximal 2m: %lu\n", max4k, max2m); 300 printf("random: average 4k: %lu, average 2m: %lu\n", mean4krand, mean2mrand); 301 printf("random:minimal 4k: %lu, minimal 2m: %lu\n", min4krand, min2mrand); 302 printf("random:maximal 4k: %lu, maximal 2m: %lu\n\n", max4krand, max2mrand); 303 printf("short area\n"); 304 printf("average 4k: %lu, average 2m: %lu\n", mean4kshort, mean2mshort); 305 printf("minimal 4k: %lu, minimal 2m: %lu\n", min4kshort, min2mshort); 306 printf("maximal 4k: %lu, maximal 2m: %lu\n", max4kshort, max2mshort); 307 printf("random: average 4k: %lu, average 2m: %lu\n", mean4kshortrand, mean2mshortrand); 308 printf("random:minimal 4k: %lu, minimal 2m: %lu\n", min4kshortrand, min2mshortrand); 309 printf("random:maximal 4k: %lu, maximal 2m: %lu\n", max4kshortrand, max2mshortrand); 310 printf("exited successfully\n"); 311 return 0; 312} 313