ca1f624517
For processing, reclaim_pv_chunk() removes the pv_chunk from the lru list, which makes pc_lru linkage invalid. Then the pmap lock is released, which allows for other thread to free the last pv entry allocated from the chunk and call free_pv_chunk(), which tries to modify the invalid linkage. Similarly, the chunk is inserted into the private tailq new_tail temporary. Again, free_pv_chunk() might be run and corrupt the linkage for the new_tail after the pmap lock is dropped. This is a consequence of r299788 elimination of pvh_global_lock, which allowed for reclaim to run in parallel with other pmap calls which free pv chunks. As a fix, do not remove the chunk from pc_lru queue, use a marker to remember the position in the queue iteration. We can safely operate on the chunks after the chunk's pmap is locked, we fetched the chunk after the marker, and we checked that chunk pmap is same as we have locked, because chunk removal from pc_lru requires both pv_chunk_mutex and the pmap mutex owned. Note that the fix lost an optimization which was present in the previous algorithm. Namely, new_tail requeueing rotated the pv chunks list so that reclaim didn't scan the same pv chunks that couldn't be freed (because they contained a wired and/or superpage mapping) on every invocation. An additional change is planned which would improve this. Reported and tested by: pho Reviewed by: alc Sponsored by: The FreeBSD Foundation MFC after: 1 week |
||
---|---|---|
.. | ||
pc | ||
xen | ||
_align.h | ||
_bus.h | ||
_inttypes.h | ||
_limits.h | ||
_stdint.h | ||
_types.h | ||
acpica_machdep.h | ||
apm_bios.h | ||
asm.h | ||
asmacros.h | ||
atomic.h | ||
bus_dma.h | ||
bus.h | ||
clock.h | ||
counter.h | ||
cpu.h | ||
cpufunc.h | ||
cputypes.h | ||
db_machdep.h | ||
dump.h | ||
efi.h | ||
elf.h | ||
endian.h | ||
exec.h | ||
fdt.h | ||
float.h | ||
floatingpoint.h | ||
fpu.h | ||
frame.h | ||
gdb_machdep.h | ||
ieeefp.h | ||
in_cksum.h | ||
intr_machdep.h | ||
iodev.h | ||
kdb.h | ||
limits.h | ||
md_var.h | ||
memdev.h | ||
metadata.h | ||
minidump.h | ||
mp_watchdog.h | ||
nexusvar.h | ||
npx.h | ||
ofw_machdep.h | ||
param.h | ||
pcb.h | ||
pci_cfgreg.h | ||
pcpu.h | ||
pmap.h | ||
pmc_mdep.h | ||
ppireg.h | ||
proc.h | ||
profile.h | ||
psl.h | ||
ptrace.h | ||
pvclock.h | ||
reg.h | ||
reloc.h | ||
resource.h | ||
runq.h | ||
segments.h | ||
setjmp.h | ||
sf_buf.h | ||
sgx.h | ||
sgxreg.h | ||
sigframe.h | ||
signal.h | ||
smp.h | ||
specialreg.h | ||
stack.h | ||
stdarg.h | ||
sysarch.h | ||
timerreg.h | ||
trap.h | ||
tss.h | ||
ucontext.h | ||
varargs.h | ||
vdso.h | ||
vm.h | ||
vmm_dev.h | ||
vmm_instruction_emul.h | ||
vmm.h | ||
vmparam.h |