1 1.3 andvar /* $NetBSD: t_uvm_physseg_load.c,v 1.3 2022/07/26 19:49:32 andvar Exp $ */ 2 1.1 cherry 3 1.1 cherry /*- 4 1.1 cherry * Copyright (c) 2015, 2016 The NetBSD Foundation, Inc. 5 1.1 cherry * All rights reserved. 6 1.1 cherry * 7 1.1 cherry * This code is derived from software contributed to The NetBSD Foundation 8 1.1 cherry * by Santhosh N. Raju <santhosh.raju (at) gmail.com> and 9 1.1 cherry * by Cherry G. Mathew 10 1.1 cherry * 11 1.1 cherry * Redistribution and use in source and binary forms, with or without 12 1.1 cherry * modification, are permitted provided that the following conditions 13 1.1 cherry * are met: 14 1.1 cherry * 1. Redistributions of source code must retain the above copyright 15 1.1 cherry * notice, this list of conditions and the following disclaimer. 16 1.1 cherry * 2. Redistributions in binary form must reproduce the above copyright 17 1.1 cherry * notice, this list of conditions and the following disclaimer in the 18 1.1 cherry * documentation and/or other materials provided with the distribution. 19 1.1 cherry * 20 1.1 cherry * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.1 cherry * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.1 cherry * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.1 cherry * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.1 cherry * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.1 cherry * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.1 cherry * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.1 cherry * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.1 cherry * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.1 cherry * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.1 cherry * POSSIBILITY OF SUCH DAMAGE. 31 1.1 cherry */ 32 1.1 cherry 33 1.1 cherry #include <sys/cdefs.h> 34 1.3 andvar __RCSID("$NetBSD: t_uvm_physseg_load.c,v 1.3 2022/07/26 19:49:32 andvar Exp $"); 35 1.2 cherry 36 1.2 cherry /* 37 1.2 cherry * If this line is commented out tests related touvm_physseg_get_pmseg() 38 1.2 cherry * wont run. 39 1.2 cherry * 40 1.2 cherry * Have a look at machine/uvm_physseg.h for more details. 41 1.2 cherry */ 42 1.2 cherry #define __HAVE_PMAP_PHYSSEG 43 1.2 cherry 44 1.2 cherry /* 45 1.2 cherry * This is a dummy struct used for testing purposes 46 1.2 cherry * 47 1.2 cherry * In reality this struct would exist in the MD part of the code residing in 48 1.2 cherry * machines/vmparam.h 49 1.2 cherry */ 50 1.2 cherry 51 1.2 cherry #ifdef __HAVE_PMAP_PHYSSEG 52 1.2 cherry struct pmap_physseg { 53 1.2 cherry int dummy_variable; /* Dummy variable use for testing */ 54 1.2 cherry }; 55 1.2 cherry #endif 56 1.1 cherry 57 1.1 cherry /* Testing API - assumes userland */ 58 1.1 cherry /* Provide Kernel API equivalents */ 59 1.1 cherry #include <assert.h> 60 1.1 cherry #include <stdbool.h> 61 1.1 cherry #include <string.h> /* memset(3) et. al */ 62 1.1 cherry #include <stdio.h> /* printf(3) */ 63 1.1 cherry #include <stdlib.h> /* malloc(3) */ 64 1.1 cherry #include <stdarg.h> 65 1.1 cherry #include <stddef.h> 66 1.1 cherry #include <time.h> 67 1.1 cherry 68 1.1 cherry #define PRIxPADDR "lx" 69 1.1 cherry #define PRIxPSIZE "lx" 70 1.1 cherry #define PRIuPSIZE "lu" 71 1.1 cherry #define PRIxVADDR "lx" 72 1.1 cherry #define PRIxVSIZE "lx" 73 1.1 cherry #define PRIuVSIZE "lu" 74 1.1 cherry 75 1.1 cherry #define UVM_HOTPLUG /* Enable hotplug with rbtree. */ 76 1.1 cherry #define PMAP_STEAL_MEMORY 77 1.1 cherry #define DEBUG /* Enable debug functionality. */ 78 1.1 cherry 79 1.1 cherry typedef unsigned long vaddr_t; 80 1.1 cherry typedef unsigned long paddr_t; 81 1.1 cherry typedef unsigned long psize_t; 82 1.1 cherry typedef unsigned long vsize_t; 83 1.1 cherry 84 1.2 cherry #include <uvm/uvm_physseg.h> 85 1.1 cherry #include <uvm/uvm_page.h> 86 1.1 cherry 87 1.1 cherry #ifndef DIAGNOSTIC 88 1.1 cherry #define KASSERTMSG(e, msg, ...) /* NOTHING */ 89 1.1 cherry #define KASSERT(e) /* NOTHING */ 90 1.1 cherry #else 91 1.1 cherry #define KASSERT(a) assert(a) 92 1.1 cherry #define KASSERTMSG(exp, ...) printf(__VA_ARGS__); assert((exp)) 93 1.1 cherry #endif 94 1.1 cherry 95 1.1 cherry #define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH 96 1.1 cherry 97 1.1 cherry #define VM_NFREELIST 4 98 1.1 cherry #define VM_FREELIST_DEFAULT 0 99 1.1 cherry #define VM_FREELIST_FIRST16 3 100 1.1 cherry #define VM_FREELIST_FIRST1G 2 101 1.1 cherry #define VM_FREELIST_FIRST4G 1 102 1.1 cherry 103 1.1 cherry /* 104 1.1 cherry * Used in tests when Array implementation is tested 105 1.1 cherry */ 106 1.1 cherry #if !defined(VM_PHYSSEG_MAX) 107 1.1 cherry #define VM_PHYSSEG_MAX 32 108 1.1 cherry #endif 109 1.1 cherry 110 1.1 cherry #define PAGE_SIZE 4096 111 1.1 cherry #define PAGE_SHIFT 12 112 1.1 cherry #define atop(x) (((paddr_t)(x)) >> PAGE_SHIFT) 113 1.1 cherry 114 1.1 cherry #define mutex_enter(l) 115 1.1 cherry #define mutex_exit(l) 116 1.1 cherry 117 1.1 cherry #define _SYS_KMEM_H_ /* Disallow the real kmem API (see below) */ 118 1.1 cherry /* free(p) XXX: pgs management need more thought */ 119 1.1 cherry #define kmem_alloc(size, flags) malloc(size) 120 1.1 cherry #define kmem_zalloc(size, flags) malloc(size) 121 1.1 cherry #define kmem_free(p, size) free(p) 122 1.1 cherry 123 1.1 cherry psize_t physmem; 124 1.1 cherry 125 1.1 cherry struct uvmexp uvmexp; /* decl */ 126 1.1 cherry 127 1.1 cherry /* 128 1.1 cherry * uvm structure borrowed from uvm.h 129 1.1 cherry * 130 1.1 cherry * Remember this is a dummy structure used within the ATF Tests and 131 1.1 cherry * uses only necessary fields from the original uvm struct. 132 1.1 cherry * See uvm/uvm.h for the full struct. 133 1.1 cherry */ 134 1.1 cherry 135 1.1 cherry struct uvm { 136 1.1 cherry /* vm_page related parameters */ 137 1.1 cherry 138 1.1 cherry bool page_init_done; /* TRUE if uvm_page_init() finished */ 139 1.1 cherry } uvm; 140 1.1 cherry 141 1.1 cherry static void 142 1.1 cherry panic(const char *fmt, ...) 143 1.1 cherry { 144 1.1 cherry va_list ap; 145 1.1 cherry 146 1.1 cherry va_start(ap, fmt); 147 1.1 cherry vprintf(fmt, ap); 148 1.1 cherry printf("\n"); 149 1.1 cherry va_end(ap); 150 1.1 cherry KASSERT(false); 151 1.1 cherry 152 1.1 cherry /*NOTREACHED*/ 153 1.1 cherry } 154 1.1 cherry 155 1.1 cherry static void 156 1.1 cherry uvm_pagefree(struct vm_page *pg) 157 1.1 cherry { 158 1.1 cherry return; 159 1.1 cherry } 160 1.1 cherry 161 1.1 cherry #if defined(UVM_HOTPLUG) 162 1.1 cherry static void 163 1.1 cherry uvmpdpol_reinit(void) 164 1.1 cherry { 165 1.1 cherry return; 166 1.1 cherry } 167 1.1 cherry #endif /* UVM_HOTPLUG */ 168 1.1 cherry 169 1.1 cherry /* end - Provide Kernel API equivalents */ 170 1.1 cherry 171 1.1 cherry #include "uvm/uvm_physseg.c" 172 1.1 cherry 173 1.1 cherry #include <atf-c.h> 174 1.1 cherry 175 1.1 cherry #define ONE_MEGABYTE 1024 * 1024 176 1.1 cherry 177 1.1 cherry /* Sample Page Frame Numbers */ 178 1.1 cherry #define VALID_START_PFN_1 atop(0) 179 1.1 cherry #define VALID_END_PFN_1 atop(ONE_MEGABYTE) 180 1.1 cherry #define VALID_AVAIL_START_PFN_1 atop(0) 181 1.1 cherry #define VALID_AVAIL_END_PFN_1 atop(ONE_MEGABYTE) 182 1.1 cherry 183 1.1 cherry #define VALID_START_PFN_2 atop(ONE_MEGABYTE + 1) 184 1.1 cherry #define VALID_END_PFN_2 atop(ONE_MEGABYTE * 2) 185 1.1 cherry #define VALID_AVAIL_START_PFN_2 atop(ONE_MEGABYTE + 1) 186 1.1 cherry #define VALID_AVAIL_END_PFN_2 atop(ONE_MEGABYTE * 2) 187 1.1 cherry 188 1.1 cherry #define VALID_START_PFN_3 atop((ONE_MEGABYTE * 2) + 1) 189 1.1 cherry #define VALID_END_PFN_3 atop(ONE_MEGABYTE * 3) 190 1.1 cherry #define VALID_AVAIL_START_PFN_3 atop((ONE_MEGABYTE * 2) + 1) 191 1.1 cherry #define VALID_AVAIL_END_PFN_3 atop(ONE_MEGABYTE * 3) 192 1.1 cherry 193 1.1 cherry #define VALID_START_PFN_4 atop(ONE_MEGABYTE + 1) 194 1.1 cherry #define VALID_END_PFN_4 atop(ONE_MEGABYTE * 128) 195 1.1 cherry #define VALID_AVAIL_START_PFN_4 atop(ONE_MEGABYTE + 1) 196 1.1 cherry #define VALID_AVAIL_END_PFN_4 atop(ONE_MEGABYTE * 128) 197 1.1 cherry 198 1.1 cherry #define VALID_START_PFN_5 atop(ONE_MEGABYTE + 1) 199 1.1 cherry #define VALID_END_PFN_5 atop(ONE_MEGABYTE * 256) 200 1.1 cherry #define VALID_AVAIL_START_PFN_5 atop(ONE_MEGABYTE + 1) 201 1.1 cherry #define VALID_AVAIL_END_PFN_5 atop(ONE_MEGABYTE * 256) 202 1.1 cherry 203 1.1 cherry /* 204 1.1 cherry * Total number of pages (of 4K size each) should be 256 for 1MB of memory. 205 1.1 cherry */ 206 1.1 cherry #define PAGE_COUNT_1M 256 207 1.1 cherry 208 1.1 cherry /* 209 1.1 cherry * The number of Page Frames to allot per segment 210 1.1 cherry */ 211 1.1 cherry #define PF_STEP 8 212 1.1 cherry 213 1.1 cherry /* 214 1.3 andvar * A debug function to print the content of upm. 215 1.1 cherry */ 216 1.1 cherry static inline void 217 1.1 cherry uvm_physseg_dump_seg(uvm_physseg_t upm) 218 1.1 cherry { 219 1.1 cherry #if defined(DEBUG) 220 1.1 cherry printf("%s: seg->start == %ld\n", __func__, 221 1.1 cherry uvm_physseg_get_start(upm)); 222 1.1 cherry printf("%s: seg->end == %ld\n", __func__, 223 1.1 cherry uvm_physseg_get_end(upm)); 224 1.1 cherry printf("%s: seg->avail_start == %ld\n", __func__, 225 1.1 cherry uvm_physseg_get_avail_start(upm)); 226 1.1 cherry printf("%s: seg->avail_end == %ld\n", __func__, 227 1.1 cherry uvm_physseg_get_avail_end(upm)); 228 1.1 cherry 229 1.1 cherry printf("====\n\n"); 230 1.1 cherry #else 231 1.1 cherry return; 232 1.1 cherry #endif /* DEBUG */ 233 1.1 cherry } 234 1.1 cherry 235 1.1 cherry /* 236 1.1 cherry * Private accessor that gets the value of vm_physmem.nentries 237 1.1 cherry */ 238 1.1 cherry static int 239 1.1 cherry uvm_physseg_get_entries(void) 240 1.1 cherry { 241 1.1 cherry #if defined(UVM_HOTPLUG) 242 1.1 cherry return uvm_physseg_graph.nentries; 243 1.1 cherry #else 244 1.1 cherry return vm_nphysmem; 245 1.1 cherry #endif /* UVM_HOTPLUG */ 246 1.1 cherry } 247 1.1 cherry 248 1.1 cherry /* 249 1.1 cherry * Note: This function replicates verbatim what happens in 250 1.1 cherry * uvm_page.c:uvm_page_init(). 251 1.1 cherry * 252 1.1 cherry * Please track any changes that happen there. 253 1.1 cherry */ 254 1.1 cherry static void 255 1.1 cherry uvm_page_init_fake(struct vm_page *pagearray, psize_t pagecount) 256 1.1 cherry { 257 1.1 cherry uvm_physseg_t bank; 258 1.1 cherry size_t n; 259 1.1 cherry 260 1.1 cherry for (bank = uvm_physseg_get_first(), 261 1.1 cherry uvm_physseg_seg_chomp_slab(bank, pagearray, pagecount); 262 1.2 cherry uvm_physseg_valid_p(bank); 263 1.1 cherry bank = uvm_physseg_get_next(bank)) { 264 1.1 cherry 265 1.1 cherry n = uvm_physseg_get_end(bank) - uvm_physseg_get_start(bank); 266 1.1 cherry uvm_physseg_seg_alloc_from_slab(bank, n); 267 1.1 cherry uvm_physseg_init_seg(bank, pagearray); 268 1.1 cherry 269 1.1 cherry /* set up page array pointers */ 270 1.1 cherry pagearray += n; 271 1.1 cherry pagecount -= n; 272 1.1 cherry } 273 1.1 cherry 274 1.1 cherry uvm.page_init_done = true; 275 1.1 cherry } 276 1.1 cherry 277 1.1 cherry /* 278 1.1 cherry * PHYS_TO_VM_PAGE: find vm_page for a PA. used by MI code to get vm_pages 279 1.1 cherry * back from an I/O mapping (ugh!). used in some MD code as well. 280 1.1 cherry */ 281 1.1 cherry static struct vm_page * 282 1.1 cherry uvm_phys_to_vm_page(paddr_t pa) 283 1.1 cherry { 284 1.1 cherry paddr_t pf = atop(pa); 285 1.1 cherry paddr_t off; 286 1.1 cherry uvm_physseg_t psi; 287 1.1 cherry 288 1.1 cherry psi = uvm_physseg_find(pf, &off); 289 1.1 cherry if (psi != UVM_PHYSSEG_TYPE_INVALID) 290 1.1 cherry return uvm_physseg_get_pg(psi, off); 291 1.1 cherry return(NULL); 292 1.1 cherry } 293 1.1 cherry 294 1.1 cherry //static paddr_t 295 1.1 cherry //uvm_vm_page_to_phys(const struct vm_page *pg) 296 1.1 cherry //{ 297 1.1 cherry // 298 1.1 cherry // return pg->phys_addr; 299 1.1 cherry //} 300 1.1 cherry 301 1.1 cherry /* 302 1.1 cherry * XXX: To do, write control test cases for uvm_vm_page_to_phys(). 303 1.1 cherry */ 304 1.1 cherry 305 1.1 cherry /* #define VM_PAGE_TO_PHYS(entry) uvm_vm_page_to_phys(entry) */ 306 1.1 cherry 307 1.1 cherry #define PHYS_TO_VM_PAGE(pa) uvm_phys_to_vm_page(pa) 308 1.1 cherry 309 1.1 cherry /* 310 1.1 cherry * Test Fixture SetUp(). 311 1.1 cherry */ 312 1.1 cherry static void 313 1.1 cherry setup(void) 314 1.1 cherry { 315 1.1 cherry /* Prerequisites for running certain calls in uvm_physseg */ 316 1.1 cherry uvmexp.pagesize = PAGE_SIZE; 317 1.1 cherry uvmexp.npages = 0; 318 1.1 cherry uvm.page_init_done = false; 319 1.1 cherry uvm_physseg_init(); 320 1.1 cherry } 321 1.1 cherry 322 1.1 cherry ATF_TC(uvm_physseg_100); 323 1.1 cherry ATF_TC_HEAD(uvm_physseg_100, tc) 324 1.1 cherry { 325 1.1 cherry atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 326 1.1 cherry 100 calls, VM_PHYSSEG_MAX is 32."); 327 1.1 cherry } 328 1.1 cherry ATF_TC_BODY(uvm_physseg_100, tc) 329 1.1 cherry { 330 1.1 cherry paddr_t pa; 331 1.1 cherry 332 1.1 cherry setup(); 333 1.1 cherry 334 1.1 cherry for(paddr_t i = VALID_START_PFN_1; 335 1.1 cherry i < VALID_END_PFN_1; i += PF_STEP) { 336 1.1 cherry uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 337 1.1 cherry VM_FREELIST_DEFAULT); 338 1.1 cherry } 339 1.1 cherry 340 1.1 cherry ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 341 1.1 cherry 342 1.1 cherry srandom((unsigned)time(NULL)); 343 1.1 cherry for(int i = 0; i < 100; i++) { 344 1.1 cherry pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 345 1.1 cherry PHYS_TO_VM_PAGE(pa); 346 1.1 cherry } 347 1.1 cherry 348 1.1 cherry ATF_CHECK_EQ(true, true); 349 1.1 cherry } 350 1.1 cherry 351 1.1 cherry ATF_TC(uvm_physseg_1K); 352 1.1 cherry ATF_TC_HEAD(uvm_physseg_1K, tc) 353 1.1 cherry { 354 1.1 cherry atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 355 1.1 cherry 1000 calls, VM_PHYSSEG_MAX is 32."); 356 1.1 cherry } 357 1.1 cherry ATF_TC_BODY(uvm_physseg_1K, tc) 358 1.1 cherry { 359 1.1 cherry paddr_t pa; 360 1.1 cherry 361 1.1 cherry setup(); 362 1.1 cherry 363 1.1 cherry for(paddr_t i = VALID_START_PFN_1; 364 1.1 cherry i < VALID_END_PFN_1; i += PF_STEP) { 365 1.1 cherry uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 366 1.1 cherry VM_FREELIST_DEFAULT); 367 1.1 cherry } 368 1.1 cherry 369 1.1 cherry ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 370 1.1 cherry 371 1.1 cherry srandom((unsigned)time(NULL)); 372 1.1 cherry for(int i = 0; i < 1000; i++) { 373 1.1 cherry pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 374 1.1 cherry PHYS_TO_VM_PAGE(pa); 375 1.1 cherry } 376 1.1 cherry 377 1.1 cherry ATF_CHECK_EQ(true, true); 378 1.1 cherry } 379 1.1 cherry 380 1.1 cherry ATF_TC(uvm_physseg_10K); 381 1.1 cherry ATF_TC_HEAD(uvm_physseg_10K, tc) 382 1.1 cherry { 383 1.1 cherry atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 384 1.1 cherry 10,000 calls, VM_PHYSSEG_MAX is 32."); 385 1.1 cherry } 386 1.1 cherry ATF_TC_BODY(uvm_physseg_10K, tc) 387 1.1 cherry { 388 1.1 cherry paddr_t pa; 389 1.1 cherry 390 1.1 cherry setup(); 391 1.1 cherry 392 1.1 cherry for(paddr_t i = VALID_START_PFN_1; 393 1.1 cherry i < VALID_END_PFN_1; i += PF_STEP) { 394 1.1 cherry uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 395 1.1 cherry VM_FREELIST_DEFAULT); 396 1.1 cherry } 397 1.1 cherry 398 1.1 cherry ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 399 1.1 cherry 400 1.1 cherry srandom((unsigned)time(NULL)); 401 1.1 cherry for(int i = 0; i < 10000; i++) { 402 1.1 cherry pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 403 1.1 cherry PHYS_TO_VM_PAGE(pa); 404 1.1 cherry } 405 1.1 cherry 406 1.1 cherry ATF_CHECK_EQ(true, true); 407 1.1 cherry } 408 1.1 cherry 409 1.1 cherry ATF_TC(uvm_physseg_100K); 410 1.1 cherry ATF_TC_HEAD(uvm_physseg_100K, tc) 411 1.1 cherry { 412 1.1 cherry atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 413 1.1 cherry 100,000 calls, VM_PHYSSEG_MAX is 32."); 414 1.1 cherry } 415 1.1 cherry ATF_TC_BODY(uvm_physseg_100K, tc) 416 1.1 cherry { 417 1.1 cherry paddr_t pa; 418 1.1 cherry 419 1.1 cherry setup(); 420 1.1 cherry 421 1.1 cherry for(paddr_t i = VALID_START_PFN_1; 422 1.1 cherry i < VALID_END_PFN_1; i += PF_STEP) { 423 1.1 cherry uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 424 1.1 cherry VM_FREELIST_DEFAULT); 425 1.1 cherry } 426 1.1 cherry 427 1.1 cherry ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 428 1.1 cherry 429 1.1 cherry srandom((unsigned)time(NULL)); 430 1.1 cherry for(int i = 0; i < 100000; i++) { 431 1.1 cherry pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 432 1.1 cherry PHYS_TO_VM_PAGE(pa); 433 1.1 cherry } 434 1.1 cherry 435 1.1 cherry ATF_CHECK_EQ(true, true); 436 1.1 cherry } 437 1.1 cherry 438 1.1 cherry ATF_TC(uvm_physseg_1M); 439 1.1 cherry ATF_TC_HEAD(uvm_physseg_1M, tc) 440 1.1 cherry { 441 1.1 cherry atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 442 1.1 cherry 1,000,000 calls, VM_PHYSSEG_MAX is 32."); 443 1.1 cherry } 444 1.1 cherry ATF_TC_BODY(uvm_physseg_1M, tc) 445 1.1 cherry { 446 1.1 cherry paddr_t pa; 447 1.1 cherry 448 1.1 cherry setup(); 449 1.1 cherry 450 1.1 cherry for(paddr_t i = VALID_START_PFN_1; 451 1.1 cherry i < VALID_END_PFN_1; i += PF_STEP) { 452 1.1 cherry uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 453 1.1 cherry VM_FREELIST_DEFAULT); 454 1.1 cherry } 455 1.1 cherry 456 1.1 cherry ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 457 1.1 cherry 458 1.1 cherry srandom((unsigned)time(NULL)); 459 1.1 cherry for(int i = 0; i < 1000000; i++) { 460 1.1 cherry pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 461 1.1 cherry PHYS_TO_VM_PAGE(pa); 462 1.1 cherry } 463 1.1 cherry 464 1.1 cherry ATF_CHECK_EQ(true, true); 465 1.1 cherry } 466 1.1 cherry 467 1.1 cherry ATF_TC(uvm_physseg_10M); 468 1.1 cherry ATF_TC_HEAD(uvm_physseg_10M, tc) 469 1.1 cherry { 470 1.1 cherry atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 471 1.1 cherry 10,000,000 calls, VM_PHYSSEG_MAX is 32."); 472 1.1 cherry } 473 1.1 cherry ATF_TC_BODY(uvm_physseg_10M, tc) 474 1.1 cherry { 475 1.1 cherry paddr_t pa; 476 1.1 cherry 477 1.1 cherry setup(); 478 1.1 cherry 479 1.1 cherry for(paddr_t i = VALID_START_PFN_1; 480 1.1 cherry i < VALID_END_PFN_1; i += PF_STEP) { 481 1.1 cherry uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 482 1.1 cherry VM_FREELIST_DEFAULT); 483 1.1 cherry } 484 1.1 cherry 485 1.1 cherry ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 486 1.1 cherry 487 1.1 cherry srandom((unsigned)time(NULL)); 488 1.1 cherry for(int i = 0; i < 10000000; i++) { 489 1.1 cherry pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 490 1.1 cherry PHYS_TO_VM_PAGE(pa); 491 1.1 cherry } 492 1.1 cherry 493 1.1 cherry ATF_CHECK_EQ(true, true); 494 1.1 cherry } 495 1.1 cherry 496 1.1 cherry ATF_TC(uvm_physseg_100M); 497 1.1 cherry ATF_TC_HEAD(uvm_physseg_100M, tc) 498 1.1 cherry { 499 1.1 cherry atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 500 1.1 cherry 100,000,000 calls, VM_PHYSSEG_MAX is 32."); 501 1.1 cherry } 502 1.1 cherry ATF_TC_BODY(uvm_physseg_100M, tc) 503 1.1 cherry { 504 1.1 cherry paddr_t pa; 505 1.1 cherry 506 1.1 cherry setup(); 507 1.1 cherry 508 1.1 cherry for(paddr_t i = VALID_START_PFN_1; 509 1.1 cherry i < VALID_END_PFN_1; i += PF_STEP) { 510 1.1 cherry uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 511 1.1 cherry VM_FREELIST_DEFAULT); 512 1.1 cherry } 513 1.1 cherry 514 1.1 cherry ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 515 1.1 cherry 516 1.1 cherry srandom((unsigned)time(NULL)); 517 1.1 cherry for(int i = 0; i < 100000000; i++) { 518 1.1 cherry pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 519 1.1 cherry PHYS_TO_VM_PAGE(pa); 520 1.1 cherry } 521 1.1 cherry 522 1.1 cherry ATF_CHECK_EQ(true, true); 523 1.1 cherry } 524 1.1 cherry 525 1.1 cherry ATF_TC(uvm_physseg_1MB); 526 1.1 cherry ATF_TC_HEAD(uvm_physseg_1MB, tc) 527 1.1 cherry { 528 1.1 cherry atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 529 1.1 cherry 10,000,000 calls, VM_PHYSSEG_MAX is 32 on 1 MB Segment."); 530 1.1 cherry } 531 1.1 cherry ATF_TC_BODY(uvm_physseg_1MB, t) 532 1.1 cherry { 533 1.1 cherry paddr_t pa = 0; 534 1.1 cherry 535 1.1 cherry paddr_t pf = 0; 536 1.1 cherry 537 1.1 cherry psize_t pf_chunk_size = 0; 538 1.1 cherry 539 1.1 cherry psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); 540 1.1 cherry 541 1.1 cherry psize_t npages2 = (VALID_END_PFN_2 - VALID_START_PFN_2); 542 1.1 cherry 543 1.1 cherry struct vm_page *slab = malloc(sizeof(struct vm_page) * 544 1.1 cherry (npages1 + npages2)); 545 1.1 cherry 546 1.1 cherry setup(); 547 1.1 cherry 548 1.1 cherry /* We start with zero segments */ 549 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_1, npages1, NULL)); 550 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 551 1.1 cherry 552 1.1 cherry /* Post boot: Fake all segments and pages accounted for. */ 553 1.1 cherry uvm_page_init_fake(slab, npages1 + npages2); 554 1.1 cherry 555 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_2, npages2, NULL)); 556 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 557 1.1 cherry 558 1.1 cherry srandom((unsigned)time(NULL)); 559 1.1 cherry for(pf = VALID_START_PFN_2; pf < VALID_END_PFN_2; pf += PF_STEP) { 560 1.1 cherry pf_chunk_size = (psize_t) random() % (psize_t) (PF_STEP - 1) + 1; 561 1.1 cherry uvm_physseg_unplug(pf, pf_chunk_size); 562 1.1 cherry } 563 1.1 cherry 564 1.1 cherry for(int i = 0; i < 10000000; i++) { 565 1.1 cherry pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_2); 566 1.1 cherry if(pa < ctob(VALID_START_PFN_2)) 567 1.1 cherry pa += ctob(VALID_START_PFN_2); 568 1.1 cherry PHYS_TO_VM_PAGE(pa); 569 1.1 cherry } 570 1.1 cherry 571 1.1 cherry ATF_CHECK_EQ(true, true); 572 1.1 cherry } 573 1.1 cherry 574 1.1 cherry ATF_TC(uvm_physseg_64MB); 575 1.1 cherry ATF_TC_HEAD(uvm_physseg_64MB, tc) 576 1.1 cherry { 577 1.1 cherry atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 578 1.1 cherry 10,000,000 calls, VM_PHYSSEG_MAX is 32 on 64 MB Segment."); 579 1.1 cherry } 580 1.1 cherry ATF_TC_BODY(uvm_physseg_64MB, t) 581 1.1 cherry { 582 1.1 cherry paddr_t pa = 0; 583 1.1 cherry 584 1.1 cherry paddr_t pf = 0; 585 1.1 cherry 586 1.1 cherry psize_t pf_chunk_size = 0; 587 1.1 cherry 588 1.1 cherry psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); 589 1.1 cherry 590 1.1 cherry psize_t npages2 = (VALID_END_PFN_3 - VALID_START_PFN_3); 591 1.1 cherry 592 1.1 cherry struct vm_page *slab = malloc(sizeof(struct vm_page) * 593 1.1 cherry (npages1 + npages2)); 594 1.1 cherry 595 1.1 cherry setup(); 596 1.1 cherry 597 1.1 cherry /* We start with zero segments */ 598 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_1, npages1, NULL)); 599 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 600 1.1 cherry 601 1.1 cherry /* Post boot: Fake all segments and pages accounted for. */ 602 1.1 cherry uvm_page_init_fake(slab, npages1 + npages2); 603 1.1 cherry 604 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_3, npages2, NULL)); 605 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 606 1.1 cherry 607 1.1 cherry srandom((unsigned)time(NULL)); 608 1.1 cherry for(pf = VALID_START_PFN_3; pf < VALID_END_PFN_3; pf += PF_STEP) { 609 1.1 cherry pf_chunk_size = (psize_t) random() % (psize_t) (PF_STEP - 1) + 1; 610 1.1 cherry uvm_physseg_unplug(pf, pf_chunk_size); 611 1.1 cherry } 612 1.1 cherry 613 1.1 cherry for(int i = 0; i < 10000000; i++) { 614 1.1 cherry pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_3); 615 1.1 cherry if(pa < ctob(VALID_START_PFN_3)) 616 1.1 cherry pa += ctob(VALID_START_PFN_3); 617 1.1 cherry PHYS_TO_VM_PAGE(pa); 618 1.1 cherry } 619 1.1 cherry 620 1.1 cherry ATF_CHECK_EQ(true, true); 621 1.1 cherry } 622 1.1 cherry 623 1.1 cherry ATF_TC(uvm_physseg_128MB); 624 1.1 cherry ATF_TC_HEAD(uvm_physseg_128MB, tc) 625 1.1 cherry { 626 1.1 cherry atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 627 1.1 cherry 10,000,000 calls, VM_PHYSSEG_MAX is 32 on 128 MB Segment."); 628 1.1 cherry } 629 1.1 cherry ATF_TC_BODY(uvm_physseg_128MB, t) 630 1.1 cherry { 631 1.1 cherry paddr_t pa = 0; 632 1.1 cherry 633 1.1 cherry paddr_t pf = 0; 634 1.1 cherry 635 1.1 cherry psize_t pf_chunk_size = 0; 636 1.1 cherry 637 1.1 cherry psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); 638 1.1 cherry 639 1.1 cherry psize_t npages2 = (VALID_END_PFN_4 - VALID_START_PFN_4); 640 1.1 cherry 641 1.1 cherry struct vm_page *slab = malloc(sizeof(struct vm_page) 642 1.1 cherry * (npages1 + npages2)); 643 1.1 cherry 644 1.1 cherry setup(); 645 1.1 cherry 646 1.1 cherry /* We start with zero segments */ 647 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_1, npages1, NULL)); 648 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 649 1.1 cherry 650 1.1 cherry /* Post boot: Fake all segments and pages accounted for. */ 651 1.1 cherry uvm_page_init_fake(slab, npages1 + npages2); 652 1.1 cherry 653 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_2, npages2, NULL)); 654 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 655 1.1 cherry 656 1.1 cherry srandom((unsigned)time(NULL)); 657 1.1 cherry for(pf = VALID_START_PFN_4; pf < VALID_END_PFN_4; pf += PF_STEP) { 658 1.1 cherry pf_chunk_size = (psize_t) random() % (psize_t) (PF_STEP - 1) + 1; 659 1.1 cherry uvm_physseg_unplug(pf, pf_chunk_size); 660 1.1 cherry } 661 1.1 cherry 662 1.1 cherry for(int i = 0; i < 10000000; i++) { 663 1.1 cherry pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_4); 664 1.1 cherry if(pa < ctob(VALID_START_PFN_4)) 665 1.1 cherry pa += ctob(VALID_START_PFN_4); 666 1.1 cherry PHYS_TO_VM_PAGE(pa); 667 1.1 cherry } 668 1.1 cherry 669 1.1 cherry ATF_CHECK_EQ(true, true); 670 1.1 cherry } 671 1.1 cherry 672 1.1 cherry ATF_TC(uvm_physseg_256MB); 673 1.1 cherry ATF_TC_HEAD(uvm_physseg_256MB, tc) 674 1.1 cherry { 675 1.1 cherry atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 676 1.1 cherry 10,000,000 calls, VM_PHYSSEG_MAX is 32 on 256 MB Segment."); 677 1.1 cherry } 678 1.1 cherry ATF_TC_BODY(uvm_physseg_256MB, t) 679 1.1 cherry { 680 1.1 cherry paddr_t pa = 0; 681 1.1 cherry 682 1.1 cherry paddr_t pf = 0; 683 1.1 cherry 684 1.1 cherry psize_t pf_chunk_size = 0; 685 1.1 cherry 686 1.1 cherry psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); 687 1.1 cherry 688 1.1 cherry psize_t npages2 = (VALID_END_PFN_5 - VALID_START_PFN_5); 689 1.1 cherry 690 1.1 cherry struct vm_page *slab = malloc(sizeof(struct vm_page) * (npages1 + npages2)); 691 1.1 cherry 692 1.1 cherry setup(); 693 1.1 cherry 694 1.1 cherry /* We start with zero segments */ 695 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_1, npages1, NULL)); 696 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 697 1.1 cherry 698 1.1 cherry /* Post boot: Fake all segments and pages accounted for. */ 699 1.1 cherry uvm_page_init_fake(slab, npages1 + npages2); 700 1.1 cherry 701 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_2, npages2, NULL)); 702 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 703 1.1 cherry 704 1.1 cherry srandom((unsigned)time(NULL)); 705 1.1 cherry for(pf = VALID_START_PFN_5; pf < VALID_END_PFN_5; pf += PF_STEP) { 706 1.1 cherry pf_chunk_size = (psize_t) random() % (psize_t) (PF_STEP - 1) + 1; 707 1.1 cherry uvm_physseg_unplug(pf, pf_chunk_size); 708 1.1 cherry } 709 1.1 cherry 710 1.1 cherry for(int i = 0; i < 10000000; i++) { 711 1.1 cherry pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_5); 712 1.1 cherry if(pa < ctob(VALID_END_PFN_5)) 713 1.1 cherry pa += ctob(VALID_START_PFN_5); 714 1.1 cherry PHYS_TO_VM_PAGE(pa); 715 1.1 cherry } 716 1.1 cherry 717 1.1 cherry ATF_CHECK_EQ(true, true); 718 1.1 cherry } 719 1.1 cherry 720 1.1 cherry ATF_TP_ADD_TCS(tp) 721 1.1 cherry { 722 1.1 cherry /* Fixed memory size tests. */ 723 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_100); 724 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_1K); 725 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_10K); 726 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_100K); 727 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_1M); 728 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_10M); 729 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_100M); 730 1.1 cherry 731 1.1 cherry #if defined(UVM_HOTPLUG) 732 1.1 cherry /* Variable memory size tests. */ 733 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_1MB); 734 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_64MB); 735 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_128MB); 736 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_256MB); 737 1.1 cherry #endif /* UVM_HOTPLUG */ 738 1.1 cherry 739 1.1 cherry return atf_no_error(); 740 1.1 cherry } 741