Changeset View
Standalone View
sys/vm/vm_fault.c
Show First 20 Lines • Show All 266 Lines • ▼ Show 20 Lines | vm_fault_dirty(vm_map_entry_t entry, vm_page_t m, vm_prot_t prot, | ||||
* If this is a NOSYNC mmap we do not want to set PGA_NOSYNC | * If this is a NOSYNC mmap we do not want to set PGA_NOSYNC | ||||
* if the page is already dirty to prevent data written with | * if the page is already dirty to prevent data written with | ||||
* the expectation of being synced from not being synced. | * the expectation of being synced from not being synced. | ||||
* Likewise if this entry does not request NOSYNC then make | * Likewise if this entry does not request NOSYNC then make | ||||
* sure the page isn't marked NOSYNC. Applications sharing | * sure the page isn't marked NOSYNC. Applications sharing | ||||
* data should use the same flags to avoid ping ponging. | * data should use the same flags to avoid ping ponging. | ||||
*/ | */ | ||||
if ((entry->eflags & MAP_ENTRY_NOSYNC) != 0) { | if ((entry->eflags & MAP_ENTRY_NOSYNC) != 0) { | ||||
if (m->dirty == 0) { | if (m->dirty == 0) { | ||||
jeff: Would the results of the atomic swap allow us to avoid vm_page_lock here?
I don't understand… | |||||
vm_page_aflag_set(m, PGA_NOSYNC); | vm_page_aflag_set(m, PGA_NOSYNC); | ||||
} | } | ||||
} else { | } else { | ||||
vm_page_aflag_clear(m, PGA_NOSYNC); | vm_page_aflag_clear(m, PGA_NOSYNC); | ||||
} | } | ||||
/* | /* | ||||
* If the fault is a write, we know that this page is being | * If the fault is a write, we know that this page is being | ||||
* written NOW so dirty it explicitly to save on | * written NOW so dirty it explicitly to save on | ||||
* pmap_is_modified() calls later. | * pmap_is_modified() calls later. | ||||
* | * | ||||
* Also, since the page is now dirty, we can possibly tell | * Also, since the page is now dirty, we can possibly tell | ||||
* the pager to release any swap backing the page. Calling | * the pager to release any swap backing the page. Calling | ||||
* the pager requires a write lock on the object. | * the pager requires a write lock on the object. | ||||
*/ | */ | ||||
if (need_dirty) | if (need_dirty) | ||||
vm_page_dirty(m); | vm_page_set_dirty(m, excl); | ||||
Done Inline ActionsWas this not leaking swap space in the !excl && need_dirty case? Did we not encounter this due to the conditions under which we call vm_fault_soft_fast? jeff: Was this not leaking swap space in the !excl && need_dirty case?
Did we not encounter this due… | |||||
Not Done Inline ActionsIt's not precisely a leak, because the swap space can eventually be reclaimed, e.g., when the vm object is destroyed. However, I do agree that the current behavior is less than ideal, and it probably occurs more often than we would like. In such cases, your patch is already an improvement. Addressing this problem was also the objective of D22324. alc: It's not precisely a leak, because the swap space can eventually be reclaimed, e.g., when the… | |||||
Done Inline ActionsIf you are comfortable with the 'two bit' solution (HASSWAP & UNSWAPPED) I can code that and push the locking/bit set/bit clear into swap_pager_unswapped(). Given that we were that imprecise about clearing it before do you think we need an additional page queue to lower the latency or should existing paging systems be adequate with the delayed bit detection? jeff: If you are comfortable with the 'two bit' solution (HASSWAP & UNSWAPPED) I can code that and… | |||||
if (!excl) | if (!excl) | ||||
vm_page_unlock(m); | vm_page_unlock(m); | ||||
else if (need_dirty) | |||||
vm_pager_page_unswapped(m); | |||||
} | } | ||||
/* | /* | ||||
* Unlocks fs.first_object and fs.map on success. | * Unlocks fs.first_object and fs.map on success. | ||||
*/ | */ | ||||
static int | static int | ||||
vm_fault_soft_fast(struct faultstate *fs, vm_offset_t vaddr, vm_prot_t prot, | vm_fault_soft_fast(struct faultstate *fs, vm_offset_t vaddr, vm_prot_t prot, | ||||
int fault_type, int fault_flags, boolean_t wired, vm_page_t *m_hold) | int fault_type, int fault_flags, boolean_t wired, vm_page_t *m_hold) | ||||
▲ Show 20 Lines • Show All 1,626 Lines • Show Last 20 Lines |
Would the results of the atomic swap allow us to avoid vm_page_lock here?
I don't understand the case where we're not dirtying the page but we do need to set PGA_NOSYNC. Do we need to do this if !need_dirty? Can't we wait for the first dirtying fault?