hat_unload_callback passes the wrong length to segvn_hat_unload_callback
hat_unload_callback() is supposed to call the specified callback on each range that is unloaded. The only consumer of this is segvn_unmap(), which specifies the segvn_hat_unload_callback().
However, the length passed to the callback is always wrong. It happens to be the number of pages, rather than the number of bytes, but this is also an accident. It's "lucky" that this is less than the correct size, so that segvn_hat_unload_callback() unloads less pages than it should, which is handled properly. If pagesize was different, we could pass a much larger length than we should, causing it to unload too many pages, breaking everything.
The problem is that handle_ranges() computes the length as "rng_cnt << LEVEL_SIZE(rng_level)". LEVEL_SIZE() gives the size in bytes, so we are typically shifting by 4096, with undefined results.
The fix is to shift by LEVEL_SHIFT().
Updated by Electric Monk over 6 years ago
- Status changed from New to Closed
- % Done changed from 0 to 100
commit a6a74e0e62d62ff750cd4b790be5eacc99c3bb8c Author: Matthew Ahrens <email@example.com> Date: 2015-01-16T02:21:04.000Z 5498 kmem_reap does one xcall per page 5514 hat_unload_callback passes the wrong length to segvn_hat_unload_callback Reviewed by: Adam Leventhal <firstname.lastname@example.org> Reviewed by: Dan Kimmel <email@example.com> Reviewed by: George Wilson <firstname.lastname@example.org> Reviewed by: Josef 'Jeff' Sipek <email@example.com> Reviewed by: Paul Dagnelie <firstname.lastname@example.org> Reviewed by: Robert Mustacchi <email@example.com> Approved by: Richard Lowe <firstname.lastname@example.org>