1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2020, Scott Phillips <scottph@freebsd.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice unmodified, this list of conditions, and the following 11 * disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * $FreeBSD$ 28 */ 29 30 #ifndef _SYS_DUMPSET_H_ 31 #define _SYS_DUMPSET_H_ 32 33 #include <sys/_bitset.h> 34 #include <sys/bitset.h> 35 36 extern struct bitset *vm_page_dump; 37 extern long vm_page_dump_pages; 38 extern vm_paddr_t dump_avail[PHYS_AVAIL_COUNT]; 39 40 /* For the common case: add/remove a page from the minidump bitset. */ 41 #define dump_add_page(pa) vm_page_dump_add(vm_page_dump, pa) 42 #define dump_drop_page(pa) vm_page_dump_drop(vm_page_dump, pa) 43 44 static inline void 45 vm_page_dump_add(struct bitset *bitset, vm_paddr_t pa) 46 { 47 vm_pindex_t adj; 48 int i; 49 50 adj = 0; 51 for (i = 0; dump_avail[i + 1] != 0; i += 2) { 52 if (pa >= dump_avail[i] && pa < dump_avail[i + 1]) { 53 BIT_SET_ATOMIC(vm_page_dump_pages, 54 (pa >> PAGE_SHIFT) - (dump_avail[i] >> PAGE_SHIFT) + 55 adj, bitset); 56 return; 57 } 58 adj += howmany(dump_avail[i + 1], PAGE_SIZE) - 59 dump_avail[i] / PAGE_SIZE; 60 } 61 } 62 63 static inline void 64 vm_page_dump_drop(struct bitset *bitset, vm_paddr_t pa) 65 { 66 vm_pindex_t adj; 67 int i; 68 69 adj = 0; 70 for (i = 0; dump_avail[i + 1] != 0; i += 2) { 71 if (pa >= dump_avail[i] && pa < dump_avail[i + 1]) { 72 BIT_CLR_ATOMIC(vm_page_dump_pages, 73 (pa >> PAGE_SHIFT) - (dump_avail[i] >> PAGE_SHIFT) + 74 adj, bitset); 75 return; 76 } 77 adj += howmany(dump_avail[i + 1], PAGE_SIZE) - 78 dump_avail[i] / PAGE_SIZE; 79 } 80 } 81 82 static inline vm_paddr_t 83 vm_page_dump_index_to_pa(int bit) 84 { 85 int i, tot; 86 87 for (i = 0; dump_avail[i + 1] != 0; i += 2) { 88 tot = howmany(dump_avail[i + 1], PAGE_SIZE) - 89 dump_avail[i] / PAGE_SIZE; 90 if (bit < tot) 91 return ((vm_paddr_t)bit * PAGE_SIZE + 92 (dump_avail[i] & ~PAGE_MASK)); 93 bit -= tot; 94 } 95 return ((vm_paddr_t)NULL); 96 } 97 98 #define VM_PAGE_DUMP_FOREACH(bitset, pa) \ 99 for (vm_pindex_t __b = BIT_FFS(vm_page_dump_pages, bitset); \ 100 (pa) = vm_page_dump_index_to_pa(__b - 1), __b != 0; \ 101 __b = BIT_FFS_AT(vm_page_dump_pages, bitset, __b)) 102 103 #endif /* _SYS_DUMPSET_H_ */ 104