1312123Sngie/* $NetBSD: t_uvm_physseg_load.c,v 1.2 2016/12/22 08:15:20 cherry Exp $ */ 2312123Sngie 3312123Sngie/*- 4312123Sngie * Copyright (c) 2015, 2016 The NetBSD Foundation, Inc. 5312123Sngie * All rights reserved. 6312123Sngie * 7312123Sngie * This code is derived from software contributed to The NetBSD Foundation 8312123Sngie * by Santhosh N. Raju <santhosh.raju@gmail.com> and 9312123Sngie * by Cherry G. Mathew 10312123Sngie * 11312123Sngie * Redistribution and use in source and binary forms, with or without 12312123Sngie * modification, are permitted provided that the following conditions 13312123Sngie * are met: 14312123Sngie * 1. Redistributions of source code must retain the above copyright 15312123Sngie * notice, this list of conditions and the following disclaimer. 16312123Sngie * 2. Redistributions in binary form must reproduce the above copyright 17312123Sngie * notice, this list of conditions and the following disclaimer in the 18312123Sngie * documentation and/or other materials provided with the distribution. 19312123Sngie * 20312123Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21312123Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22312123Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23312123Sngie * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24312123Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25312123Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26312123Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27312123Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28312123Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29312123Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30312123Sngie * POSSIBILITY OF SUCH DAMAGE. 31312123Sngie */ 32312123Sngie 33312123Sngie#include <sys/cdefs.h> 34312123Sngie__RCSID("$NetBSD: t_uvm_physseg_load.c,v 1.2 2016/12/22 08:15:20 cherry Exp $"); 35312123Sngie 36312123Sngie/* 37312123Sngie * If this line is commented out tests related touvm_physseg_get_pmseg() 38312123Sngie * wont run. 39312123Sngie * 40312123Sngie * Have a look at machine/uvm_physseg.h for more details. 41312123Sngie */ 42312123Sngie#define __HAVE_PMAP_PHYSSEG 43312123Sngie 44312123Sngie/* 45312123Sngie * This is a dummy struct used for testing purposes 46312123Sngie * 47312123Sngie * In reality this struct would exist in the MD part of the code residing in 48312123Sngie * machines/vmparam.h 49312123Sngie */ 50312123Sngie 51312123Sngie#ifdef __HAVE_PMAP_PHYSSEG 52312123Sngiestruct pmap_physseg { 53312123Sngie int dummy_variable; /* Dummy variable use for testing */ 54312123Sngie}; 55312123Sngie#endif 56312123Sngie 57312123Sngie/* Testing API - assumes userland */ 58312123Sngie/* Provide Kernel API equivalents */ 59312123Sngie#include <assert.h> 60312123Sngie#include <stdbool.h> 61312123Sngie#include <string.h> /* memset(3) et. al */ 62312123Sngie#include <stdio.h> /* printf(3) */ 63312123Sngie#include <stdlib.h> /* malloc(3) */ 64312123Sngie#include <stdarg.h> 65312123Sngie#include <stddef.h> 66312123Sngie#include <time.h> 67312123Sngie 68312123Sngie#define PRIxPADDR "lx" 69312123Sngie#define PRIxPSIZE "lx" 70312123Sngie#define PRIuPSIZE "lu" 71312123Sngie#define PRIxVADDR "lx" 72312123Sngie#define PRIxVSIZE "lx" 73312123Sngie#define PRIuVSIZE "lu" 74312123Sngie 75312123Sngie#define UVM_HOTPLUG /* Enable hotplug with rbtree. */ 76312123Sngie#define PMAP_STEAL_MEMORY 77312123Sngie#define DEBUG /* Enable debug functionality. */ 78312123Sngie 79312123Sngietypedef unsigned long vaddr_t; 80312123Sngietypedef unsigned long paddr_t; 81312123Sngietypedef unsigned long psize_t; 82312123Sngietypedef unsigned long vsize_t; 83312123Sngie 84312123Sngie#include <uvm/uvm_physseg.h> 85312123Sngie#include <uvm/uvm_page.h> 86312123Sngie 87312123Sngie#ifndef DIAGNOSTIC 88312123Sngie#define KASSERTMSG(e, msg, ...) /* NOTHING */ 89312123Sngie#define KASSERT(e) /* NOTHING */ 90312123Sngie#else 91312123Sngie#define KASSERT(a) assert(a) 92312123Sngie#define KASSERTMSG(exp, ...) printf(__VA_ARGS__); assert((exp)) 93312123Sngie#endif 94312123Sngie 95312123Sngie#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH 96312123Sngie 97312123Sngie#define VM_NFREELIST 4 98312123Sngie#define VM_FREELIST_DEFAULT 0 99312123Sngie#define VM_FREELIST_FIRST16 3 100312123Sngie#define VM_FREELIST_FIRST1G 2 101312123Sngie#define VM_FREELIST_FIRST4G 1 102312123Sngie 103312123Sngie/* 104312123Sngie * Used in tests when Array implementation is tested 105312123Sngie */ 106312123Sngie#if !defined(VM_PHYSSEG_MAX) 107312123Sngie#define VM_PHYSSEG_MAX 32 108312123Sngie#endif 109312123Sngie 110312123Sngie#define PAGE_SIZE 4096 111312123Sngie#define PAGE_SHIFT 12 112312123Sngie#define atop(x) (((paddr_t)(x)) >> PAGE_SHIFT) 113312123Sngie 114312123Sngie#define mutex_enter(l) 115312123Sngie#define mutex_exit(l) 116312123Sngie 117312123Sngie#define _SYS_KMEM_H_ /* Disallow the real kmem API (see below) */ 118312123Sngie/* free(p) XXX: pgs management need more thought */ 119312123Sngie#define kmem_alloc(size, flags) malloc(size) 120312123Sngie#define kmem_zalloc(size, flags) malloc(size) 121312123Sngie#define kmem_free(p, size) free(p) 122312123Sngie 123312123Sngiepsize_t physmem; 124312123Sngie 125312123Sngiestruct uvmexp uvmexp; /* decl */ 126312123Sngie 127312123Sngie/* 128312123Sngie * uvm structure borrowed from uvm.h 129312123Sngie * 130312123Sngie * Remember this is a dummy structure used within the ATF Tests and 131312123Sngie * uses only necessary fields from the original uvm struct. 132312123Sngie * See uvm/uvm.h for the full struct. 133312123Sngie */ 134312123Sngie 135312123Sngiestruct uvm { 136312123Sngie /* vm_page related parameters */ 137312123Sngie 138312123Sngie bool page_init_done; /* TRUE if uvm_page_init() finished */ 139312123Sngie} uvm; 140312123Sngie 141312123Sngiestatic void 142312123Sngiepanic(const char *fmt, ...) 143312123Sngie{ 144312123Sngie va_list ap; 145312123Sngie 146312123Sngie va_start(ap, fmt); 147312123Sngie vprintf(fmt, ap); 148312123Sngie printf("\n"); 149312123Sngie va_end(ap); 150312123Sngie KASSERT(false); 151312123Sngie 152312123Sngie /*NOTREACHED*/ 153312123Sngie} 154312123Sngie 155312123Sngiestatic void 156312123Sngieuvm_pagefree(struct vm_page *pg) 157312123Sngie{ 158312123Sngie return; 159312123Sngie} 160312123Sngie 161312123Sngie#if defined(UVM_HOTPLUG) 162312123Sngiestatic void 163312123Sngieuvmpdpol_reinit(void) 164312123Sngie{ 165312123Sngie return; 166312123Sngie} 167312123Sngie#endif /* UVM_HOTPLUG */ 168312123Sngie 169312123Sngie/* end - Provide Kernel API equivalents */ 170312123Sngie 171312123Sngie#include "uvm/uvm_physseg.c" 172312123Sngie 173312123Sngie#include <atf-c.h> 174312123Sngie 175312123Sngie#define ONE_MEGABYTE 1024 * 1024 176312123Sngie 177312123Sngie/* Sample Page Frame Numbers */ 178312123Sngie#define VALID_START_PFN_1 atop(0) 179312123Sngie#define VALID_END_PFN_1 atop(ONE_MEGABYTE) 180312123Sngie#define VALID_AVAIL_START_PFN_1 atop(0) 181312123Sngie#define VALID_AVAIL_END_PFN_1 atop(ONE_MEGABYTE) 182312123Sngie 183312123Sngie#define VALID_START_PFN_2 atop(ONE_MEGABYTE + 1) 184312123Sngie#define VALID_END_PFN_2 atop(ONE_MEGABYTE * 2) 185312123Sngie#define VALID_AVAIL_START_PFN_2 atop(ONE_MEGABYTE + 1) 186312123Sngie#define VALID_AVAIL_END_PFN_2 atop(ONE_MEGABYTE * 2) 187312123Sngie 188312123Sngie#define VALID_START_PFN_3 atop((ONE_MEGABYTE * 2) + 1) 189312123Sngie#define VALID_END_PFN_3 atop(ONE_MEGABYTE * 3) 190312123Sngie#define VALID_AVAIL_START_PFN_3 atop((ONE_MEGABYTE * 2) + 1) 191312123Sngie#define VALID_AVAIL_END_PFN_3 atop(ONE_MEGABYTE * 3) 192312123Sngie 193312123Sngie#define VALID_START_PFN_4 atop(ONE_MEGABYTE + 1) 194312123Sngie#define VALID_END_PFN_4 atop(ONE_MEGABYTE * 128) 195312123Sngie#define VALID_AVAIL_START_PFN_4 atop(ONE_MEGABYTE + 1) 196312123Sngie#define VALID_AVAIL_END_PFN_4 atop(ONE_MEGABYTE * 128) 197312123Sngie 198312123Sngie#define VALID_START_PFN_5 atop(ONE_MEGABYTE + 1) 199312123Sngie#define VALID_END_PFN_5 atop(ONE_MEGABYTE * 256) 200312123Sngie#define VALID_AVAIL_START_PFN_5 atop(ONE_MEGABYTE + 1) 201312123Sngie#define VALID_AVAIL_END_PFN_5 atop(ONE_MEGABYTE * 256) 202312123Sngie 203312123Sngie/* 204312123Sngie * Total number of pages (of 4K size each) should be 256 for 1MB of memory. 205312123Sngie */ 206312123Sngie#define PAGE_COUNT_1M 256 207312123Sngie 208312123Sngie/* 209312123Sngie * The number of Page Frames to allot per segment 210312123Sngie */ 211312123Sngie#define PF_STEP 8 212312123Sngie 213312123Sngie/* 214312123Sngie * A debug fucntion to print the content of upm. 215312123Sngie */ 216312123Sngie static inline void 217312123Sngie uvm_physseg_dump_seg(uvm_physseg_t upm) 218312123Sngie { 219312123Sngie#if defined(DEBUG) 220312123Sngie printf("%s: seg->start == %ld\n", __func__, 221312123Sngie uvm_physseg_get_start(upm)); 222312123Sngie printf("%s: seg->end == %ld\n", __func__, 223312123Sngie uvm_physseg_get_end(upm)); 224312123Sngie printf("%s: seg->avail_start == %ld\n", __func__, 225312123Sngie uvm_physseg_get_avail_start(upm)); 226312123Sngie printf("%s: seg->avail_end == %ld\n", __func__, 227312123Sngie uvm_physseg_get_avail_end(upm)); 228312123Sngie 229312123Sngie printf("====\n\n"); 230312123Sngie#else 231312123Sngie return; 232312123Sngie#endif /* DEBUG */ 233312123Sngie } 234312123Sngie 235312123Sngie/* 236312123Sngie * Private accessor that gets the value of vm_physmem.nentries 237312123Sngie */ 238312123Sngiestatic int 239312123Sngieuvm_physseg_get_entries(void) 240312123Sngie{ 241312123Sngie#if defined(UVM_HOTPLUG) 242312123Sngie return uvm_physseg_graph.nentries; 243312123Sngie#else 244312123Sngie return vm_nphysmem; 245312123Sngie#endif /* UVM_HOTPLUG */ 246312123Sngie} 247312123Sngie 248312123Sngie/* 249312123Sngie * Note: This function replicates verbatim what happens in 250312123Sngie * uvm_page.c:uvm_page_init(). 251312123Sngie * 252312123Sngie * Please track any changes that happen there. 253312123Sngie */ 254312123Sngiestatic void 255312123Sngieuvm_page_init_fake(struct vm_page *pagearray, psize_t pagecount) 256312123Sngie{ 257312123Sngie uvm_physseg_t bank; 258312123Sngie size_t n; 259312123Sngie 260312123Sngie for (bank = uvm_physseg_get_first(), 261312123Sngie uvm_physseg_seg_chomp_slab(bank, pagearray, pagecount); 262312123Sngie uvm_physseg_valid_p(bank); 263312123Sngie bank = uvm_physseg_get_next(bank)) { 264312123Sngie 265312123Sngie n = uvm_physseg_get_end(bank) - uvm_physseg_get_start(bank); 266312123Sngie uvm_physseg_seg_alloc_from_slab(bank, n); 267312123Sngie uvm_physseg_init_seg(bank, pagearray); 268312123Sngie 269312123Sngie /* set up page array pointers */ 270312123Sngie pagearray += n; 271312123Sngie pagecount -= n; 272312123Sngie } 273312123Sngie 274312123Sngie uvm.page_init_done = true; 275312123Sngie} 276312123Sngie 277312123Sngie/* 278312123Sngie * PHYS_TO_VM_PAGE: find vm_page for a PA. used by MI code to get vm_pages 279312123Sngie * back from an I/O mapping (ugh!). used in some MD code as well. 280312123Sngie */ 281312123Sngiestatic struct vm_page * 282312123Sngieuvm_phys_to_vm_page(paddr_t pa) 283312123Sngie{ 284312123Sngie paddr_t pf = atop(pa); 285312123Sngie paddr_t off; 286312123Sngie uvm_physseg_t psi; 287312123Sngie 288312123Sngie psi = uvm_physseg_find(pf, &off); 289312123Sngie if (psi != UVM_PHYSSEG_TYPE_INVALID) 290312123Sngie return uvm_physseg_get_pg(psi, off); 291312123Sngie return(NULL); 292312123Sngie} 293312123Sngie 294312123Sngie//static paddr_t 295312123Sngie//uvm_vm_page_to_phys(const struct vm_page *pg) 296312123Sngie//{ 297312123Sngie// 298312123Sngie// return pg->phys_addr; 299312123Sngie//} 300312123Sngie 301312123Sngie/* 302312123Sngie * XXX: To do, write control test cases for uvm_vm_page_to_phys(). 303312123Sngie */ 304312123Sngie 305312123Sngie/* #define VM_PAGE_TO_PHYS(entry) uvm_vm_page_to_phys(entry) */ 306312123Sngie 307312123Sngie#define PHYS_TO_VM_PAGE(pa) uvm_phys_to_vm_page(pa) 308312123Sngie 309312123Sngie/* 310312123Sngie * Test Fixture SetUp(). 311312123Sngie */ 312312123Sngiestatic void 313312123Sngiesetup(void) 314312123Sngie{ 315312123Sngie /* Prerequisites for running certain calls in uvm_physseg */ 316312123Sngie uvmexp.pagesize = PAGE_SIZE; 317312123Sngie uvmexp.npages = 0; 318312123Sngie uvm.page_init_done = false; 319312123Sngie uvm_physseg_init(); 320312123Sngie} 321312123Sngie 322312123SngieATF_TC(uvm_physseg_100); 323312123SngieATF_TC_HEAD(uvm_physseg_100, tc) 324312123Sngie{ 325312123Sngie atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 326312123Sngie 100 calls, VM_PHYSSEG_MAX is 32."); 327312123Sngie} 328312123SngieATF_TC_BODY(uvm_physseg_100, tc) 329312123Sngie{ 330312123Sngie paddr_t pa; 331312123Sngie 332312123Sngie setup(); 333312123Sngie 334312123Sngie for(paddr_t i = VALID_START_PFN_1; 335312123Sngie i < VALID_END_PFN_1; i += PF_STEP) { 336312123Sngie uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 337312123Sngie VM_FREELIST_DEFAULT); 338312123Sngie } 339312123Sngie 340312123Sngie ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 341312123Sngie 342312123Sngie srandom((unsigned)time(NULL)); 343312123Sngie for(int i = 0; i < 100; i++) { 344312123Sngie pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 345312123Sngie PHYS_TO_VM_PAGE(pa); 346312123Sngie } 347312123Sngie 348312123Sngie ATF_CHECK_EQ(true, true); 349312123Sngie} 350312123Sngie 351312123SngieATF_TC(uvm_physseg_1K); 352312123SngieATF_TC_HEAD(uvm_physseg_1K, tc) 353312123Sngie{ 354312123Sngie atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 355312123Sngie 1000 calls, VM_PHYSSEG_MAX is 32."); 356312123Sngie} 357312123SngieATF_TC_BODY(uvm_physseg_1K, tc) 358312123Sngie{ 359312123Sngie paddr_t pa; 360312123Sngie 361312123Sngie setup(); 362312123Sngie 363312123Sngie for(paddr_t i = VALID_START_PFN_1; 364312123Sngie i < VALID_END_PFN_1; i += PF_STEP) { 365312123Sngie uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 366312123Sngie VM_FREELIST_DEFAULT); 367312123Sngie } 368312123Sngie 369312123Sngie ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 370312123Sngie 371312123Sngie srandom((unsigned)time(NULL)); 372312123Sngie for(int i = 0; i < 1000; i++) { 373312123Sngie pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 374312123Sngie PHYS_TO_VM_PAGE(pa); 375312123Sngie } 376312123Sngie 377312123Sngie ATF_CHECK_EQ(true, true); 378312123Sngie} 379312123Sngie 380312123SngieATF_TC(uvm_physseg_10K); 381312123SngieATF_TC_HEAD(uvm_physseg_10K, tc) 382312123Sngie{ 383312123Sngie atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 384312123Sngie 10,000 calls, VM_PHYSSEG_MAX is 32."); 385312123Sngie} 386312123SngieATF_TC_BODY(uvm_physseg_10K, tc) 387312123Sngie{ 388312123Sngie paddr_t pa; 389312123Sngie 390312123Sngie setup(); 391312123Sngie 392312123Sngie for(paddr_t i = VALID_START_PFN_1; 393312123Sngie i < VALID_END_PFN_1; i += PF_STEP) { 394312123Sngie uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 395312123Sngie VM_FREELIST_DEFAULT); 396312123Sngie } 397312123Sngie 398312123Sngie ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 399312123Sngie 400312123Sngie srandom((unsigned)time(NULL)); 401312123Sngie for(int i = 0; i < 10000; i++) { 402312123Sngie pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 403312123Sngie PHYS_TO_VM_PAGE(pa); 404312123Sngie } 405312123Sngie 406312123Sngie ATF_CHECK_EQ(true, true); 407312123Sngie} 408312123Sngie 409312123SngieATF_TC(uvm_physseg_100K); 410312123SngieATF_TC_HEAD(uvm_physseg_100K, tc) 411312123Sngie{ 412312123Sngie atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 413312123Sngie 100,000 calls, VM_PHYSSEG_MAX is 32."); 414312123Sngie} 415312123SngieATF_TC_BODY(uvm_physseg_100K, tc) 416312123Sngie{ 417312123Sngie paddr_t pa; 418312123Sngie 419312123Sngie setup(); 420312123Sngie 421312123Sngie for(paddr_t i = VALID_START_PFN_1; 422312123Sngie i < VALID_END_PFN_1; i += PF_STEP) { 423312123Sngie uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 424312123Sngie VM_FREELIST_DEFAULT); 425312123Sngie } 426312123Sngie 427312123Sngie ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 428312123Sngie 429312123Sngie srandom((unsigned)time(NULL)); 430312123Sngie for(int i = 0; i < 100000; i++) { 431312123Sngie pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 432312123Sngie PHYS_TO_VM_PAGE(pa); 433312123Sngie } 434312123Sngie 435312123Sngie ATF_CHECK_EQ(true, true); 436312123Sngie} 437312123Sngie 438312123SngieATF_TC(uvm_physseg_1M); 439312123SngieATF_TC_HEAD(uvm_physseg_1M, tc) 440312123Sngie{ 441312123Sngie atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 442312123Sngie 1,000,000 calls, VM_PHYSSEG_MAX is 32."); 443312123Sngie} 444312123SngieATF_TC_BODY(uvm_physseg_1M, tc) 445312123Sngie{ 446312123Sngie paddr_t pa; 447312123Sngie 448312123Sngie setup(); 449312123Sngie 450312123Sngie for(paddr_t i = VALID_START_PFN_1; 451312123Sngie i < VALID_END_PFN_1; i += PF_STEP) { 452312123Sngie uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 453312123Sngie VM_FREELIST_DEFAULT); 454312123Sngie } 455312123Sngie 456312123Sngie ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 457312123Sngie 458312123Sngie srandom((unsigned)time(NULL)); 459312123Sngie for(int i = 0; i < 1000000; i++) { 460312123Sngie pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 461312123Sngie PHYS_TO_VM_PAGE(pa); 462312123Sngie } 463312123Sngie 464312123Sngie ATF_CHECK_EQ(true, true); 465312123Sngie} 466312123Sngie 467312123SngieATF_TC(uvm_physseg_10M); 468312123SngieATF_TC_HEAD(uvm_physseg_10M, tc) 469312123Sngie{ 470312123Sngie atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 471312123Sngie 10,000,000 calls, VM_PHYSSEG_MAX is 32."); 472312123Sngie} 473312123SngieATF_TC_BODY(uvm_physseg_10M, tc) 474312123Sngie{ 475312123Sngie paddr_t pa; 476312123Sngie 477312123Sngie setup(); 478312123Sngie 479312123Sngie for(paddr_t i = VALID_START_PFN_1; 480312123Sngie i < VALID_END_PFN_1; i += PF_STEP) { 481312123Sngie uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 482312123Sngie VM_FREELIST_DEFAULT); 483312123Sngie } 484312123Sngie 485312123Sngie ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 486312123Sngie 487312123Sngie srandom((unsigned)time(NULL)); 488312123Sngie for(int i = 0; i < 10000000; i++) { 489312123Sngie pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 490312123Sngie PHYS_TO_VM_PAGE(pa); 491312123Sngie } 492312123Sngie 493312123Sngie ATF_CHECK_EQ(true, true); 494312123Sngie} 495312123Sngie 496312123SngieATF_TC(uvm_physseg_100M); 497312123SngieATF_TC_HEAD(uvm_physseg_100M, tc) 498312123Sngie{ 499312123Sngie atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 500312123Sngie 100,000,000 calls, VM_PHYSSEG_MAX is 32."); 501312123Sngie} 502312123SngieATF_TC_BODY(uvm_physseg_100M, tc) 503312123Sngie{ 504312123Sngie paddr_t pa; 505312123Sngie 506312123Sngie setup(); 507312123Sngie 508312123Sngie for(paddr_t i = VALID_START_PFN_1; 509312123Sngie i < VALID_END_PFN_1; i += PF_STEP) { 510312123Sngie uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, 511312123Sngie VM_FREELIST_DEFAULT); 512312123Sngie } 513312123Sngie 514312123Sngie ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); 515312123Sngie 516312123Sngie srandom((unsigned)time(NULL)); 517312123Sngie for(int i = 0; i < 100000000; i++) { 518312123Sngie pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); 519312123Sngie PHYS_TO_VM_PAGE(pa); 520312123Sngie } 521312123Sngie 522312123Sngie ATF_CHECK_EQ(true, true); 523312123Sngie} 524312123Sngie 525312123SngieATF_TC(uvm_physseg_1MB); 526312123SngieATF_TC_HEAD(uvm_physseg_1MB, tc) 527312123Sngie{ 528312123Sngie atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 529312123Sngie 10,000,000 calls, VM_PHYSSEG_MAX is 32 on 1 MB Segment."); 530312123Sngie} 531312123SngieATF_TC_BODY(uvm_physseg_1MB, t) 532312123Sngie{ 533312123Sngie paddr_t pa = 0; 534312123Sngie 535312123Sngie paddr_t pf = 0; 536312123Sngie 537312123Sngie psize_t pf_chunk_size = 0; 538312123Sngie 539312123Sngie psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); 540312123Sngie 541312123Sngie psize_t npages2 = (VALID_END_PFN_2 - VALID_START_PFN_2); 542312123Sngie 543312123Sngie struct vm_page *slab = malloc(sizeof(struct vm_page) * 544312123Sngie (npages1 + npages2)); 545312123Sngie 546312123Sngie setup(); 547312123Sngie 548312123Sngie /* We start with zero segments */ 549312123Sngie ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_1, npages1, NULL)); 550312123Sngie ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 551312123Sngie 552312123Sngie /* Post boot: Fake all segments and pages accounted for. */ 553312123Sngie uvm_page_init_fake(slab, npages1 + npages2); 554312123Sngie 555312123Sngie ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_2, npages2, NULL)); 556312123Sngie ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 557312123Sngie 558312123Sngie srandom((unsigned)time(NULL)); 559312123Sngie for(pf = VALID_START_PFN_2; pf < VALID_END_PFN_2; pf += PF_STEP) { 560312123Sngie pf_chunk_size = (psize_t) random() % (psize_t) (PF_STEP - 1) + 1; 561312123Sngie uvm_physseg_unplug(pf, pf_chunk_size); 562312123Sngie } 563312123Sngie 564312123Sngie for(int i = 0; i < 10000000; i++) { 565312123Sngie pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_2); 566312123Sngie if(pa < ctob(VALID_START_PFN_2)) 567312123Sngie pa += ctob(VALID_START_PFN_2); 568312123Sngie PHYS_TO_VM_PAGE(pa); 569312123Sngie } 570312123Sngie 571312123Sngie ATF_CHECK_EQ(true, true); 572312123Sngie} 573312123Sngie 574312123SngieATF_TC(uvm_physseg_64MB); 575312123SngieATF_TC_HEAD(uvm_physseg_64MB, tc) 576312123Sngie{ 577312123Sngie atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 578312123Sngie 10,000,000 calls, VM_PHYSSEG_MAX is 32 on 64 MB Segment."); 579312123Sngie} 580312123SngieATF_TC_BODY(uvm_physseg_64MB, t) 581312123Sngie{ 582312123Sngie paddr_t pa = 0; 583312123Sngie 584312123Sngie paddr_t pf = 0; 585312123Sngie 586312123Sngie psize_t pf_chunk_size = 0; 587312123Sngie 588312123Sngie psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); 589312123Sngie 590312123Sngie psize_t npages2 = (VALID_END_PFN_3 - VALID_START_PFN_3); 591312123Sngie 592312123Sngie struct vm_page *slab = malloc(sizeof(struct vm_page) * 593312123Sngie (npages1 + npages2)); 594312123Sngie 595312123Sngie setup(); 596312123Sngie 597312123Sngie /* We start with zero segments */ 598312123Sngie ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_1, npages1, NULL)); 599312123Sngie ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 600312123Sngie 601312123Sngie /* Post boot: Fake all segments and pages accounted for. */ 602312123Sngie uvm_page_init_fake(slab, npages1 + npages2); 603312123Sngie 604312123Sngie ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_3, npages2, NULL)); 605312123Sngie ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 606312123Sngie 607312123Sngie srandom((unsigned)time(NULL)); 608312123Sngie for(pf = VALID_START_PFN_3; pf < VALID_END_PFN_3; pf += PF_STEP) { 609312123Sngie pf_chunk_size = (psize_t) random() % (psize_t) (PF_STEP - 1) + 1; 610312123Sngie uvm_physseg_unplug(pf, pf_chunk_size); 611312123Sngie } 612312123Sngie 613312123Sngie for(int i = 0; i < 10000000; i++) { 614312123Sngie pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_3); 615312123Sngie if(pa < ctob(VALID_START_PFN_3)) 616312123Sngie pa += ctob(VALID_START_PFN_3); 617312123Sngie PHYS_TO_VM_PAGE(pa); 618312123Sngie } 619312123Sngie 620312123Sngie ATF_CHECK_EQ(true, true); 621312123Sngie} 622312123Sngie 623312123SngieATF_TC(uvm_physseg_128MB); 624312123SngieATF_TC_HEAD(uvm_physseg_128MB, tc) 625312123Sngie{ 626312123Sngie atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 627312123Sngie 10,000,000 calls, VM_PHYSSEG_MAX is 32 on 128 MB Segment."); 628312123Sngie} 629312123SngieATF_TC_BODY(uvm_physseg_128MB, t) 630312123Sngie{ 631312123Sngie paddr_t pa = 0; 632312123Sngie 633312123Sngie paddr_t pf = 0; 634312123Sngie 635312123Sngie psize_t pf_chunk_size = 0; 636312123Sngie 637312123Sngie psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); 638312123Sngie 639312123Sngie psize_t npages2 = (VALID_END_PFN_4 - VALID_START_PFN_4); 640312123Sngie 641312123Sngie struct vm_page *slab = malloc(sizeof(struct vm_page) 642312123Sngie * (npages1 + npages2)); 643312123Sngie 644312123Sngie setup(); 645312123Sngie 646312123Sngie /* We start with zero segments */ 647312123Sngie ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_1, npages1, NULL)); 648312123Sngie ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 649312123Sngie 650312123Sngie /* Post boot: Fake all segments and pages accounted for. */ 651312123Sngie uvm_page_init_fake(slab, npages1 + npages2); 652312123Sngie 653312123Sngie ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_2, npages2, NULL)); 654312123Sngie ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 655312123Sngie 656312123Sngie srandom((unsigned)time(NULL)); 657312123Sngie for(pf = VALID_START_PFN_4; pf < VALID_END_PFN_4; pf += PF_STEP) { 658312123Sngie pf_chunk_size = (psize_t) random() % (psize_t) (PF_STEP - 1) + 1; 659312123Sngie uvm_physseg_unplug(pf, pf_chunk_size); 660312123Sngie } 661312123Sngie 662312123Sngie for(int i = 0; i < 10000000; i++) { 663312123Sngie pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_4); 664312123Sngie if(pa < ctob(VALID_START_PFN_4)) 665312123Sngie pa += ctob(VALID_START_PFN_4); 666312123Sngie PHYS_TO_VM_PAGE(pa); 667312123Sngie } 668312123Sngie 669312123Sngie ATF_CHECK_EQ(true, true); 670312123Sngie} 671312123Sngie 672312123SngieATF_TC(uvm_physseg_256MB); 673312123SngieATF_TC_HEAD(uvm_physseg_256MB, tc) 674312123Sngie{ 675312123Sngie atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ 676312123Sngie 10,000,000 calls, VM_PHYSSEG_MAX is 32 on 256 MB Segment."); 677312123Sngie} 678312123SngieATF_TC_BODY(uvm_physseg_256MB, t) 679312123Sngie{ 680312123Sngie paddr_t pa = 0; 681312123Sngie 682312123Sngie paddr_t pf = 0; 683312123Sngie 684312123Sngie psize_t pf_chunk_size = 0; 685312123Sngie 686312123Sngie psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); 687312123Sngie 688312123Sngie psize_t npages2 = (VALID_END_PFN_5 - VALID_START_PFN_5); 689312123Sngie 690312123Sngie struct vm_page *slab = malloc(sizeof(struct vm_page) * (npages1 + npages2)); 691312123Sngie 692312123Sngie setup(); 693312123Sngie 694312123Sngie /* We start with zero segments */ 695312123Sngie ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_1, npages1, NULL)); 696312123Sngie ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 697312123Sngie 698312123Sngie /* Post boot: Fake all segments and pages accounted for. */ 699312123Sngie uvm_page_init_fake(slab, npages1 + npages2); 700312123Sngie 701312123Sngie ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_2, npages2, NULL)); 702312123Sngie ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 703312123Sngie 704312123Sngie srandom((unsigned)time(NULL)); 705312123Sngie for(pf = VALID_START_PFN_5; pf < VALID_END_PFN_5; pf += PF_STEP) { 706312123Sngie pf_chunk_size = (psize_t) random() % (psize_t) (PF_STEP - 1) + 1; 707312123Sngie uvm_physseg_unplug(pf, pf_chunk_size); 708312123Sngie } 709312123Sngie 710312123Sngie for(int i = 0; i < 10000000; i++) { 711312123Sngie pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_5); 712312123Sngie if(pa < ctob(VALID_END_PFN_5)) 713312123Sngie pa += ctob(VALID_START_PFN_5); 714312123Sngie PHYS_TO_VM_PAGE(pa); 715312123Sngie } 716312123Sngie 717312123Sngie ATF_CHECK_EQ(true, true); 718312123Sngie} 719312123Sngie 720312123SngieATF_TP_ADD_TCS(tp) 721312123Sngie{ 722312123Sngie /* Fixed memory size tests. */ 723312123Sngie ATF_TP_ADD_TC(tp, uvm_physseg_100); 724312123Sngie ATF_TP_ADD_TC(tp, uvm_physseg_1K); 725312123Sngie ATF_TP_ADD_TC(tp, uvm_physseg_10K); 726312123Sngie ATF_TP_ADD_TC(tp, uvm_physseg_100K); 727312123Sngie ATF_TP_ADD_TC(tp, uvm_physseg_1M); 728312123Sngie ATF_TP_ADD_TC(tp, uvm_physseg_10M); 729312123Sngie ATF_TP_ADD_TC(tp, uvm_physseg_100M); 730312123Sngie 731312123Sngie#if defined(UVM_HOTPLUG) 732312123Sngie /* Variable memory size tests. */ 733312123Sngie ATF_TP_ADD_TC(tp, uvm_physseg_1MB); 734312123Sngie ATF_TP_ADD_TC(tp, uvm_physseg_64MB); 735312123Sngie ATF_TP_ADD_TC(tp, uvm_physseg_128MB); 736312123Sngie ATF_TP_ADD_TC(tp, uvm_physseg_256MB); 737312123Sngie#endif /* UVM_HOTPLUG */ 738312123Sngie 739312123Sngie return atf_no_error(); 740312123Sngie} 741