* vm_page_set_valid_range: * * Sets portions of a page valid. The arguments are expected * to be DEV_BSIZE aligned but if they aren't the bitmap is inclusive * of any partial chunks touched by the range. The invalid portion of * such chunks will be zeroed. * * (base + size) must be less then or equal to PAGE_SIZE. */
| 5015 | * (base + size) must be less then or equal to PAGE_SIZE. |
| 5016 | */ |
| 5017 | void |
| 5018 | vm_page_set_valid_range(vm_page_t m, int base, int size) |
| 5019 | { |
| 5020 | int endoff, frag; |
| 5021 | vm_page_bits_t pagebits; |
| 5022 | |
| 5023 | vm_page_assert_busied(m); |
| 5024 | if (size == 0) /* handle degenerate case */ |
| 5025 | return; |
| 5026 | |
| 5027 | /* |
| 5028 | * If the base is not DEV_BSIZE aligned and the valid |
| 5029 | * bit is clear, we have to zero out a portion of the |
| 5030 | * first block. |
| 5031 | */ |
| 5032 | if ((frag = rounddown2(base, DEV_BSIZE)) != base && |
| 5033 | (m->valid & (1 << (base >> DEV_BSHIFT))) == 0) |
| 5034 | pmap_zero_page_area(m, frag, base - frag); |
| 5035 | |
| 5036 | /* |
| 5037 | * If the ending offset is not DEV_BSIZE aligned and the |
| 5038 | * valid bit is clear, we have to zero out a portion of |
| 5039 | * the last block. |
| 5040 | */ |
| 5041 | endoff = base + size; |
| 5042 | if ((frag = rounddown2(endoff, DEV_BSIZE)) != endoff && |
| 5043 | (m->valid & (1 << (endoff >> DEV_BSHIFT))) == 0) |
| 5044 | pmap_zero_page_area(m, endoff, |
| 5045 | DEV_BSIZE - (endoff & (DEV_BSIZE - 1))); |
| 5046 | |
| 5047 | /* |
| 5048 | * Assert that no previously invalid block that is now being validated |
| 5049 | * is already dirty. |
| 5050 | */ |
| 5051 | KASSERT((~m->valid & vm_page_bits(base, size) & m->dirty) == 0, |
| 5052 | ("vm_page_set_valid_range: page %p is dirty", m)); |
| 5053 | |
| 5054 | /* |
| 5055 | * Set valid bits inclusive of any overlap. |
| 5056 | */ |
| 5057 | pagebits = vm_page_bits(base, size); |
| 5058 | if (vm_page_xbusied(m)) |
| 5059 | m->valid |= pagebits; |
| 5060 | else |
| 5061 | vm_page_bits_set(m, &m->valid, pagebits); |
| 5062 | } |
| 5063 | |
| 5064 | /* |
| 5065 | * Set the page dirty bits and free the invalid swap space if |
no test coverage detected