Hello, > Since entry is released, you need to read the vme_next field before calling > vm_map_coalesce_entry, just like we do for current->vme_next.
A merge keeps the predecessor, and that predecessor now contains start. entry->vme_next points after the merged entry, so vm_map_pageable_scan() would skip the range whose protection just changed. The saved successor can also be freed by a later merge in the same loop. vm_map_lookup_entry(map, start, &entry) returns the live entry that contains start, which is the predecessor. The map is still write-locked. This is the same lookup done before the loop. > Also, I guess we can avoid doing this when vm_map_coalesce_entry returned > false? With a non-empty range, the loop can already have freed the start entry. The last call then runs on the entry after the range and returns false when that entry has a different protection, which is the normal case. Skipping the lookup there would leave the stale pointer. David
