1 1.11 andvar /* $NetBSD: t_uvm_physseg.c,v 1.11 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.11 andvar __RCSID("$NetBSD: t_uvm_physseg.c,v 1.11 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 to uvm_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 <errno.h> 61 1.1 cherry #include <stdbool.h> 62 1.1 cherry #include <string.h> /* memset(3) et. al */ 63 1.1 cherry #include <stdio.h> /* printf(3) */ 64 1.1 cherry #include <stdlib.h> /* malloc(3) */ 65 1.1 cherry #include <stdarg.h> 66 1.1 cherry #include <stddef.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 1 108 1.1 cherry #endif 109 1.1 cherry 110 1.1 cherry #define PAGE_SHIFT 12 111 1.1 cherry #define PAGE_SIZE (1 << PAGE_SHIFT) 112 1.1 cherry #define PAGE_MASK (PAGE_SIZE - 1) 113 1.1 cherry #define atop(x) (((paddr_t)(x)) >> PAGE_SHIFT) 114 1.1 cherry #define ptoa(x) (((paddr_t)(x)) << PAGE_SHIFT) 115 1.1 cherry 116 1.1 cherry #define mutex_enter(l) 117 1.1 cherry #define mutex_exit(l) 118 1.1 cherry 119 1.1 cherry psize_t physmem; 120 1.1 cherry 121 1.1 cherry struct uvmexp uvmexp; /* decl */ 122 1.1 cherry 123 1.1 cherry /* 124 1.1 cherry * uvm structure borrowed from uvm.h 125 1.1 cherry * 126 1.1 cherry * Remember this is a dummy structure used within the ATF Tests and 127 1.1 cherry * uses only necessary fields from the original uvm struct. 128 1.1 cherry * See uvm/uvm.h for the full struct. 129 1.1 cherry */ 130 1.1 cherry 131 1.1 cherry struct uvm { 132 1.1 cherry /* vm_page related parameters */ 133 1.1 cherry 134 1.1 cherry bool page_init_done; /* TRUE if uvm_page_init() finished */ 135 1.1 cherry } uvm; 136 1.1 cherry 137 1.1 cherry #include <sys/kmem.h> 138 1.1 cherry 139 1.1 cherry void * 140 1.1 cherry kmem_alloc(size_t size, km_flag_t flags) 141 1.1 cherry { 142 1.1 cherry return malloc(size); 143 1.1 cherry } 144 1.1 cherry 145 1.1 cherry void * 146 1.1 cherry kmem_zalloc(size_t size, km_flag_t flags) 147 1.1 cherry { 148 1.1 cherry void *ptr; 149 1.1 cherry ptr = malloc(size); 150 1.1 cherry 151 1.1 cherry memset(ptr, 0, size); 152 1.1 cherry 153 1.1 cherry return ptr; 154 1.1 cherry } 155 1.1 cherry 156 1.1 cherry void 157 1.1 cherry kmem_free(void *mem, size_t size) 158 1.1 cherry { 159 1.1 cherry free(mem); 160 1.1 cherry } 161 1.1 cherry 162 1.1 cherry static void 163 1.1 cherry panic(const char *fmt, ...) 164 1.1 cherry { 165 1.1 cherry va_list ap; 166 1.1 cherry 167 1.1 cherry va_start(ap, fmt); 168 1.1 cherry vprintf(fmt, ap); 169 1.1 cherry printf("\n"); 170 1.1 cherry va_end(ap); 171 1.1 cherry KASSERT(false); 172 1.1 cherry 173 1.1 cherry /*NOTREACHED*/ 174 1.1 cherry } 175 1.1 cherry 176 1.1 cherry static void 177 1.1 cherry uvm_pagefree(struct vm_page *pg) 178 1.1 cherry { 179 1.1 cherry return; 180 1.1 cherry } 181 1.1 cherry 182 1.1 cherry #if defined(UVM_HOTPLUG) 183 1.1 cherry static void 184 1.1 cherry uvmpdpol_reinit(void) 185 1.1 cherry { 186 1.1 cherry return; 187 1.1 cherry } 188 1.1 cherry #endif /* UVM_HOTPLUG */ 189 1.1 cherry 190 1.1 cherry /* end - Provide Kernel API equivalents */ 191 1.1 cherry 192 1.1 cherry 193 1.1 cherry #include "uvm/uvm_physseg.c" 194 1.1 cherry 195 1.1 cherry #include <atf-c.h> 196 1.1 cherry 197 1.1 cherry #define SIXTYFOUR_KILO (64 * 1024) 198 1.1 cherry #define ONETWENTYEIGHT_KILO (128 * 1024) 199 1.1 cherry #define TWOFIFTYSIX_KILO (256 * 1024) 200 1.1 cherry #define FIVEONETWO_KILO (512 * 1024) 201 1.1 cherry #define ONE_MEGABYTE (1024 * 1024) 202 1.1 cherry #define TWO_MEGABYTE (2 * 1024 * 1024) 203 1.1 cherry 204 1.1 cherry /* Sample Page Frame Numbers */ 205 1.1 cherry #define VALID_START_PFN_1 atop(0) 206 1.1 cherry #define VALID_END_PFN_1 atop(ONE_MEGABYTE) 207 1.1 cherry #define VALID_AVAIL_START_PFN_1 atop(0) 208 1.1 cherry #define VALID_AVAIL_END_PFN_1 atop(ONE_MEGABYTE) 209 1.1 cherry 210 1.1 cherry #define VALID_START_PFN_2 atop(ONE_MEGABYTE + 1) 211 1.1 cherry #define VALID_END_PFN_2 atop(ONE_MEGABYTE * 2) 212 1.1 cherry #define VALID_AVAIL_START_PFN_2 atop(ONE_MEGABYTE + 1) 213 1.1 cherry #define VALID_AVAIL_END_PFN_2 atop(ONE_MEGABYTE * 2) 214 1.1 cherry 215 1.1 cherry #define VALID_START_PFN_3 atop((ONE_MEGABYTE * 2) + 1) 216 1.1 cherry #define VALID_END_PFN_3 atop(ONE_MEGABYTE * 3) 217 1.1 cherry #define VALID_AVAIL_START_PFN_3 atop((ONE_MEGABYTE * 2) + 1) 218 1.1 cherry #define VALID_AVAIL_END_PFN_3 atop(ONE_MEGABYTE * 3) 219 1.1 cherry 220 1.1 cherry #define VALID_START_PFN_4 atop((ONE_MEGABYTE * 3) + 1) 221 1.1 cherry #define VALID_END_PFN_4 atop(ONE_MEGABYTE * 4) 222 1.1 cherry #define VALID_AVAIL_START_PFN_4 atop((ONE_MEGABYTE * 3) + 1) 223 1.1 cherry #define VALID_AVAIL_END_PFN_4 atop(ONE_MEGABYTE * 4) 224 1.1 cherry 225 1.1 cherry /* 226 1.1 cherry * Total number of pages (of 4K size each) should be 256 for 1MB of memory. 227 1.1 cherry */ 228 1.1 cherry #define PAGE_COUNT_1M 256 229 1.1 cherry 230 1.1 cherry /* 231 1.11 andvar * A debug function to print the content of upm. 232 1.1 cherry */ 233 1.1 cherry static inline void 234 1.1 cherry uvm_physseg_dump_seg(uvm_physseg_t upm) 235 1.1 cherry { 236 1.1 cherry #if defined(DEBUG) 237 1.1 cherry printf("%s: seg->start == %ld\n", __func__, 238 1.1 cherry uvm_physseg_get_start(upm)); 239 1.1 cherry printf("%s: seg->end == %ld\n", __func__, 240 1.1 cherry uvm_physseg_get_end(upm)); 241 1.1 cherry printf("%s: seg->avail_start == %ld\n", __func__, 242 1.1 cherry uvm_physseg_get_avail_start(upm)); 243 1.1 cherry printf("%s: seg->avail_end == %ld\n", __func__, 244 1.1 cherry uvm_physseg_get_avail_end(upm)); 245 1.1 cherry 246 1.1 cherry printf("====\n\n"); 247 1.1 cherry #else 248 1.1 cherry return; 249 1.1 cherry #endif /* DEBUG */ 250 1.1 cherry } 251 1.1 cherry 252 1.1 cherry /* 253 1.1 cherry * Private accessor that gets the value of uvm_physseg_graph.nentries 254 1.1 cherry */ 255 1.1 cherry static int 256 1.1 cherry uvm_physseg_get_entries(void) 257 1.1 cherry { 258 1.1 cherry #if defined(UVM_HOTPLUG) 259 1.1 cherry return uvm_physseg_graph.nentries; 260 1.1 cherry #else 261 1.1 cherry return vm_nphysmem; 262 1.1 cherry #endif /* UVM_HOTPLUG */ 263 1.1 cherry } 264 1.1 cherry 265 1.1 cherry #if !defined(UVM_HOTPLUG) 266 1.1 cherry static void * 267 1.1 cherry uvm_physseg_alloc(size_t sz) 268 1.1 cherry { 269 1.1 cherry return &vm_physmem[vm_nphysseg++]; 270 1.1 cherry } 271 1.1 cherry #endif 272 1.1 cherry 273 1.1 cherry /* 274 1.4 fox * This macro was added to convert uvmexp.npages from int to psize_t 275 1.4 fox */ 276 1.4 fox #define INT_TO_PSIZE_T(X) (psize_t)X 277 1.4 fox 278 1.4 fox /* 279 1.1 cherry * Test Fixture SetUp(). 280 1.1 cherry */ 281 1.1 cherry static void 282 1.1 cherry setup(void) 283 1.1 cherry { 284 1.1 cherry /* Prerequisites for running certain calls in uvm_physseg */ 285 1.1 cherry uvmexp.pagesize = PAGE_SIZE; 286 1.1 cherry uvmexp.npages = 0; 287 1.1 cherry uvm.page_init_done = false; 288 1.1 cherry uvm_physseg_init(); 289 1.1 cherry } 290 1.1 cherry 291 1.1 cherry 292 1.1 cherry /* <---- Tests for Internal functions ----> */ 293 1.1 cherry #if defined(UVM_HOTPLUG) 294 1.1 cherry ATF_TC(uvm_physseg_alloc_atboot_mismatch); 295 1.1 cherry ATF_TC_HEAD(uvm_physseg_alloc_atboot_mismatch, tc) 296 1.1 cherry { 297 1.1 cherry atf_tc_set_md_var(tc, "descr", "boot time uvm_physseg_alloc() sanity" 298 1.1 cherry "size mismatch alloc() test."); 299 1.1 cherry } 300 1.1 cherry 301 1.1 cherry ATF_TC_BODY(uvm_physseg_alloc_atboot_mismatch, tc) 302 1.1 cherry { 303 1.1 cherry uvm.page_init_done = false; 304 1.1 cherry 305 1.1 cherry atf_tc_expect_signal(SIGABRT, "size mismatch alloc()"); 306 1.1 cherry 307 1.1 cherry uvm_physseg_alloc(sizeof(struct uvm_physseg) - 1); 308 1.1 cherry } 309 1.1 cherry 310 1.1 cherry ATF_TC(uvm_physseg_alloc_atboot_overrun); 311 1.1 cherry ATF_TC_HEAD(uvm_physseg_alloc_atboot_overrun, tc) 312 1.1 cherry { 313 1.1 cherry atf_tc_set_md_var(tc, "descr", "boot time uvm_physseg_alloc() sanity" 314 1.1 cherry "array overrun alloc() test."); 315 1.1 cherry } 316 1.1 cherry 317 1.1 cherry ATF_TC_BODY(uvm_physseg_alloc_atboot_overrun, tc) 318 1.1 cherry { 319 1.1 cherry uvm.page_init_done = false; 320 1.1 cherry 321 1.1 cherry atf_tc_expect_signal(SIGABRT, "array overrun alloc()"); 322 1.1 cherry 323 1.1 cherry uvm_physseg_alloc((VM_PHYSSEG_MAX + 1) * sizeof(struct uvm_physseg)); 324 1.1 cherry 325 1.1 cherry } 326 1.1 cherry 327 1.1 cherry ATF_TC(uvm_physseg_alloc_sanity); 328 1.1 cherry ATF_TC_HEAD(uvm_physseg_alloc_sanity, tc) 329 1.1 cherry { 330 1.1 cherry atf_tc_set_md_var(tc, "descr", "further uvm_physseg_alloc() sanity checks"); 331 1.1 cherry } 332 1.1 cherry 333 1.1 cherry ATF_TC_BODY(uvm_physseg_alloc_sanity, tc) 334 1.1 cherry { 335 1.1 cherry 336 1.1 cherry /* At boot time */ 337 1.1 cherry uvm.page_init_done = false; 338 1.1 cherry 339 1.1 cherry /* Correct alloc */ 340 1.1 cherry ATF_REQUIRE(uvm_physseg_alloc(VM_PHYSSEG_MAX * sizeof(struct uvm_physseg))); 341 1.1 cherry 342 1.1 cherry /* Retry static alloc()s as dynamic - we expect them to pass */ 343 1.1 cherry uvm.page_init_done = true; 344 1.1 cherry ATF_REQUIRE(uvm_physseg_alloc(sizeof(struct uvm_physseg) - 1)); 345 1.1 cherry ATF_REQUIRE(uvm_physseg_alloc(2 * VM_PHYSSEG_MAX * sizeof(struct uvm_physseg))); 346 1.1 cherry } 347 1.1 cherry 348 1.1 cherry ATF_TC(uvm_physseg_free_atboot_mismatch); 349 1.1 cherry ATF_TC_HEAD(uvm_physseg_free_atboot_mismatch, tc) 350 1.1 cherry { 351 1.1 cherry atf_tc_set_md_var(tc, "descr", "boot time uvm_physseg_free() sanity" 352 1.1 cherry "size mismatch free() test."); 353 1.1 cherry } 354 1.1 cherry 355 1.1 cherry ATF_TC_BODY(uvm_physseg_free_atboot_mismatch, tc) 356 1.1 cherry { 357 1.1 cherry uvm.page_init_done = false; 358 1.1 cherry 359 1.1 cherry atf_tc_expect_signal(SIGABRT, "size mismatch free()"); 360 1.1 cherry 361 1.1 cherry uvm_physseg_free(&uvm_physseg[0], sizeof(struct uvm_physseg) - 1); 362 1.1 cherry } 363 1.1 cherry 364 1.1 cherry ATF_TC(uvm_physseg_free_sanity); 365 1.1 cherry ATF_TC_HEAD(uvm_physseg_free_sanity, tc) 366 1.1 cherry { 367 1.1 cherry atf_tc_set_md_var(tc, "descr", "further uvm_physseg_free() sanity checks"); 368 1.1 cherry } 369 1.1 cherry 370 1.1 cherry ATF_TC_BODY(uvm_physseg_free_sanity, tc) 371 1.1 cherry { 372 1.1 cherry 373 1.1 cherry /* At boot time */ 374 1.1 cherry uvm.page_init_done = false; 375 1.1 cherry 376 1.1 cherry struct uvm_physseg *seg; 377 1.1 cherry 378 1.1 cherry #if VM_PHYSSEG_MAX > 1 379 1.1 cherry /* 380 1.1 cherry * Note: free()ing the entire array is considered to be an 381 1.1 cherry * error. Thus VM_PHYSSEG_MAX - 1. 382 1.1 cherry */ 383 1.1 cherry 384 1.1 cherry seg = uvm_physseg_alloc((VM_PHYSSEG_MAX - 1) * sizeof(*seg)); 385 1.1 cherry uvm_physseg_free(seg, (VM_PHYSSEG_MAX - 1) * sizeof(struct uvm_physseg)); 386 1.1 cherry #endif 387 1.1 cherry 388 1.1 cherry /* Retry static alloc()s as dynamic - we expect them to pass */ 389 1.1 cherry uvm.page_init_done = true; 390 1.1 cherry 391 1.1 cherry seg = uvm_physseg_alloc(sizeof(struct uvm_physseg) - 1); 392 1.1 cherry uvm_physseg_free(seg, sizeof(struct uvm_physseg) - 1); 393 1.1 cherry 394 1.1 cherry seg = uvm_physseg_alloc(2 * VM_PHYSSEG_MAX * sizeof(struct uvm_physseg)); 395 1.1 cherry 396 1.1 cherry uvm_physseg_free(seg, 2 * VM_PHYSSEG_MAX * sizeof(struct uvm_physseg)); 397 1.1 cherry } 398 1.1 cherry 399 1.1 cherry #if VM_PHYSSEG_MAX > 1 400 1.1 cherry ATF_TC(uvm_physseg_atboot_free_leak); 401 1.1 cherry ATF_TC_HEAD(uvm_physseg_atboot_free_leak, tc) 402 1.1 cherry { 403 1.1 cherry atf_tc_set_md_var(tc, "descr", 404 1.7 fox "does free() leak at boot ?" 405 1.1 cherry "This test needs VM_PHYSSEG_MAX > 1)"); 406 1.1 cherry } 407 1.1 cherry 408 1.1 cherry ATF_TC_BODY(uvm_physseg_atboot_free_leak, tc) 409 1.1 cherry { 410 1.1 cherry 411 1.1 cherry /* At boot time */ 412 1.1 cherry uvm.page_init_done = false; 413 1.1 cherry 414 1.1 cherry /* alloc to array size */ 415 1.1 cherry struct uvm_physseg *seg; 416 1.1 cherry seg = uvm_physseg_alloc(VM_PHYSSEG_MAX * sizeof(*seg)); 417 1.1 cherry 418 1.1 cherry uvm_physseg_free(seg, sizeof(*seg)); 419 1.1 cherry 420 1.1 cherry atf_tc_expect_signal(SIGABRT, "array overrun on alloc() after leak"); 421 1.1 cherry 422 1.1 cherry ATF_REQUIRE(uvm_physseg_alloc(sizeof(struct uvm_physseg))); 423 1.1 cherry } 424 1.1 cherry #endif /* VM_PHYSSEG_MAX */ 425 1.1 cherry #endif /* UVM_HOTPLUG */ 426 1.1 cherry 427 1.1 cherry /* 428 1.1 cherry * Note: This function replicates verbatim what happens in 429 1.1 cherry * uvm_page.c:uvm_page_init(). 430 1.1 cherry * 431 1.1 cherry * Please track any changes that happen there. 432 1.1 cherry */ 433 1.1 cherry static void 434 1.1 cherry uvm_page_init_fake(struct vm_page *pagearray, psize_t pagecount) 435 1.1 cherry { 436 1.1 cherry uvm_physseg_t bank; 437 1.1 cherry size_t n; 438 1.1 cherry 439 1.1 cherry for (bank = uvm_physseg_get_first(), 440 1.1 cherry uvm_physseg_seg_chomp_slab(bank, pagearray, pagecount); 441 1.2 cherry uvm_physseg_valid_p(bank); 442 1.1 cherry bank = uvm_physseg_get_next(bank)) { 443 1.1 cherry 444 1.1 cherry n = uvm_physseg_get_end(bank) - uvm_physseg_get_start(bank); 445 1.1 cherry uvm_physseg_seg_alloc_from_slab(bank, n); 446 1.1 cherry uvm_physseg_init_seg(bank, pagearray); 447 1.1 cherry 448 1.1 cherry /* set up page array pointers */ 449 1.1 cherry pagearray += n; 450 1.1 cherry pagecount -= n; 451 1.1 cherry } 452 1.1 cherry 453 1.1 cherry uvm.page_init_done = true; 454 1.1 cherry } 455 1.1 cherry 456 1.1 cherry ATF_TC(uvm_physseg_plug); 457 1.1 cherry ATF_TC_HEAD(uvm_physseg_plug, tc) 458 1.1 cherry { 459 1.1 cherry atf_tc_set_md_var(tc, "descr", 460 1.1 cherry "Test plug functionality."); 461 1.1 cherry } 462 1.1 cherry /* Note: We only do the second boot time plug if VM_PHYSSEG_MAX > 1 */ 463 1.1 cherry ATF_TC_BODY(uvm_physseg_plug, tc) 464 1.1 cherry { 465 1.1 cherry int nentries = 0; /* Count of entries via plug done so far */ 466 1.1 cherry uvm_physseg_t upm1; 467 1.1 cherry #if VM_PHYSSEG_MAX > 2 468 1.1 cherry uvm_physseg_t upm2; 469 1.1 cherry #endif 470 1.1 cherry 471 1.1 cherry #if VM_PHYSSEG_MAX > 1 472 1.1 cherry uvm_physseg_t upm3; 473 1.1 cherry #endif 474 1.1 cherry uvm_physseg_t upm4; 475 1.1 cherry psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); 476 1.1 cherry psize_t npages2 = (VALID_END_PFN_2 - VALID_START_PFN_2); 477 1.1 cherry psize_t npages3 = (VALID_END_PFN_3 - VALID_START_PFN_3); 478 1.1 cherry psize_t npages4 = (VALID_END_PFN_4 - VALID_START_PFN_4); 479 1.1 cherry struct vm_page *pgs, *slab = malloc(sizeof(struct vm_page) * (npages1 480 1.1 cherry #if VM_PHYSSEG_MAX > 2 481 1.1 cherry + npages2 482 1.1 cherry #endif 483 1.1 cherry + npages3)); 484 1.1 cherry 485 1.1 cherry /* Fake early boot */ 486 1.1 cherry 487 1.1 cherry setup(); 488 1.1 cherry 489 1.1 cherry /* Vanilla plug x 2 */ 490 1.1 cherry ATF_REQUIRE_EQ(uvm_physseg_plug(VALID_START_PFN_1, npages1, &upm1), true); 491 1.1 cherry ATF_REQUIRE_EQ(++nentries, uvm_physseg_get_entries()); 492 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 493 1.1 cherry 494 1.1 cherry #if VM_PHYSSEG_MAX > 2 495 1.1 cherry ATF_REQUIRE_EQ(uvm_physseg_plug(VALID_START_PFN_2, npages2, &upm2), true); 496 1.1 cherry ATF_REQUIRE_EQ(++nentries, uvm_physseg_get_entries()); 497 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 498 1.1 cherry #endif 499 1.1 cherry /* Post boot: Fake all segments and pages accounted for. */ 500 1.1 cherry uvm_page_init_fake(slab, npages1 + npages2 + npages3); 501 1.1 cherry 502 1.1 cherry ATF_CHECK_EQ(npages1 503 1.1 cherry #if VM_PHYSSEG_MAX > 2 504 1.1 cherry + npages2 505 1.1 cherry #endif 506 1.4 fox , INT_TO_PSIZE_T(uvmexp.npages)); 507 1.1 cherry #if VM_PHYSSEG_MAX > 1 508 1.1 cherry /* Scavenge plug - goes into the same slab */ 509 1.1 cherry ATF_REQUIRE_EQ(uvm_physseg_plug(VALID_START_PFN_3, npages3, &upm3), true); 510 1.1 cherry ATF_REQUIRE_EQ(++nentries, uvm_physseg_get_entries()); 511 1.1 cherry ATF_REQUIRE_EQ(npages1 512 1.1 cherry #if VM_PHYSSEG_MAX > 2 513 1.1 cherry + npages2 514 1.1 cherry #endif 515 1.5 fox + npages3, INT_TO_PSIZE_T(uvmexp.npages)); 516 1.1 cherry 517 1.1 cherry /* Scavenge plug should fit right in the slab */ 518 1.1 cherry pgs = uvm_physseg_get_pg(upm3, 0); 519 1.1 cherry ATF_REQUIRE(pgs > slab && pgs < (slab + npages1 + npages2 + npages3)); 520 1.1 cherry #endif 521 1.1 cherry /* Hot plug - goes into a brand new slab */ 522 1.1 cherry ATF_REQUIRE_EQ(uvm_physseg_plug(VALID_START_PFN_4, npages4, &upm4), true); 523 1.1 cherry /* The hot plug slab should have nothing to do with the original slab */ 524 1.1 cherry pgs = uvm_physseg_get_pg(upm4, 0); 525 1.6 fox ATF_REQUIRE(pgs < slab || pgs >= (slab + npages1 526 1.1 cherry #if VM_PHYSSEG_MAX > 2 527 1.1 cherry + npages2 528 1.1 cherry #endif 529 1.1 cherry + npages3)); 530 1.1 cherry 531 1.1 cherry } 532 1.1 cherry ATF_TC(uvm_physseg_unplug); 533 1.1 cherry ATF_TC_HEAD(uvm_physseg_unplug, tc) 534 1.1 cherry { 535 1.1 cherry atf_tc_set_md_var(tc, "descr", 536 1.1 cherry "Test unplug functionality."); 537 1.1 cherry } 538 1.1 cherry ATF_TC_BODY(uvm_physseg_unplug, tc) 539 1.1 cherry { 540 1.1 cherry paddr_t pa = 0; 541 1.1 cherry 542 1.1 cherry psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); 543 1.1 cherry psize_t npages2 = (VALID_END_PFN_2 - VALID_START_PFN_2); 544 1.1 cherry psize_t npages3 = (VALID_END_PFN_3 - VALID_START_PFN_3); 545 1.1 cherry 546 1.1 cherry struct vm_page *slab = malloc(sizeof(struct vm_page) * (npages1 + npages2 + npages3)); 547 1.1 cherry 548 1.1 cherry uvm_physseg_t upm; 549 1.1 cherry 550 1.1 cherry /* Boot time */ 551 1.1 cherry setup(); 552 1.1 cherry 553 1.1 cherry /* We start with zero segments */ 554 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_plug(atop(0), atop(ONE_MEGABYTE), NULL)); 555 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 556 1.1 cherry /* Do we have an arbitrary offset in there ? */ 557 1.1 cherry uvm_physseg_find(atop(TWOFIFTYSIX_KILO), &pa); 558 1.1 cherry ATF_REQUIRE_EQ(pa, atop(TWOFIFTYSIX_KILO)); 559 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); /* Boot time sanity */ 560 1.1 cherry 561 1.1 cherry #if VM_PHYSSEG_MAX == 1 562 1.1 cherry /* 563 1.1 cherry * This is the curious case at boot time, of having one 564 1.1 cherry * extent(9) static entry per segment, which means that a 565 1.1 cherry * fragmenting unplug will fail. 566 1.1 cherry */ 567 1.1 cherry atf_tc_expect_signal(SIGABRT, "fragmenting unplug for single segment"); 568 1.1 cherry 569 1.1 cherry /* 570 1.1 cherry * In order to test the fragmenting cases, please set 571 1.1 cherry * VM_PHYSSEG_MAX > 1 572 1.1 cherry */ 573 1.1 cherry #endif 574 1.1 cherry /* Now let's unplug from the middle */ 575 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_unplug(atop(TWOFIFTYSIX_KILO), atop(FIVEONETWO_KILO))); 576 1.1 cherry /* verify that a gap exists at TWOFIFTYSIX_KILO */ 577 1.1 cherry pa = 0; /* reset */ 578 1.1 cherry uvm_physseg_find(atop(TWOFIFTYSIX_KILO), &pa); 579 1.1 cherry ATF_REQUIRE_EQ(pa, 0); 580 1.1 cherry 581 1.1 cherry /* Post boot: Fake all segments and pages accounted for. */ 582 1.1 cherry uvm_page_init_fake(slab, npages1 + npages2 + npages3); 583 1.1 cherry /* Account for the unplug */ 584 1.1 cherry ATF_CHECK_EQ(atop(FIVEONETWO_KILO), uvmexp.npages); 585 1.1 cherry 586 1.1 cherry /* Original entry should fragment into two */ 587 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 588 1.1 cherry 589 1.1 cherry upm = uvm_physseg_find(atop(TWOFIFTYSIX_KILO + FIVEONETWO_KILO), NULL); 590 1.1 cherry 591 1.2 cherry ATF_REQUIRE(uvm_physseg_valid_p(upm)); 592 1.1 cherry 593 1.1 cherry /* Now unplug the tail fragment - should swallow the complete entry */ 594 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_unplug(atop(TWOFIFTYSIX_KILO + FIVEONETWO_KILO), atop(TWOFIFTYSIX_KILO))); 595 1.1 cherry 596 1.1 cherry /* The "swallow" above should have invalidated the handle */ 597 1.2 cherry ATF_REQUIRE_EQ(false, uvm_physseg_valid_p(upm)); 598 1.1 cherry 599 1.1 cherry /* Only the first one is left now */ 600 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 601 1.1 cherry 602 1.1 cherry /* Unplug from the back */ 603 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_unplug(atop(ONETWENTYEIGHT_KILO), atop(ONETWENTYEIGHT_KILO))); 604 1.1 cherry /* Shouldn't change the number of segments */ 605 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 606 1.1 cherry 607 1.1 cherry /* Unplug from the front */ 608 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_unplug(0, atop(SIXTYFOUR_KILO))); 609 1.1 cherry /* Shouldn't change the number of segments */ 610 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 611 1.1 cherry 612 1.1 cherry /* Unplugging the final fragment should fail */ 613 1.1 cherry atf_tc_expect_signal(SIGABRT, "Unplugging the last segment"); 614 1.1 cherry ATF_REQUIRE_EQ(true, uvm_physseg_unplug(atop(SIXTYFOUR_KILO), atop(SIXTYFOUR_KILO))); 615 1.1 cherry } 616 1.1 cherry 617 1.1 cherry 618 1.1 cherry /* <---- end Tests for Internal functions ----> */ 619 1.1 cherry 620 1.1 cherry /* Tests for functions exported via uvm_physseg.h */ 621 1.1 cherry ATF_TC(uvm_physseg_init); 622 1.1 cherry ATF_TC_HEAD(uvm_physseg_init, tc) 623 1.1 cherry { 624 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_init() call\ 625 1.1 cherry initializes the vm_physmem struct which holds the rb_tree."); 626 1.1 cherry } 627 1.1 cherry ATF_TC_BODY(uvm_physseg_init, tc) 628 1.1 cherry { 629 1.1 cherry uvm_physseg_init(); 630 1.1 cherry 631 1.1 cherry ATF_REQUIRE_EQ(0, uvm_physseg_get_entries()); 632 1.1 cherry } 633 1.1 cherry 634 1.1 cherry ATF_TC(uvm_page_physload_preload); 635 1.1 cherry ATF_TC_HEAD(uvm_page_physload_preload, tc) 636 1.1 cherry { 637 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physload() \ 638 1.1 cherry call works without a panic() in a preload scenario."); 639 1.1 cherry } 640 1.1 cherry ATF_TC_BODY(uvm_page_physload_preload, tc) 641 1.1 cherry { 642 1.1 cherry uvm_physseg_t upm; 643 1.1 cherry 644 1.1 cherry setup(); 645 1.1 cherry 646 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 647 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 648 1.1 cherry 649 1.1 cherry /* Should return a valid handle */ 650 1.2 cherry ATF_REQUIRE(uvm_physseg_valid_p(upm)); 651 1.1 cherry 652 1.1 cherry /* No pages should be allocated yet */ 653 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 654 1.1 cherry 655 1.1 cherry /* After the first call one segment should exist */ 656 1.1 cherry ATF_CHECK_EQ(1, uvm_physseg_get_entries()); 657 1.1 cherry 658 1.1 cherry /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */ 659 1.1 cherry #if VM_PHYSSEG_MAX > 1 660 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 661 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 662 1.1 cherry 663 1.1 cherry /* Should return a valid handle */ 664 1.2 cherry ATF_REQUIRE(uvm_physseg_valid_p(upm)); 665 1.1 cherry 666 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 667 1.1 cherry 668 1.1 cherry /* After the second call two segments should exist */ 669 1.1 cherry ATF_CHECK_EQ(2, uvm_physseg_get_entries()); 670 1.1 cherry #endif 671 1.1 cherry } 672 1.1 cherry 673 1.1 cherry ATF_TC(uvm_page_physload_postboot); 674 1.1 cherry ATF_TC_HEAD(uvm_page_physload_postboot, tc) 675 1.1 cherry { 676 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physload() \ 677 1.1 cherry panic()s in a post boot scenario."); 678 1.1 cherry } 679 1.1 cherry ATF_TC_BODY(uvm_page_physload_postboot, tc) 680 1.1 cherry { 681 1.1 cherry uvm_physseg_t upm; 682 1.1 cherry 683 1.1 cherry psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); 684 1.1 cherry psize_t npages2 = (VALID_END_PFN_2 - VALID_START_PFN_2); 685 1.1 cherry 686 1.1 cherry struct vm_page *slab = malloc(sizeof(struct vm_page) * (npages1 + npages2)); 687 1.1 cherry 688 1.1 cherry setup(); 689 1.1 cherry 690 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 691 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 692 1.1 cherry 693 1.1 cherry /* Should return a valid handle */ 694 1.2 cherry ATF_REQUIRE(uvm_physseg_valid_p(upm)); 695 1.1 cherry 696 1.1 cherry /* No pages should be allocated yet */ 697 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 698 1.1 cherry 699 1.1 cherry /* After the first call one segment should exist */ 700 1.1 cherry ATF_CHECK_EQ(1, uvm_physseg_get_entries()); 701 1.1 cherry 702 1.1 cherry /* Post boot: Fake all segments and pages accounted for. */ 703 1.1 cherry uvm_page_init_fake(slab, npages1 + npages2); 704 1.1 cherry 705 1.1 cherry atf_tc_expect_signal(SIGABRT, 706 1.1 cherry "uvm_page_physload() called post boot"); 707 1.1 cherry 708 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 709 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 710 1.1 cherry 711 1.1 cherry /* Should return a valid handle */ 712 1.2 cherry ATF_REQUIRE(uvm_physseg_valid_p(upm)); 713 1.1 cherry 714 1.4 fox ATF_REQUIRE_EQ(npages1 + npages2, INT_TO_PSIZE_T(uvmexp.npages)); 715 1.1 cherry 716 1.1 cherry /* After the second call two segments should exist */ 717 1.1 cherry ATF_CHECK_EQ(2, uvm_physseg_get_entries()); 718 1.1 cherry } 719 1.1 cherry 720 1.1 cherry ATF_TC(uvm_physseg_handle_immutable); 721 1.1 cherry ATF_TC_HEAD(uvm_physseg_handle_immutable, tc) 722 1.1 cherry { 723 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the uvm_physseg_t handle is \ 724 1.1 cherry immutable."); 725 1.1 cherry } 726 1.1 cherry ATF_TC_BODY(uvm_physseg_handle_immutable, tc) 727 1.1 cherry { 728 1.1 cherry uvm_physseg_t upm; 729 1.1 cherry 730 1.1 cherry /* We insert the segments in out of order */ 731 1.1 cherry 732 1.1 cherry setup(); 733 1.1 cherry 734 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 735 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 736 1.1 cherry 737 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 738 1.1 cherry 739 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 740 1.1 cherry 741 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID_EMPTY, uvm_physseg_get_prev(upm)); 742 1.1 cherry 743 1.1 cherry /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */ 744 1.1 cherry #if VM_PHYSSEG_MAX > 1 745 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 746 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 747 1.1 cherry 748 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 749 1.1 cherry 750 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 751 1.1 cherry 752 1.1 cherry /* Fetch Previous, we inserted a lower value */ 753 1.1 cherry upm = uvm_physseg_get_prev(upm); 754 1.1 cherry 755 1.1 cherry #if !defined(UVM_HOTPLUG) 756 1.1 cherry /* 757 1.1 cherry * This test is going to fail for the Array Implementation but is 758 1.1 cherry * expected to pass in the RB Tree implementation. 759 1.1 cherry */ 760 1.1 cherry /* Failure can be expected iff there are more than one handles */ 761 1.1 cherry atf_tc_expect_fail("Mutable handle in static array impl."); 762 1.1 cherry #endif 763 1.1 cherry ATF_CHECK(UVM_PHYSSEG_TYPE_INVALID_EMPTY != upm); 764 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm)); 765 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm)); 766 1.1 cherry #endif 767 1.1 cherry } 768 1.1 cherry 769 1.1 cherry ATF_TC(uvm_physseg_seg_chomp_slab); 770 1.1 cherry ATF_TC_HEAD(uvm_physseg_seg_chomp_slab, tc) 771 1.1 cherry { 772 1.1 cherry atf_tc_set_md_var(tc, "descr", "The slab import code.()"); 773 1.1 cherry 774 1.1 cherry } 775 1.1 cherry ATF_TC_BODY(uvm_physseg_seg_chomp_slab, tc) 776 1.1 cherry { 777 1.1 cherry int err; 778 1.1 cherry size_t i; 779 1.1 cherry struct uvm_physseg *seg; 780 1.1 cherry struct vm_page *slab, *pgs; 781 1.1 cherry const size_t npages = UVM_PHYSSEG_BOOT_UNPLUG_MAX; /* Number of pages */ 782 1.1 cherry 783 1.1 cherry setup(); 784 1.1 cherry 785 1.1 cherry /* This is boot time */ 786 1.1 cherry slab = malloc(sizeof(struct vm_page) * npages * 2); 787 1.1 cherry 788 1.1 cherry seg = uvm_physseg_alloc(sizeof(struct uvm_physseg)); 789 1.1 cherry 790 1.1 cherry uvm_physseg_seg_chomp_slab(PHYSSEG_NODE_TO_HANDLE(seg), slab, npages * 2); 791 1.1 cherry 792 1.1 cherry /* Should be able to allocate two 128 * sizeof(*slab) */ 793 1.1 cherry ATF_REQUIRE_EQ(0, extent_alloc(seg->ext, sizeof(*slab), 1, 0, EX_BOUNDZERO, (void *)&pgs)); 794 1.1 cherry err = extent_free(seg->ext, (u_long) pgs, sizeof(*slab), EX_BOUNDZERO); 795 1.1 cherry 796 1.1 cherry #if VM_PHYSSEG_MAX == 1 797 1.1 cherry /* 798 1.1 cherry * free() needs an extra region descriptor, but we only have 799 1.1 cherry * one! The classic alloc() at free() problem 800 1.1 cherry */ 801 1.1 cherry 802 1.1 cherry ATF_REQUIRE_EQ(ENOMEM, err); 803 1.1 cherry #else 804 1.1 cherry /* Try alloc/free at static time */ 805 1.1 cherry for (i = 0; i < npages; i++) { 806 1.1 cherry ATF_REQUIRE_EQ(0, extent_alloc(seg->ext, sizeof(*slab), 1, 0, EX_BOUNDZERO, (void *)&pgs)); 807 1.1 cherry err = extent_free(seg->ext, (u_long) pgs, sizeof(*slab), EX_BOUNDZERO); 808 1.1 cherry ATF_REQUIRE_EQ(0, err); 809 1.1 cherry } 810 1.1 cherry #endif 811 1.1 cherry 812 1.1 cherry /* Now setup post boot */ 813 1.1 cherry uvm.page_init_done = true; 814 1.1 cherry 815 1.1 cherry uvm_physseg_seg_chomp_slab(PHYSSEG_NODE_TO_HANDLE(seg), slab, npages * 2); 816 1.1 cherry 817 1.1 cherry /* Try alloc/free after uvm_page.c:uvm_page_init() as well */ 818 1.1 cherry for (i = 0; i < npages; i++) { 819 1.1 cherry ATF_REQUIRE_EQ(0, extent_alloc(seg->ext, sizeof(*slab), 1, 0, EX_BOUNDZERO, (void *)&pgs)); 820 1.1 cherry err = extent_free(seg->ext, (u_long) pgs, sizeof(*slab), EX_BOUNDZERO); 821 1.1 cherry ATF_REQUIRE_EQ(0, err); 822 1.1 cherry } 823 1.1 cherry 824 1.1 cherry } 825 1.1 cherry 826 1.1 cherry ATF_TC(uvm_physseg_alloc_from_slab); 827 1.1 cherry ATF_TC_HEAD(uvm_physseg_alloc_from_slab, tc) 828 1.1 cherry { 829 1.1 cherry atf_tc_set_md_var(tc, "descr", "The slab alloc code.()"); 830 1.1 cherry 831 1.1 cherry } 832 1.1 cherry ATF_TC_BODY(uvm_physseg_alloc_from_slab, tc) 833 1.1 cherry { 834 1.1 cherry struct uvm_physseg *seg; 835 1.1 cherry struct vm_page *slab, *pgs; 836 1.1 cherry const size_t npages = UVM_PHYSSEG_BOOT_UNPLUG_MAX; /* Number of pages */ 837 1.1 cherry 838 1.1 cherry setup(); 839 1.1 cherry 840 1.1 cherry /* This is boot time */ 841 1.1 cherry slab = malloc(sizeof(struct vm_page) * npages * 2); 842 1.1 cherry 843 1.1 cherry seg = uvm_physseg_alloc(sizeof(struct uvm_physseg)); 844 1.1 cherry 845 1.1 cherry uvm_physseg_seg_chomp_slab(PHYSSEG_NODE_TO_HANDLE(seg), slab, npages * 2); 846 1.1 cherry 847 1.1 cherry pgs = uvm_physseg_seg_alloc_from_slab(PHYSSEG_NODE_TO_HANDLE(seg), npages); 848 1.1 cherry 849 1.1 cherry ATF_REQUIRE(pgs != NULL); 850 1.1 cherry 851 1.1 cherry /* Now setup post boot */ 852 1.1 cherry uvm.page_init_done = true; 853 1.1 cherry 854 1.1 cherry #if VM_PHYSSEG_MAX > 1 855 1.1 cherry pgs = uvm_physseg_seg_alloc_from_slab(PHYSSEG_NODE_TO_HANDLE(seg), npages); 856 1.1 cherry ATF_REQUIRE(pgs != NULL); 857 1.1 cherry #endif 858 1.1 cherry atf_tc_expect_fail("alloc beyond extent"); 859 1.1 cherry 860 1.1 cherry pgs = uvm_physseg_seg_alloc_from_slab(PHYSSEG_NODE_TO_HANDLE(seg), npages); 861 1.1 cherry ATF_REQUIRE(pgs != NULL); 862 1.1 cherry } 863 1.1 cherry 864 1.1 cherry ATF_TC(uvm_physseg_init_seg); 865 1.1 cherry ATF_TC_HEAD(uvm_physseg_init_seg, tc) 866 1.1 cherry { 867 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if uvm_physseg_init_seg adds pages to" 868 1.1 cherry "uvmexp.npages"); 869 1.1 cherry } 870 1.1 cherry ATF_TC_BODY(uvm_physseg_init_seg, tc) 871 1.1 cherry { 872 1.1 cherry struct uvm_physseg *seg; 873 1.1 cherry struct vm_page *slab, *pgs; 874 1.1 cherry const size_t npages = UVM_PHYSSEG_BOOT_UNPLUG_MAX; /* Number of pages */ 875 1.1 cherry 876 1.1 cherry setup(); 877 1.1 cherry 878 1.1 cherry /* This is boot time */ 879 1.1 cherry slab = malloc(sizeof(struct vm_page) * npages * 2); 880 1.1 cherry 881 1.1 cherry seg = uvm_physseg_alloc(sizeof(struct uvm_physseg)); 882 1.1 cherry 883 1.1 cherry uvm_physseg_seg_chomp_slab(PHYSSEG_NODE_TO_HANDLE(seg), slab, npages * 2); 884 1.1 cherry 885 1.1 cherry pgs = uvm_physseg_seg_alloc_from_slab(PHYSSEG_NODE_TO_HANDLE(seg), npages); 886 1.1 cherry 887 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 888 1.1 cherry 889 1.1 cherry seg->start = 0; 890 1.1 cherry seg->end = npages; 891 1.1 cherry 892 1.1 cherry seg->avail_start = 0; 893 1.1 cherry seg->avail_end = npages; 894 1.1 cherry 895 1.1 cherry uvm_physseg_init_seg(PHYSSEG_NODE_TO_HANDLE(seg), pgs); 896 1.1 cherry 897 1.4 fox ATF_REQUIRE_EQ(npages, INT_TO_PSIZE_T(uvmexp.npages)); 898 1.1 cherry } 899 1.1 cherry 900 1.1 cherry #if 0 901 1.1 cherry ATF_TC(uvm_physseg_init_seg); 902 1.1 cherry ATF_TC_HEAD(uvm_physseg_init_seg, tc) 903 1.1 cherry { 904 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physload() \ 905 1.1 cherry call works without a panic() after Segment is inited."); 906 1.1 cherry } 907 1.1 cherry ATF_TC_BODY(uvm_physseg_init_seg, tc) 908 1.1 cherry { 909 1.1 cherry uvm_physseg_t upm; 910 1.1 cherry psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1); 911 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); 912 1.1 cherry 913 1.1 cherry setup(); 914 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 915 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 916 1.1 cherry 917 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 918 1.1 cherry 919 1.1 cherry ATF_CHECK_EQ(0, uvmexp.npages); 920 1.1 cherry 921 1.1 cherry /* 922 1.1 cherry * Boot time physplug needs explicit external init, 923 1.1 cherry * Duplicate what uvm_page.c:uvm_page_init() does. 924 1.1 cherry * Note: not everything uvm_page_init() does gets done here. 925 1.1 cherry * Read the source. 926 1.1 cherry */ 927 1.1 cherry /* suck in backing slab, initialise extent. */ 928 1.1 cherry uvm_physseg_seg_chomp_slab(upm, pgs, npages); 929 1.1 cherry 930 1.1 cherry /* 931 1.1 cherry * Actual pgs[] allocation, from extent. 932 1.1 cherry */ 933 1.1 cherry uvm_physseg_alloc_from_slab(upm, npages); 934 1.1 cherry 935 1.1 cherry /* Now we initialize the segment */ 936 1.1 cherry uvm_physseg_init_seg(upm, pgs); 937 1.1 cherry 938 1.1 cherry /* Done with boot simulation */ 939 1.1 cherry extent_init(); 940 1.1 cherry uvm.page_init_done = true; 941 1.1 cherry 942 1.1 cherry /* We have total memory of 1MB */ 943 1.1 cherry ATF_CHECK_EQ(PAGE_COUNT_1M, uvmexp.npages); 944 1.1 cherry 945 1.1 cherry upm =uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 946 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 947 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 948 1.1 cherry 949 1.1 cherry /* We added another 1MB so PAGE_COUNT_1M + PAGE_COUNT_1M */ 950 1.1 cherry ATF_CHECK_EQ(PAGE_COUNT_1M + PAGE_COUNT_1M, uvmexp.npages); 951 1.1 cherry 952 1.1 cherry } 953 1.1 cherry #endif 954 1.1 cherry 955 1.1 cherry ATF_TC(uvm_physseg_get_start); 956 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_start, tc) 957 1.1 cherry { 958 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the start PFN is returned \ 959 1.1 cherry correctly from a segment created via uvm_page_physload()."); 960 1.1 cherry } 961 1.1 cherry ATF_TC_BODY(uvm_physseg_get_start, tc) 962 1.1 cherry { 963 1.1 cherry uvm_physseg_t upm; 964 1.1 cherry 965 1.1 cherry /* Fake early boot */ 966 1.1 cherry setup(); 967 1.1 cherry 968 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 969 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 970 1.1 cherry 971 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 972 1.1 cherry 973 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 974 1.1 cherry 975 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm)); 976 1.1 cherry 977 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */ 978 1.1 cherry #if VM_PHYSSEG_MAX > 1 979 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 980 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 981 1.1 cherry 982 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 983 1.1 cherry 984 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 985 1.1 cherry 986 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); 987 1.1 cherry #endif 988 1.1 cherry } 989 1.1 cherry 990 1.1 cherry ATF_TC(uvm_physseg_get_start_invalid); 991 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_start_invalid, tc) 992 1.1 cherry { 993 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \ 994 1.1 cherry correctly when uvm_physseg_get_start() is called with invalid \ 995 1.1 cherry parameter values."); 996 1.1 cherry } 997 1.1 cherry ATF_TC_BODY(uvm_physseg_get_start_invalid, tc) 998 1.1 cherry { 999 1.1 cherry /* Check for pgs == NULL */ 1000 1.1 cherry setup(); 1001 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1002 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1003 1.1 cherry 1004 1.1 cherry /* Force other check conditions */ 1005 1.1 cherry uvm.page_init_done = true; 1006 1.1 cherry 1007 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1008 1.1 cherry 1009 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1010 1.1 cherry 1011 1.1 cherry ATF_REQUIRE_EQ(true, uvm.page_init_done); 1012 1.1 cherry 1013 1.1 cherry /* Invalid uvm_physseg_t */ 1014 1.1 cherry ATF_CHECK_EQ((paddr_t) -1, 1015 1.1 cherry uvm_physseg_get_start(UVM_PHYSSEG_TYPE_INVALID)); 1016 1.1 cherry } 1017 1.1 cherry 1018 1.1 cherry ATF_TC(uvm_physseg_get_end); 1019 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_end, tc) 1020 1.1 cherry { 1021 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the end PFN is returned \ 1022 1.1 cherry correctly from a segment created via uvm_page_physload()."); 1023 1.1 cherry } 1024 1.1 cherry ATF_TC_BODY(uvm_physseg_get_end, tc) 1025 1.1 cherry { 1026 1.1 cherry uvm_physseg_t upm; 1027 1.1 cherry 1028 1.1 cherry setup(); 1029 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1030 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1031 1.1 cherry 1032 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1033 1.1 cherry 1034 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1035 1.1 cherry 1036 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm)); 1037 1.1 cherry 1038 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */ 1039 1.1 cherry #if VM_PHYSSEG_MAX > 1 1040 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 1041 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 1042 1.1 cherry 1043 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 1044 1.1 cherry 1045 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1046 1.1 cherry 1047 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); 1048 1.1 cherry #endif 1049 1.1 cherry } 1050 1.1 cherry 1051 1.1 cherry ATF_TC(uvm_physseg_get_end_invalid); 1052 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_end_invalid, tc) 1053 1.1 cherry { 1054 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \ 1055 1.1 cherry correctly when uvm_physseg_get_end() is called with invalid \ 1056 1.1 cherry parameter values."); 1057 1.1 cherry } 1058 1.1 cherry ATF_TC_BODY(uvm_physseg_get_end_invalid, tc) 1059 1.1 cherry { 1060 1.1 cherry /* Check for pgs == NULL */ 1061 1.1 cherry setup(); 1062 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1063 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1064 1.1 cherry 1065 1.1 cherry /* Force other check conditions */ 1066 1.1 cherry uvm.page_init_done = true; 1067 1.1 cherry 1068 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1069 1.1 cherry 1070 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1071 1.1 cherry 1072 1.1 cherry ATF_REQUIRE_EQ(true, uvm.page_init_done); 1073 1.1 cherry 1074 1.1 cherry /* Invalid uvm_physseg_t */ 1075 1.1 cherry ATF_CHECK_EQ((paddr_t) -1, 1076 1.1 cherry uvm_physseg_get_end(UVM_PHYSSEG_TYPE_INVALID)); 1077 1.1 cherry } 1078 1.1 cherry 1079 1.1 cherry ATF_TC(uvm_physseg_get_avail_start); 1080 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_avail_start, tc) 1081 1.1 cherry { 1082 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the avail_start PFN is \ 1083 1.1 cherry returned correctly from a segment created via uvm_page_physload()."); 1084 1.1 cherry } 1085 1.1 cherry ATF_TC_BODY(uvm_physseg_get_avail_start, tc) 1086 1.1 cherry { 1087 1.1 cherry uvm_physseg_t upm; 1088 1.1 cherry 1089 1.1 cherry setup(); 1090 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1091 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1092 1.1 cherry 1093 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1094 1.1 cherry 1095 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1096 1.1 cherry 1097 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_1, uvm_physseg_get_avail_start(upm)); 1098 1.1 cherry 1099 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */ 1100 1.1 cherry #if VM_PHYSSEG_MAX > 1 1101 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 1102 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 1103 1.1 cherry 1104 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1105 1.1 cherry 1106 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 1107 1.1 cherry 1108 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm)); 1109 1.1 cherry #endif 1110 1.1 cherry } 1111 1.1 cherry 1112 1.1 cherry ATF_TC(uvm_physseg_get_avail_start_invalid); 1113 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_avail_start_invalid, tc) 1114 1.1 cherry { 1115 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \ 1116 1.1 cherry correctly when uvm_physseg_get_avail_start() is called with invalid\ 1117 1.1 cherry parameter values."); 1118 1.1 cherry } 1119 1.1 cherry ATF_TC_BODY(uvm_physseg_get_avail_start_invalid, tc) 1120 1.1 cherry { 1121 1.1 cherry /* Check for pgs == NULL */ 1122 1.1 cherry setup(); 1123 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1124 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1125 1.1 cherry 1126 1.1 cherry /* Force other check conditions */ 1127 1.1 cherry uvm.page_init_done = true; 1128 1.1 cherry 1129 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1130 1.1 cherry 1131 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1132 1.1 cherry 1133 1.1 cherry ATF_REQUIRE_EQ(true, uvm.page_init_done); 1134 1.1 cherry 1135 1.1 cherry /* Invalid uvm_physseg_t */ 1136 1.1 cherry ATF_CHECK_EQ((paddr_t) -1, 1137 1.1 cherry uvm_physseg_get_avail_start(UVM_PHYSSEG_TYPE_INVALID)); 1138 1.1 cherry } 1139 1.1 cherry 1140 1.1 cherry ATF_TC(uvm_physseg_get_avail_end); 1141 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_avail_end, tc) 1142 1.1 cherry { 1143 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the avail_end PFN is \ 1144 1.1 cherry returned correctly from a segment created via uvm_page_physload()."); 1145 1.1 cherry } 1146 1.1 cherry ATF_TC_BODY(uvm_physseg_get_avail_end, tc) 1147 1.1 cherry { 1148 1.1 cherry uvm_physseg_t upm; 1149 1.1 cherry 1150 1.1 cherry setup(); 1151 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1152 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1153 1.1 cherry 1154 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1155 1.1 cherry 1156 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1157 1.1 cherry 1158 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1, uvm_physseg_get_avail_end(upm)); 1159 1.1 cherry 1160 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */ 1161 1.1 cherry #if VM_PHYSSEG_MAX > 1 1162 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 1163 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 1164 1.1 cherry 1165 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 1166 1.1 cherry 1167 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1168 1.1 cherry 1169 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm)); 1170 1.1 cherry #endif 1171 1.1 cherry } 1172 1.1 cherry 1173 1.1 cherry ATF_TC(uvm_physseg_get_avail_end_invalid); 1174 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_avail_end_invalid, tc) 1175 1.1 cherry { 1176 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \ 1177 1.1 cherry correctly when uvm_physseg_get_avail_end() is called with invalid\ 1178 1.1 cherry parameter values."); 1179 1.1 cherry } 1180 1.1 cherry ATF_TC_BODY(uvm_physseg_get_avail_end_invalid, tc) 1181 1.1 cherry { 1182 1.1 cherry /* Check for pgs == NULL */ 1183 1.1 cherry setup(); 1184 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1185 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1186 1.1 cherry 1187 1.1 cherry /* Force other check conditions */ 1188 1.1 cherry uvm.page_init_done = true; 1189 1.1 cherry 1190 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1191 1.1 cherry 1192 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1193 1.1 cherry 1194 1.1 cherry ATF_REQUIRE_EQ(true, uvm.page_init_done); 1195 1.1 cherry 1196 1.1 cherry /* Invalid uvm_physseg_t */ 1197 1.1 cherry ATF_CHECK_EQ((paddr_t) -1, 1198 1.1 cherry uvm_physseg_get_avail_end(UVM_PHYSSEG_TYPE_INVALID)); 1199 1.1 cherry } 1200 1.1 cherry 1201 1.1 cherry ATF_TC(uvm_physseg_get_next); 1202 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_next, tc) 1203 1.1 cherry { 1204 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the pointer values for next \ 1205 1.1 cherry segment using the uvm_physseg_get_next() call."); 1206 1.1 cherry } 1207 1.1 cherry ATF_TC_BODY(uvm_physseg_get_next, tc) 1208 1.1 cherry { 1209 1.1 cherry uvm_physseg_t upm; 1210 1.1 cherry #if VM_PHYSSEG_MAX > 1 1211 1.1 cherry uvm_physseg_t upm_next; 1212 1.1 cherry #endif 1213 1.1 cherry 1214 1.1 cherry /* We insert the segments in ascending order */ 1215 1.1 cherry 1216 1.1 cherry setup(); 1217 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1218 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1219 1.1 cherry 1220 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1221 1.1 cherry 1222 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1223 1.1 cherry 1224 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID_OVERFLOW, 1225 1.1 cherry uvm_physseg_get_next(upm)); 1226 1.1 cherry 1227 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */ 1228 1.1 cherry #if VM_PHYSSEG_MAX > 1 1229 1.1 cherry upm_next = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 1230 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 1231 1.1 cherry 1232 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1233 1.1 cherry 1234 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 1235 1.1 cherry 1236 1.1 cherry upm = uvm_physseg_get_next(upm); /* Fetch Next */ 1237 1.1 cherry 1238 1.1 cherry ATF_CHECK_EQ(upm_next, upm); 1239 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); 1240 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); 1241 1.1 cherry #endif 1242 1.1 cherry 1243 1.1 cherry /* This test will be triggered only if there are 3 or more segments. */ 1244 1.1 cherry #if VM_PHYSSEG_MAX > 2 1245 1.1 cherry upm_next = uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3, 1246 1.1 cherry VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT); 1247 1.1 cherry 1248 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1249 1.1 cherry 1250 1.1 cherry ATF_REQUIRE_EQ(3, uvm_physseg_get_entries()); 1251 1.1 cherry 1252 1.1 cherry upm = uvm_physseg_get_next(upm); /* Fetch Next */ 1253 1.1 cherry 1254 1.1 cherry ATF_CHECK_EQ(upm_next, upm); 1255 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_3, uvm_physseg_get_start(upm)); 1256 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_3, uvm_physseg_get_end(upm)); 1257 1.1 cherry #endif 1258 1.1 cherry } 1259 1.1 cherry 1260 1.1 cherry ATF_TC(uvm_physseg_get_next_invalid); 1261 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_next_invalid, tc) 1262 1.1 cherry { 1263 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \ 1264 1.1 cherry correctly when uvm_physseg_get_next() is called with invalid \ 1265 1.1 cherry parameter values."); 1266 1.1 cherry } 1267 1.1 cherry ATF_TC_BODY(uvm_physseg_get_next_invalid, tc) 1268 1.1 cherry { 1269 1.1 cherry uvm_physseg_t upm = UVM_PHYSSEG_TYPE_INVALID; 1270 1.1 cherry 1271 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID, uvm_physseg_get_next(upm)); 1272 1.1 cherry } 1273 1.1 cherry 1274 1.1 cherry ATF_TC(uvm_physseg_get_prev); 1275 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_prev, tc) 1276 1.1 cherry { 1277 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the pointer values for previous \ 1278 1.1 cherry segment using the uvm_physseg_get_prev() call."); 1279 1.1 cherry } 1280 1.1 cherry ATF_TC_BODY(uvm_physseg_get_prev, tc) 1281 1.1 cherry { 1282 1.1 cherry #if VM_PHYSSEG_MAX > 1 1283 1.1 cherry uvm_physseg_t upm; 1284 1.1 cherry #endif 1285 1.1 cherry uvm_physseg_t upm_prev; 1286 1.1 cherry 1287 1.1 cherry 1288 1.1 cherry setup(); 1289 1.1 cherry upm_prev = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1290 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1291 1.1 cherry 1292 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1293 1.1 cherry 1294 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1295 1.1 cherry 1296 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID_EMPTY, 1297 1.1 cherry uvm_physseg_get_prev(upm_prev)); 1298 1.1 cherry 1299 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */ 1300 1.1 cherry #if VM_PHYSSEG_MAX > 1 1301 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 1302 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 1303 1.1 cherry 1304 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1305 1.1 cherry 1306 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 1307 1.1 cherry 1308 1.1 cherry /* Fetch Previous, we inserted a lower value */ 1309 1.1 cherry upm = uvm_physseg_get_prev(upm); 1310 1.1 cherry 1311 1.1 cherry ATF_CHECK_EQ(upm_prev, upm); 1312 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm)); 1313 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm)); 1314 1.1 cherry #endif 1315 1.1 cherry 1316 1.1 cherry /* This test will be triggered only if there are 3 or more segments. */ 1317 1.1 cherry #if VM_PHYSSEG_MAX > 2 1318 1.1 cherry uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3, 1319 1.1 cherry VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT); 1320 1.1 cherry 1321 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1322 1.1 cherry 1323 1.1 cherry ATF_REQUIRE_EQ(3, uvm_physseg_get_entries()); 1324 1.1 cherry 1325 1.1 cherry /* 1326 1.1 cherry * This will return a UVM_PHYSSEG_TYPE_INVALID_EMPTY we are at the 1327 1.1 cherry * lowest 1328 1.1 cherry */ 1329 1.1 cherry upm = uvm_physseg_get_prev(upm); 1330 1.1 cherry 1331 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID_EMPTY, upm); 1332 1.1 cherry #endif 1333 1.1 cherry } 1334 1.1 cherry 1335 1.1 cherry ATF_TC(uvm_physseg_get_prev_invalid); 1336 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_prev_invalid, tc) 1337 1.1 cherry { 1338 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \ 1339 1.1 cherry correctly when uvm_physseg_get_prev() is called with invalid \ 1340 1.1 cherry parameter values."); 1341 1.1 cherry } 1342 1.1 cherry ATF_TC_BODY(uvm_physseg_get_prev_invalid, tc) 1343 1.1 cherry { 1344 1.1 cherry uvm_physseg_t upm = UVM_PHYSSEG_TYPE_INVALID; 1345 1.1 cherry 1346 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID, uvm_physseg_get_prev(upm)); 1347 1.1 cherry } 1348 1.1 cherry 1349 1.1 cherry ATF_TC(uvm_physseg_get_first); 1350 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_first, tc) 1351 1.1 cherry { 1352 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the pointer values for first \ 1353 1.1 cherry segment (lowest node) using the uvm_physseg_get_first() call."); 1354 1.1 cherry } 1355 1.1 cherry ATF_TC_BODY(uvm_physseg_get_first, tc) 1356 1.1 cherry { 1357 1.1 cherry uvm_physseg_t upm = UVM_PHYSSEG_TYPE_INVALID_EMPTY; 1358 1.1 cherry uvm_physseg_t upm_first; 1359 1.1 cherry 1360 1.1 cherry /* Fake early boot */ 1361 1.1 cherry setup(); 1362 1.1 cherry 1363 1.1 cherry /* No nodes exist */ 1364 1.1 cherry ATF_CHECK_EQ(upm, uvm_physseg_get_first()); 1365 1.1 cherry 1366 1.1 cherry upm_first = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 1367 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 1368 1.1 cherry 1369 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1370 1.1 cherry 1371 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1372 1.1 cherry 1373 1.1 cherry /* Pointer to first should be the least valued node */ 1374 1.1 cherry upm = uvm_physseg_get_first(); 1375 1.1 cherry ATF_CHECK_EQ(upm_first, upm); 1376 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); 1377 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); 1378 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm)); 1379 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm)); 1380 1.1 cherry 1381 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */ 1382 1.1 cherry #if VM_PHYSSEG_MAX > 1 1383 1.1 cherry /* Insert a node of lesser value */ 1384 1.1 cherry upm_first = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1385 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1386 1.1 cherry 1387 1.1 cherry ATF_CHECK_EQ(0, uvmexp.npages); 1388 1.1 cherry 1389 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 1390 1.1 cherry 1391 1.1 cherry /* Pointer to first should be the least valued node */ 1392 1.1 cherry upm = uvm_physseg_get_first(); 1393 1.1 cherry ATF_CHECK_EQ(upm_first, upm); 1394 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm)); 1395 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm)); 1396 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_1, uvm_physseg_get_avail_start(upm)); 1397 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1, uvm_physseg_get_avail_end(upm)); 1398 1.1 cherry #endif 1399 1.1 cherry 1400 1.1 cherry /* This test will be triggered only if there are 3 or more segments. */ 1401 1.1 cherry #if VM_PHYSSEG_MAX > 2 1402 1.1 cherry /* Insert a node of higher value */ 1403 1.1 cherry upm_first =uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3, 1404 1.1 cherry VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT); 1405 1.1 cherry 1406 1.1 cherry ATF_CHECK_EQ(0, uvmexp.npages); 1407 1.1 cherry 1408 1.1 cherry ATF_REQUIRE_EQ(3, uvm_physseg_get_entries()); 1409 1.1 cherry 1410 1.1 cherry /* Pointer to first should be the least valued node */ 1411 1.1 cherry upm = uvm_physseg_get_first(); 1412 1.1 cherry ATF_CHECK(upm_first != upm); 1413 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm)); 1414 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm)); 1415 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_1, uvm_physseg_get_avail_start(upm)); 1416 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1, uvm_physseg_get_avail_end(upm)); 1417 1.1 cherry #endif 1418 1.1 cherry } 1419 1.1 cherry 1420 1.1 cherry ATF_TC(uvm_physseg_get_last); 1421 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_last, tc) 1422 1.1 cherry { 1423 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the pointer values for last \ 1424 1.1 cherry segment using the uvm_physseg_get_last() call."); 1425 1.1 cherry } 1426 1.1 cherry ATF_TC_BODY(uvm_physseg_get_last, tc) 1427 1.1 cherry { 1428 1.1 cherry uvm_physseg_t upm = UVM_PHYSSEG_TYPE_INVALID_EMPTY; 1429 1.1 cherry uvm_physseg_t upm_last; 1430 1.1 cherry 1431 1.1 cherry setup(); 1432 1.1 cherry 1433 1.1 cherry /* No nodes exist */ 1434 1.1 cherry ATF_CHECK_EQ(upm, uvm_physseg_get_last()); 1435 1.1 cherry 1436 1.1 cherry upm_last = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1437 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1438 1.1 cherry 1439 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1440 1.1 cherry 1441 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1442 1.1 cherry 1443 1.1 cherry /* Pointer to last should be the most valued node */ 1444 1.1 cherry upm = uvm_physseg_get_last(); 1445 1.1 cherry ATF_CHECK_EQ(upm_last, upm); 1446 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm)); 1447 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm)); 1448 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_1, uvm_physseg_get_avail_start(upm)); 1449 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1, uvm_physseg_get_avail_end(upm)); 1450 1.1 cherry 1451 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */ 1452 1.1 cherry #if VM_PHYSSEG_MAX > 1 1453 1.1 cherry /* Insert node of greater value */ 1454 1.1 cherry upm_last = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 1455 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 1456 1.1 cherry 1457 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1458 1.1 cherry 1459 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 1460 1.1 cherry 1461 1.1 cherry /* Pointer to last should be the most valued node */ 1462 1.1 cherry upm = uvm_physseg_get_last(); 1463 1.1 cherry ATF_CHECK_EQ(upm_last, upm); 1464 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); 1465 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); 1466 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm)); 1467 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm)); 1468 1.1 cherry #endif 1469 1.1 cherry 1470 1.1 cherry /* This test will be triggered only if there are 3 or more segments. */ 1471 1.1 cherry #if VM_PHYSSEG_MAX > 2 1472 1.1 cherry /* Insert node of greater value */ 1473 1.1 cherry upm_last = uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3, 1474 1.1 cherry VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT); 1475 1.1 cherry 1476 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1477 1.1 cherry 1478 1.1 cherry ATF_REQUIRE_EQ(3, uvm_physseg_get_entries()); 1479 1.1 cherry 1480 1.1 cherry /* Pointer to last should be the most valued node */ 1481 1.1 cherry upm = uvm_physseg_get_last(); 1482 1.1 cherry ATF_CHECK_EQ(upm_last, upm); 1483 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_3, uvm_physseg_get_start(upm)); 1484 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_3, uvm_physseg_get_end(upm)); 1485 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_3, uvm_physseg_get_avail_start(upm)); 1486 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_3, uvm_physseg_get_avail_end(upm)); 1487 1.1 cherry #endif 1488 1.1 cherry } 1489 1.1 cherry 1490 1.1 cherry ATF_TC(uvm_physseg_valid); 1491 1.1 cherry ATF_TC_HEAD(uvm_physseg_valid, tc) 1492 1.1 cherry { 1493 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the pointer value for current \ 1494 1.2 cherry segment is valid using the uvm_physseg_valid_p() call."); 1495 1.1 cherry } 1496 1.1 cherry ATF_TC_BODY(uvm_physseg_valid, tc) 1497 1.1 cherry { 1498 1.1 cherry psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1); 1499 1.1 cherry 1500 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); 1501 1.1 cherry 1502 1.1 cherry uvm_physseg_t upm; 1503 1.1 cherry 1504 1.1 cherry setup(); 1505 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1506 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1507 1.1 cherry 1508 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1509 1.1 cherry 1510 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1511 1.1 cherry 1512 1.1 cherry uvm_physseg_init_seg(upm, pgs); 1513 1.1 cherry 1514 1.1 cherry ATF_REQUIRE_EQ(PAGE_COUNT_1M, uvmexp.npages); 1515 1.1 cherry 1516 1.2 cherry ATF_CHECK_EQ(true, uvm_physseg_valid_p(upm)); 1517 1.1 cherry } 1518 1.1 cherry 1519 1.1 cherry ATF_TC(uvm_physseg_valid_invalid); 1520 1.1 cherry ATF_TC_HEAD(uvm_physseg_valid_invalid, tc) 1521 1.1 cherry { 1522 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests the pointer value for current \ 1523 1.2 cherry segment is invalid using the uvm_physseg_valid_p() call."); 1524 1.1 cherry } 1525 1.1 cherry ATF_TC_BODY(uvm_physseg_valid_invalid, tc) 1526 1.1 cherry { 1527 1.1 cherry uvm_physseg_t upm; 1528 1.1 cherry 1529 1.1 cherry setup(); 1530 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1531 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1532 1.1 cherry 1533 1.1 cherry /* Force other check conditions */ 1534 1.1 cherry uvm.page_init_done = true; 1535 1.1 cherry 1536 1.1 cherry ATF_REQUIRE_EQ(true, uvm.page_init_done); 1537 1.1 cherry 1538 1.1 cherry /* Invalid uvm_physseg_t */ 1539 1.2 cherry ATF_CHECK_EQ(false, uvm_physseg_valid_p(UVM_PHYSSEG_TYPE_INVALID)); 1540 1.1 cherry 1541 1.1 cherry /* 1542 1.1 cherry * Without any pages initialized for segment, it is considered 1543 1.1 cherry * invalid 1544 1.1 cherry */ 1545 1.2 cherry ATF_CHECK_EQ(false, uvm_physseg_valid_p(upm)); 1546 1.1 cherry } 1547 1.1 cherry 1548 1.1 cherry ATF_TC(uvm_physseg_get_highest); 1549 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_highest, tc) 1550 1.1 cherry { 1551 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned PFN matches \ 1552 1.1 cherry the highest PFN in use by the system."); 1553 1.1 cherry } 1554 1.1 cherry ATF_TC_BODY(uvm_physseg_get_highest, tc) 1555 1.1 cherry { 1556 1.1 cherry setup(); 1557 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1558 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1559 1.1 cherry 1560 1.1 cherry /* Only one segment so highest is the current */ 1561 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1 - 1, uvm_physseg_get_highest_frame()); 1562 1.1 cherry 1563 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */ 1564 1.1 cherry #if VM_PHYSSEG_MAX > 1 1565 1.1 cherry uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3, 1566 1.1 cherry VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT); 1567 1.1 cherry 1568 1.1 cherry /* PFN_3 > PFN_1 */ 1569 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_3 - 1, uvm_physseg_get_highest_frame()); 1570 1.1 cherry #endif 1571 1.1 cherry 1572 1.1 cherry /* This test will be triggered only if there are 3 or more segments. */ 1573 1.1 cherry #if VM_PHYSSEG_MAX > 2 1574 1.1 cherry uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 1575 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 1576 1.1 cherry 1577 1.1 cherry /* PFN_3 > PFN_2 */ 1578 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_3 - 1, uvm_physseg_get_highest_frame()); 1579 1.1 cherry #endif 1580 1.1 cherry } 1581 1.1 cherry 1582 1.1 cherry ATF_TC(uvm_physseg_get_free_list); 1583 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_free_list, tc) 1584 1.1 cherry { 1585 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned Free List type \ 1586 1.1 cherry of a segment matches the one returned from \ 1587 1.1 cherry uvm_physseg_get_free_list() call."); 1588 1.1 cherry } 1589 1.1 cherry ATF_TC_BODY(uvm_physseg_get_free_list, tc) 1590 1.1 cherry { 1591 1.1 cherry uvm_physseg_t upm; 1592 1.1 cherry 1593 1.1 cherry /* Fake early boot */ 1594 1.1 cherry setup(); 1595 1.1 cherry 1596 1.1 cherry /* Insertions are made in ascending order */ 1597 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1598 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1599 1.1 cherry 1600 1.1 cherry ATF_CHECK_EQ(VM_FREELIST_DEFAULT, uvm_physseg_get_free_list(upm)); 1601 1.1 cherry 1602 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */ 1603 1.1 cherry #if VM_PHYSSEG_MAX > 1 1604 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 1605 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_FIRST16); 1606 1.1 cherry 1607 1.1 cherry ATF_CHECK_EQ(VM_FREELIST_FIRST16, uvm_physseg_get_free_list(upm)); 1608 1.1 cherry #endif 1609 1.1 cherry 1610 1.1 cherry /* This test will be triggered only if there are 3 or more segments. */ 1611 1.1 cherry #if VM_PHYSSEG_MAX > 2 1612 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3, 1613 1.1 cherry VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_FIRST1G); 1614 1.1 cherry 1615 1.1 cherry ATF_CHECK_EQ(VM_FREELIST_FIRST1G, uvm_physseg_get_free_list(upm)); 1616 1.1 cherry #endif 1617 1.1 cherry } 1618 1.1 cherry 1619 1.1 cherry ATF_TC(uvm_physseg_get_start_hint); 1620 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_start_hint, tc) 1621 1.1 cherry { 1622 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned start_hint value \ 1623 1.1 cherry of a segment matches the one returned from \ 1624 1.1 cherry uvm_physseg_get_start_hint() call."); 1625 1.1 cherry } 1626 1.1 cherry ATF_TC_BODY(uvm_physseg_get_start_hint, tc) 1627 1.1 cherry { 1628 1.1 cherry uvm_physseg_t upm; 1629 1.1 cherry 1630 1.1 cherry setup(); 1631 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1632 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1633 1.1 cherry 1634 1.1 cherry /* Will be Zero since no specific value is set during init */ 1635 1.1 cherry ATF_CHECK_EQ(0, uvm_physseg_get_start_hint(upm)); 1636 1.1 cherry } 1637 1.1 cherry 1638 1.1 cherry ATF_TC(uvm_physseg_set_start_hint); 1639 1.1 cherry ATF_TC_HEAD(uvm_physseg_set_start_hint, tc) 1640 1.1 cherry { 1641 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned start_hint value \ 1642 1.1 cherry of a segment matches the one set by the \ 1643 1.1 cherry uvm_physseg_set_start_hint() call."); 1644 1.1 cherry } 1645 1.1 cherry ATF_TC_BODY(uvm_physseg_set_start_hint, tc) 1646 1.1 cherry { 1647 1.1 cherry psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1); 1648 1.1 cherry 1649 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); 1650 1.1 cherry 1651 1.1 cherry uvm_physseg_t upm; 1652 1.1 cherry 1653 1.1 cherry setup(); 1654 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1655 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1656 1.1 cherry 1657 1.1 cherry uvm_physseg_init_seg(upm, pgs); 1658 1.1 cherry 1659 1.1 cherry ATF_CHECK_EQ(true, uvm_physseg_set_start_hint(upm, atop(128))); 1660 1.1 cherry 1661 1.1 cherry /* Will be atop(128) since no specific value is set above */ 1662 1.1 cherry ATF_CHECK_EQ(atop(128), uvm_physseg_get_start_hint(upm)); 1663 1.1 cherry } 1664 1.1 cherry 1665 1.1 cherry ATF_TC(uvm_physseg_set_start_hint_invalid); 1666 1.1 cherry ATF_TC_HEAD(uvm_physseg_set_start_hint_invalid, tc) 1667 1.1 cherry { 1668 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned value is false \ 1669 1.1 cherry when an invalid segment matches the one trying to set by the \ 1670 1.1 cherry uvm_physseg_set_start_hint() call."); 1671 1.1 cherry } 1672 1.1 cherry ATF_TC_BODY(uvm_physseg_set_start_hint_invalid, tc) 1673 1.1 cherry { 1674 1.1 cherry uvm_physseg_t upm; 1675 1.1 cherry 1676 1.1 cherry setup(); 1677 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1678 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1679 1.1 cherry 1680 1.1 cherry /* Force other check conditions */ 1681 1.1 cherry uvm.page_init_done = true; 1682 1.1 cherry 1683 1.1 cherry ATF_REQUIRE_EQ(true, uvm.page_init_done); 1684 1.1 cherry 1685 1.1 cherry ATF_CHECK_EQ(false, uvm_physseg_set_start_hint(upm, atop(128))); 1686 1.1 cherry 1687 1.1 cherry /* 1688 1.1 cherry * Will be Zero since no specific value is set after the init 1689 1.1 cherry * due to failure 1690 1.1 cherry */ 1691 1.1 cherry atf_tc_expect_signal(SIGABRT, "invalid uvm_physseg_t handle"); 1692 1.1 cherry 1693 1.1 cherry ATF_CHECK_EQ(0, uvm_physseg_get_start_hint(upm)); 1694 1.1 cherry } 1695 1.1 cherry 1696 1.1 cherry ATF_TC(uvm_physseg_get_pg); 1697 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_pg, tc) 1698 1.1 cherry { 1699 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned vm_page struct \ 1700 1.1 cherry is correct when fetched by uvm_physseg_get_pg() call."); 1701 1.1 cherry } 1702 1.1 cherry ATF_TC_BODY(uvm_physseg_get_pg, tc) 1703 1.1 cherry { 1704 1.1 cherry psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1); 1705 1.1 cherry 1706 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); 1707 1.1 cherry 1708 1.1 cherry struct vm_page *extracted_pg = NULL; 1709 1.1 cherry 1710 1.1 cherry uvm_physseg_t upm; 1711 1.1 cherry 1712 1.1 cherry setup(); 1713 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1714 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1715 1.1 cherry 1716 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1717 1.1 cherry 1718 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1719 1.1 cherry 1720 1.1 cherry /* Now we initialize the segment */ 1721 1.1 cherry uvm_physseg_init_seg(upm, pgs); 1722 1.1 cherry 1723 1.1 cherry ATF_REQUIRE_EQ(PAGE_COUNT_1M, uvmexp.npages); 1724 1.1 cherry 1725 1.1 cherry ATF_REQUIRE_EQ(NULL, extracted_pg); 1726 1.1 cherry 1727 1.1 cherry /* Try fetching the 5th Page in the Segment */ 1728 1.1 cherry extracted_pg = uvm_physseg_get_pg(upm, 5); 1729 1.1 cherry 1730 1.1 cherry /* Values of phys_addr is n * PAGE_SIZE where n is the page number */ 1731 1.1 cherry ATF_CHECK_EQ(5 * PAGE_SIZE, extracted_pg->phys_addr); 1732 1.1 cherry 1733 1.1 cherry /* Try fetching the 113th Page in the Segment */ 1734 1.1 cherry extracted_pg = uvm_physseg_get_pg(upm, 113); 1735 1.1 cherry 1736 1.1 cherry ATF_CHECK_EQ(113 * PAGE_SIZE, extracted_pg->phys_addr); 1737 1.1 cherry } 1738 1.1 cherry 1739 1.1 cherry #ifdef __HAVE_PMAP_PHYSSEG 1740 1.1 cherry ATF_TC(uvm_physseg_get_pmseg); 1741 1.1 cherry ATF_TC_HEAD(uvm_physseg_get_pmseg, tc) 1742 1.1 cherry { 1743 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned pmap_physseg \ 1744 1.1 cherry struct is correct when fetched by uvm_physseg_get_pmseg() call."); 1745 1.1 cherry } 1746 1.1 cherry ATF_TC_BODY(uvm_physseg_get_pmseg, tc) 1747 1.1 cherry { 1748 1.1 cherry psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1); 1749 1.1 cherry 1750 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); 1751 1.1 cherry 1752 1.1 cherry struct pmap_physseg pmseg = { true }; 1753 1.1 cherry 1754 1.1 cherry struct pmap_physseg *extracted_pmseg = NULL; 1755 1.1 cherry 1756 1.1 cherry uvm_physseg_t upm; 1757 1.1 cherry 1758 1.1 cherry setup(); 1759 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1760 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1761 1.1 cherry 1762 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1763 1.1 cherry 1764 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1765 1.1 cherry 1766 1.1 cherry /* Now we initialize the segment */ 1767 1.1 cherry uvm_physseg_init_seg(upm, pgs); 1768 1.1 cherry 1769 1.1 cherry ATF_REQUIRE_EQ(PAGE_COUNT_1M, uvmexp.npages); 1770 1.1 cherry 1771 1.1 cherry ATF_REQUIRE_EQ(NULL, extracted_pmseg); 1772 1.1 cherry 1773 1.1 cherry ATF_REQUIRE_EQ(true, pmseg.dummy_variable); 1774 1.1 cherry 1775 1.1 cherry /* Extract the current pmseg */ 1776 1.1 cherry extracted_pmseg = uvm_physseg_get_pmseg(upm); 1777 1.1 cherry 1778 1.1 cherry /* 1779 1.1 cherry * We can only check if it is not NULL 1780 1.1 cherry * We do not know the value it contains 1781 1.1 cherry */ 1782 1.1 cherry ATF_CHECK(NULL != extracted_pmseg); 1783 1.1 cherry 1784 1.1 cherry extracted_pmseg->dummy_variable = pmseg.dummy_variable; 1785 1.1 cherry 1786 1.1 cherry /* Invert value to ensure test integrity */ 1787 1.1 cherry pmseg.dummy_variable = false; 1788 1.1 cherry 1789 1.1 cherry ATF_REQUIRE_EQ(false, pmseg.dummy_variable); 1790 1.1 cherry 1791 1.1 cherry extracted_pmseg = uvm_physseg_get_pmseg(upm); 1792 1.1 cherry 1793 1.1 cherry ATF_CHECK(NULL != extracted_pmseg); 1794 1.1 cherry 1795 1.1 cherry ATF_CHECK_EQ(true, extracted_pmseg->dummy_variable); 1796 1.1 cherry } 1797 1.1 cherry #endif 1798 1.1 cherry 1799 1.1 cherry ATF_TC(vm_physseg_find); 1800 1.1 cherry ATF_TC_HEAD(vm_physseg_find, tc) 1801 1.1 cherry { 1802 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned segment number \ 1803 1.1 cherry is correct when an PFN is passed into uvm_physseg_find() call. \ 1804 1.1 cherry In addition to this the offset of the PFN from the start of \ 1805 1.1 cherry segment is also set if the parameter is passed in as not NULL."); 1806 1.1 cherry } 1807 1.1 cherry ATF_TC_BODY(vm_physseg_find, tc) 1808 1.1 cherry { 1809 1.1 cherry psize_t offset = (psize_t) -1; 1810 1.1 cherry 1811 1.1 cherry uvm_physseg_t upm_first, result; 1812 1.1 cherry #if VM_PHYSSEG_MAX > 1 1813 1.1 cherry uvm_physseg_t upm_second; 1814 1.1 cherry #endif 1815 1.1 cherry 1816 1.1 cherry setup(); 1817 1.1 cherry 1818 1.1 cherry upm_first = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1819 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1820 1.1 cherry 1821 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1822 1.1 cherry 1823 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1824 1.1 cherry 1825 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */ 1826 1.1 cherry #if VM_PHYSSEG_MAX > 1 1827 1.1 cherry upm_second = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 1828 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 1829 1.1 cherry 1830 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 1831 1.1 cherry 1832 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1833 1.1 cherry #endif 1834 1.1 cherry 1835 1.1 cherry /* Under ONE_MEGABYTE is segment upm_first */ 1836 1.1 cherry result = uvm_physseg_find(atop(ONE_MEGABYTE - 1024), NULL); 1837 1.1 cherry ATF_CHECK_EQ(upm_first, result); 1838 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_start(upm_first), 1839 1.1 cherry uvm_physseg_get_start(result)); 1840 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_end(upm_first), 1841 1.1 cherry uvm_physseg_get_end(result)); 1842 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_avail_start(upm_first), 1843 1.1 cherry uvm_physseg_get_avail_start(result)); 1844 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_avail_end(upm_first), 1845 1.1 cherry uvm_physseg_get_avail_end(result)); 1846 1.1 cherry 1847 1.1 cherry ATF_REQUIRE_EQ((psize_t) -1, offset); 1848 1.1 cherry 1849 1.1 cherry /* This test will be triggered only if there are 2 or more segments. */ 1850 1.1 cherry #if VM_PHYSSEG_MAX > 1 1851 1.1 cherry /* Over ONE_MEGABYTE is segment upm_second */ 1852 1.1 cherry result = uvm_physseg_find(atop(ONE_MEGABYTE + 8192), &offset); 1853 1.1 cherry ATF_CHECK_EQ(upm_second, result); 1854 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_start(upm_second), 1855 1.1 cherry uvm_physseg_get_start(result)); 1856 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_end(upm_second), 1857 1.1 cherry uvm_physseg_get_end(result)); 1858 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_avail_start(upm_second), 1859 1.1 cherry uvm_physseg_get_avail_start(result)); 1860 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_avail_end(upm_second), 1861 1.1 cherry uvm_physseg_get_avail_end(result)); 1862 1.1 cherry 1863 1.1 cherry /* Offset is calculated based on PAGE_SIZE */ 1864 1.1 cherry /* atop(ONE_MEGABYTE + (2 * PAGE_SIZE)) - VALID_START_PFN1 = 2 */ 1865 1.1 cherry ATF_CHECK_EQ(2, offset); 1866 1.1 cherry #else 1867 1.1 cherry /* Under ONE_MEGABYTE is segment upm_first */ 1868 1.1 cherry result = uvm_physseg_find(atop(ONE_MEGABYTE - 12288), &offset); 1869 1.1 cherry ATF_CHECK_EQ(upm_first, result); 1870 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_start(upm_first), 1871 1.1 cherry uvm_physseg_get_start(result)); 1872 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_end(upm_first), 1873 1.1 cherry uvm_physseg_get_end(result)); 1874 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_avail_start(upm_first), 1875 1.1 cherry uvm_physseg_get_avail_start(result)); 1876 1.1 cherry ATF_CHECK_EQ(uvm_physseg_get_avail_end(upm_first), 1877 1.1 cherry uvm_physseg_get_avail_end(result)); 1878 1.1 cherry 1879 1.1 cherry /* Offset is calculated based on PAGE_SIZE */ 1880 1.1 cherry /* atop(ONE_MEGABYTE - (3 * PAGE_SIZE)) - VALID_START_PFN1 = 253 */ 1881 1.1 cherry ATF_CHECK_EQ(253, offset); 1882 1.1 cherry #endif 1883 1.1 cherry } 1884 1.1 cherry 1885 1.1 cherry ATF_TC(vm_physseg_find_invalid); 1886 1.1 cherry ATF_TC_HEAD(vm_physseg_find_invalid, tc) 1887 1.1 cherry { 1888 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the returned segment number \ 1889 1.10 andvar is (paddr_t) -1 when a non-existent PFN is passed into \ 1890 1.1 cherry uvm_physseg_find() call."); 1891 1.1 cherry } 1892 1.1 cherry ATF_TC_BODY(vm_physseg_find_invalid, tc) 1893 1.1 cherry { 1894 1.1 cherry psize_t offset = (psize_t) -1; 1895 1.1 cherry 1896 1.1 cherry setup(); 1897 1.1 cherry uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 1898 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 1899 1.1 cherry 1900 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1901 1.1 cherry 1902 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1903 1.1 cherry 1904 1.1 cherry /* No segments over 3 MB exists at the moment */ 1905 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID, 1906 1.1 cherry uvm_physseg_find(atop(ONE_MEGABYTE * 3), NULL)); 1907 1.1 cherry 1908 1.1 cherry ATF_REQUIRE_EQ((psize_t) -1, offset); 1909 1.1 cherry 1910 1.1 cherry /* No segments over 3 MB exists at the moment */ 1911 1.1 cherry ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID, 1912 1.1 cherry uvm_physseg_find(atop(ONE_MEGABYTE * 3), &offset)); 1913 1.1 cherry 1914 1.1 cherry ATF_CHECK_EQ((psize_t) -1, offset); 1915 1.1 cherry } 1916 1.1 cherry 1917 1.1 cherry ATF_TC(uvm_page_physunload_start); 1918 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_start, tc) 1919 1.1 cherry { 1920 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physunload()\ 1921 1.1 cherry call works without a panic(). Unloads from Start of the segment."); 1922 1.1 cherry } 1923 1.1 cherry ATF_TC_BODY(uvm_page_physunload_start, tc) 1924 1.1 cherry { 1925 1.1 cherry /* 1926 1.1 cherry * Would uvmexp.npages reduce everytime an uvm_page_physunload is called? 1927 1.1 cherry */ 1928 1.1 cherry psize_t npages = (VALID_END_PFN_2 - VALID_START_PFN_2); 1929 1.1 cherry 1930 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); 1931 1.1 cherry 1932 1.1 cherry paddr_t p = 0; 1933 1.1 cherry 1934 1.1 cherry uvm_physseg_t upm; 1935 1.1 cherry 1936 1.1 cherry setup(); 1937 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 1938 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 1939 1.1 cherry 1940 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1941 1.1 cherry 1942 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1943 1.1 cherry 1944 1.1 cherry uvm_physseg_init_seg(upm, pgs); 1945 1.1 cherry 1946 1.1 cherry ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p)); 1947 1.1 cherry 1948 1.1 cherry /* 1949 1.1 cherry * When called for first time, uvm_page_physload() removes the first PFN 1950 1.1 cherry * 1951 1.1 cherry * New avail start will be VALID_AVAIL_START_PFN_2 + 1 1952 1.1 cherry */ 1953 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, atop(p)); 1954 1.1 cherry 1955 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2 + 1, 1956 1.1 cherry uvm_physseg_get_avail_start(upm)); 1957 1.1 cherry 1958 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2 + 1, uvm_physseg_get_start(upm)); 1959 1.1 cherry 1960 1.1 cherry /* Rest of the stuff should remain the same */ 1961 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); 1962 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm)); 1963 1.1 cherry } 1964 1.1 cherry 1965 1.1 cherry ATF_TC(uvm_page_physunload_end); 1966 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_end, tc) 1967 1.1 cherry { 1968 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physunload()\ 1969 1.1 cherry call works without a panic(). Unloads from End of the segment."); 1970 1.1 cherry } 1971 1.1 cherry ATF_TC_BODY(uvm_page_physunload_end, tc) 1972 1.1 cherry { 1973 1.1 cherry /* 1974 1.1 cherry * Would uvmexp.npages reduce everytime an uvm_page_physunload is called? 1975 1.1 cherry */ 1976 1.1 cherry paddr_t p = 0; 1977 1.1 cherry 1978 1.1 cherry uvm_physseg_t upm; 1979 1.1 cherry 1980 1.1 cherry setup(); 1981 1.1 cherry /* Note: start != avail_start to remove from end. */ 1982 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 1983 1.1 cherry VALID_AVAIL_START_PFN_2 + 1, VALID_AVAIL_END_PFN_2, 1984 1.1 cherry VM_FREELIST_DEFAULT); 1985 1.1 cherry 1986 1.1 cherry p = 0; 1987 1.1 cherry 1988 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 1989 1.1 cherry 1990 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 1991 1.1 cherry 1992 1.1 cherry ATF_REQUIRE( 1993 1.1 cherry uvm_physseg_get_avail_start(upm) != uvm_physseg_get_start(upm)); 1994 1.1 cherry 1995 1.1 cherry ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p)); 1996 1.1 cherry 1997 1.1 cherry /* 1998 1.1 cherry * Remember if X is the upper limit the actual valid pointer is X - 1 1999 1.1 cherry * 2000 1.1 cherry * For example if 256 is the upper limit for 1MB memory, last valid 2001 1.1 cherry * pointer is 256 - 1 = 255 2002 1.1 cherry */ 2003 1.1 cherry 2004 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2 - 1, atop(p)); 2005 1.1 cherry 2006 1.1 cherry /* 2007 1.1 cherry * When called for second time, uvm_page_physload() removes the last PFN 2008 1.1 cherry * 2009 1.1 cherry * New avail end will be VALID_AVAIL_END_PFN_2 - 1 2010 1.1 cherry * New end will be VALID_AVAIL_PFN_2 - 1 2011 1.1 cherry */ 2012 1.1 cherry 2013 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2 - 1, uvm_physseg_get_avail_end(upm)); 2014 1.1 cherry 2015 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2 - 1, uvm_physseg_get_end(upm)); 2016 1.1 cherry 2017 1.1 cherry /* Rest of the stuff should remain the same */ 2018 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2 + 1, 2019 1.1 cherry uvm_physseg_get_avail_start(upm)); 2020 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); 2021 1.1 cherry } 2022 1.1 cherry 2023 1.1 cherry ATF_TC(uvm_page_physunload_none); 2024 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_none, tc) 2025 1.1 cherry { 2026 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physunload()\ 2027 1.1 cherry call works without a panic(). Does not unload from start or end \ 2028 1.1 cherry because of non-aligned start / avail_start and end / avail_end \ 2029 1.1 cherry respectively."); 2030 1.1 cherry } 2031 1.1 cherry ATF_TC_BODY(uvm_page_physunload_none, tc) 2032 1.1 cherry { 2033 1.1 cherry psize_t npages = (VALID_END_PFN_2 - VALID_START_PFN_2); 2034 1.1 cherry 2035 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); 2036 1.1 cherry 2037 1.1 cherry paddr_t p = 0; 2038 1.1 cherry 2039 1.1 cherry uvm_physseg_t upm; 2040 1.1 cherry 2041 1.1 cherry setup(); 2042 1.1 cherry /* 2043 1.1 cherry * Note: start != avail_start and end != avail_end. 2044 1.1 cherry * 2045 1.3 dholland * This prevents any unload from occurring. 2046 1.1 cherry */ 2047 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 2048 1.1 cherry VALID_AVAIL_START_PFN_2 + 1, VALID_AVAIL_END_PFN_2 - 1, 2049 1.1 cherry VM_FREELIST_DEFAULT); 2050 1.1 cherry 2051 1.1 cherry p = 0; 2052 1.1 cherry 2053 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 2054 1.1 cherry 2055 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 2056 1.1 cherry 2057 1.1 cherry ATF_REQUIRE( 2058 1.1 cherry uvm_physseg_get_avail_start(upm) != uvm_physseg_get_start(upm)); 2059 1.1 cherry 2060 1.1 cherry uvm_physseg_init_seg(upm, pgs); 2061 1.1 cherry 2062 1.1 cherry ATF_CHECK_EQ(false, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p)); 2063 1.1 cherry 2064 1.1 cherry /* uvm_page_physload() will no longer unload memory */ 2065 1.1 cherry ATF_CHECK_EQ(0, p); 2066 1.1 cherry 2067 1.1 cherry /* Rest of the stuff should remain the same */ 2068 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2 + 1, 2069 1.1 cherry uvm_physseg_get_avail_start(upm)); 2070 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2 - 1, 2071 1.1 cherry uvm_physseg_get_avail_end(upm)); 2072 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); 2073 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); 2074 1.1 cherry } 2075 1.1 cherry 2076 1.1 cherry ATF_TC(uvm_page_physunload_delete_start); 2077 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_delete_start, tc) 2078 1.1 cherry { 2079 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the uvm_page_physunload() \ 2080 1.1 cherry works when the segment gets small enough to be deleted scenario. \ 2081 1.1 cherry NOTE: This one works deletes from start."); 2082 1.1 cherry } 2083 1.1 cherry ATF_TC_BODY(uvm_page_physunload_delete_start, tc) 2084 1.1 cherry { 2085 1.1 cherry /* 2086 1.1 cherry * Would uvmexp.npages reduce everytime an uvm_page_physunload is called? 2087 1.1 cherry */ 2088 1.1 cherry paddr_t p = 0; 2089 1.1 cherry 2090 1.1 cherry uvm_physseg_t upm; 2091 1.1 cherry 2092 1.1 cherry setup(); 2093 1.1 cherry 2094 1.1 cherry /* 2095 1.1 cherry * Setup the Nuke from Starting point 2096 1.1 cherry */ 2097 1.1 cherry 2098 1.1 cherry upm = uvm_page_physload(VALID_END_PFN_1 - 1, VALID_END_PFN_1, 2099 1.1 cherry VALID_AVAIL_END_PFN_1 - 1, VALID_AVAIL_END_PFN_1, 2100 1.1 cherry VM_FREELIST_DEFAULT); 2101 1.1 cherry 2102 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 2103 1.1 cherry 2104 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 2105 1.1 cherry 2106 1.1 cherry /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */ 2107 1.1 cherry #if VM_PHYSSEG_MAX > 1 2108 1.1 cherry uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 2109 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 2110 1.1 cherry 2111 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 2112 1.1 cherry #endif 2113 1.1 cherry 2114 1.1 cherry #if VM_PHYSSEG_MAX == 1 2115 1.1 cherry atf_tc_expect_signal(SIGABRT, 2116 1.1 cherry "cannot uvm_page_physunload() the last segment"); 2117 1.1 cherry #endif 2118 1.1 cherry 2119 1.1 cherry ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p)); 2120 1.1 cherry 2121 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_1 - 1, atop(p)); 2122 1.1 cherry 2123 1.1 cherry ATF_CHECK_EQ(1, uvm_physseg_get_entries()); 2124 1.1 cherry 2125 1.1 cherry /* The only node now is the one we inserted second. */ 2126 1.1 cherry upm = uvm_physseg_get_first(); 2127 1.1 cherry 2128 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); 2129 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); 2130 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm)); 2131 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm)); 2132 1.1 cherry } 2133 1.1 cherry 2134 1.1 cherry ATF_TC(uvm_page_physunload_delete_end); 2135 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_delete_end, tc) 2136 1.1 cherry { 2137 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the uvm_page_physunload() \ 2138 1.1 cherry works when the segment gets small enough to be deleted scenario. \ 2139 1.1 cherry NOTE: This one works deletes from end."); 2140 1.1 cherry } 2141 1.1 cherry ATF_TC_BODY(uvm_page_physunload_delete_end, tc) 2142 1.1 cherry { 2143 1.1 cherry /* 2144 1.1 cherry * Would uvmexp.npages reduce everytime an uvm_page_physunload is called? 2145 1.1 cherry */ 2146 1.1 cherry 2147 1.1 cherry paddr_t p = 0; 2148 1.1 cherry 2149 1.1 cherry uvm_physseg_t upm; 2150 1.1 cherry 2151 1.1 cherry setup(); 2152 1.1 cherry 2153 1.1 cherry /* 2154 1.1 cherry * Setup the Nuke from Ending point 2155 1.1 cherry */ 2156 1.1 cherry 2157 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_START_PFN_1 + 2, 2158 1.8 fox VALID_AVAIL_START_PFN_1, VALID_AVAIL_START_PFN_1 + 2, 2159 1.1 cherry VM_FREELIST_DEFAULT); 2160 1.1 cherry 2161 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 2162 1.1 cherry 2163 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 2164 1.1 cherry 2165 1.1 cherry /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */ 2166 1.1 cherry #if VM_PHYSSEG_MAX > 1 2167 1.1 cherry uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 2168 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 2169 1.1 cherry 2170 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 2171 1.1 cherry #endif 2172 1.1 cherry 2173 1.1 cherry #if VM_PHYSSEG_MAX == 1 2174 1.1 cherry atf_tc_expect_signal(SIGABRT, 2175 1.1 cherry "cannot uvm_page_physunload() the last segment"); 2176 1.1 cherry #endif 2177 1.1 cherry 2178 1.1 cherry ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p)); 2179 1.1 cherry 2180 1.8 fox ATF_CHECK_EQ(VALID_START_PFN_1, atop(p)); 2181 1.8 fox 2182 1.1 cherry p = 0; 2183 1.1 cherry 2184 1.1 cherry ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p)); 2185 1.1 cherry 2186 1.8 fox ATF_CHECK_EQ(VALID_START_PFN_1 + 1, atop(p)); 2187 1.1 cherry 2188 1.1 cherry ATF_CHECK_EQ(1, uvm_physseg_get_entries()); 2189 1.1 cherry 2190 1.1 cherry /* The only node now is the one we inserted second. */ 2191 1.1 cherry upm = uvm_physseg_get_first(); 2192 1.1 cherry 2193 1.1 cherry ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); 2194 1.1 cherry ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); 2195 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm)); 2196 1.1 cherry ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm)); 2197 1.1 cherry } 2198 1.1 cherry 2199 1.1 cherry ATF_TC(uvm_page_physunload_invalid); 2200 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_invalid, tc) 2201 1.1 cherry { 2202 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the uvm_page_physunload() \ 2203 1.1 cherry fails when then Free list does not match."); 2204 1.1 cherry } 2205 1.1 cherry ATF_TC_BODY(uvm_page_physunload_invalid, tc) 2206 1.1 cherry { 2207 1.1 cherry psize_t npages = (VALID_END_PFN_2 - VALID_START_PFN_2); 2208 1.1 cherry 2209 1.1 cherry struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); 2210 1.1 cherry 2211 1.1 cherry paddr_t p = 0; 2212 1.1 cherry 2213 1.1 cherry uvm_physseg_t upm; 2214 1.1 cherry 2215 1.1 cherry setup(); 2216 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 2217 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 2218 1.1 cherry 2219 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 2220 1.1 cherry 2221 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 2222 1.1 cherry 2223 1.1 cherry uvm_physseg_init_seg(upm, pgs); 2224 1.1 cherry 2225 1.1 cherry ATF_CHECK_EQ(false, uvm_page_physunload(upm, VM_FREELIST_FIRST4G, &p)); 2226 1.1 cherry } 2227 1.1 cherry 2228 1.1 cherry ATF_TC(uvm_page_physunload_force); 2229 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_force, tc) 2230 1.1 cherry { 2231 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the basic \ 2232 1.1 cherry uvm_page_physunload_force() including delete works without."); 2233 1.1 cherry } 2234 1.1 cherry ATF_TC_BODY(uvm_page_physunload_force, tc) 2235 1.1 cherry { 2236 1.1 cherry /* 2237 1.1 cherry * Would uvmexp.npages reduce everytime an uvm_page_physunload is called? 2238 1.1 cherry */ 2239 1.1 cherry paddr_t p = 0; 2240 1.1 cherry 2241 1.1 cherry uvm_physseg_t upm; 2242 1.1 cherry 2243 1.1 cherry setup(); 2244 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, 2245 1.1 cherry VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); 2246 1.1 cherry 2247 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 2248 1.1 cherry 2249 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 2250 1.1 cherry 2251 1.1 cherry /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */ 2252 1.1 cherry #if VM_PHYSSEG_MAX > 1 2253 1.1 cherry /* 2254 1.9 andvar * We have couple of physloads done this is because of the fact that if 2255 1.1 cherry * we physunload all the PFs from a given range and we have only one 2256 1.1 cherry * segment in total a panic() is called 2257 1.1 cherry */ 2258 1.1 cherry uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, 2259 1.1 cherry VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); 2260 1.1 cherry 2261 1.1 cherry ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); 2262 1.1 cherry #endif 2263 1.1 cherry 2264 1.1 cherry #if VM_PHYSSEG_MAX == 1 2265 1.1 cherry atf_tc_expect_signal(SIGABRT, 2266 1.1 cherry "cannot uvm_page_physunload() the last segment"); 2267 1.1 cherry #endif 2268 1.1 cherry 2269 1.1 cherry ATF_REQUIRE_EQ(VALID_AVAIL_START_PFN_1, 2270 1.1 cherry uvm_physseg_get_avail_start(upm)); 2271 1.1 cherry 2272 1.1 cherry for(paddr_t i = VALID_AVAIL_START_PFN_1; 2273 1.1 cherry i < VALID_AVAIL_END_PFN_1; i++) { 2274 1.1 cherry ATF_CHECK_EQ(true, 2275 1.1 cherry uvm_page_physunload_force(upm, VM_FREELIST_DEFAULT, &p)); 2276 1.1 cherry ATF_CHECK_EQ(i, atop(p)); 2277 1.1 cherry 2278 1.1 cherry if(i + 1 < VALID_AVAIL_END_PFN_1) 2279 1.1 cherry ATF_CHECK_EQ(i + 1, uvm_physseg_get_avail_start(upm)); 2280 1.1 cherry } 2281 1.1 cherry 2282 1.1 cherry /* 2283 1.1 cherry * Now we try to retrieve the segment, which has been removed 2284 1.1 cherry * from the system through force unloading all the pages inside it. 2285 1.1 cherry */ 2286 1.1 cherry upm = uvm_physseg_find(VALID_AVAIL_END_PFN_1 - 1, NULL); 2287 1.1 cherry 2288 1.1 cherry /* It should no longer exist */ 2289 1.4 fox #if defined(UVM_HOTPLUG) 2290 1.1 cherry ATF_CHECK_EQ(NULL, upm); 2291 1.4 fox #else 2292 1.4 fox ATF_CHECK_EQ(-1, upm); 2293 1.4 fox #endif 2294 1.1 cherry 2295 1.1 cherry ATF_CHECK_EQ(1, uvm_physseg_get_entries()); 2296 1.1 cherry } 2297 1.1 cherry 2298 1.1 cherry ATF_TC(uvm_page_physunload_force_invalid); 2299 1.1 cherry ATF_TC_HEAD(uvm_page_physunload_force_invalid, tc) 2300 1.1 cherry { 2301 1.1 cherry atf_tc_set_md_var(tc, "descr", "Tests if the invalid conditions for \ 2302 1.1 cherry uvm_page_physunload_force_invalid()."); 2303 1.1 cherry } 2304 1.1 cherry ATF_TC_BODY(uvm_page_physunload_force_invalid, tc) 2305 1.1 cherry { 2306 1.1 cherry paddr_t p = 0; 2307 1.1 cherry 2308 1.1 cherry uvm_physseg_t upm; 2309 1.1 cherry 2310 1.1 cherry setup(); 2311 1.1 cherry upm = uvm_page_physload(VALID_START_PFN_2, VALID_START_PFN_2+ 1, 2312 1.1 cherry VALID_START_PFN_2, VALID_START_PFN_2, VM_FREELIST_DEFAULT); 2313 1.1 cherry 2314 1.1 cherry ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); 2315 1.1 cherry 2316 1.1 cherry ATF_REQUIRE_EQ(0, uvmexp.npages); 2317 1.1 cherry 2318 1.1 cherry ATF_CHECK_EQ(false, 2319 1.1 cherry uvm_page_physunload_force(upm, VM_FREELIST_DEFAULT, &p)); 2320 1.1 cherry 2321 1.1 cherry ATF_CHECK_EQ(0, p); 2322 1.1 cherry } 2323 1.1 cherry 2324 1.1 cherry ATF_TP_ADD_TCS(tp) 2325 1.1 cherry { 2326 1.1 cherry #if defined(UVM_HOTPLUG) 2327 1.1 cherry /* Internal */ 2328 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_alloc_atboot_mismatch); 2329 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_alloc_atboot_overrun); 2330 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_alloc_sanity); 2331 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_free_atboot_mismatch); 2332 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_free_sanity); 2333 1.1 cherry #if VM_PHYSSEG_MAX > 1 2334 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_atboot_free_leak); 2335 1.1 cherry #endif 2336 1.1 cherry #endif /* UVM_HOTPLUG */ 2337 1.1 cherry 2338 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_plug); 2339 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_unplug); 2340 1.1 cherry 2341 1.1 cherry /* Exported */ 2342 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_init); 2343 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physload_preload); 2344 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physload_postboot); 2345 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_handle_immutable); 2346 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_seg_chomp_slab); 2347 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_alloc_from_slab); 2348 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_init_seg); 2349 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_start); 2350 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_start_invalid); 2351 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_end); 2352 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_end_invalid); 2353 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_avail_start); 2354 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_avail_start_invalid); 2355 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_avail_end); 2356 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_avail_end_invalid); 2357 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_next); 2358 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_next_invalid); 2359 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_prev); 2360 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_prev_invalid); 2361 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_first); 2362 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_last); 2363 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_valid); 2364 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_valid_invalid); 2365 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_highest); 2366 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_free_list); 2367 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_start_hint); 2368 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_set_start_hint); 2369 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_set_start_hint_invalid); 2370 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_pg); 2371 1.1 cherry 2372 1.1 cherry #ifdef __HAVE_PMAP_PHYSSEG 2373 1.1 cherry ATF_TP_ADD_TC(tp, uvm_physseg_get_pmseg); 2374 1.1 cherry #endif 2375 1.1 cherry ATF_TP_ADD_TC(tp, vm_physseg_find); 2376 1.1 cherry ATF_TP_ADD_TC(tp, vm_physseg_find_invalid); 2377 1.1 cherry 2378 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_start); 2379 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_end); 2380 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_none); 2381 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_delete_start); 2382 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_delete_end); 2383 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_invalid); 2384 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_force); 2385 1.1 cherry ATF_TP_ADD_TC(tp, uvm_page_physunload_force_invalid); 2386 1.1 cherry 2387 1.1 cherry return atf_no_error(); 2388 1.1 cherry } 2389