On Tue, Mar 10, 2026 at 08:58:21AM -0700, Anthony Yznaga wrote: > Verify that a mapping created with MAP_DROPPABLE cannot be locked > via mlock(), and that it will not be locked if it's created after > mlockall(MCL_FUTURE). > > Signed-off-by: Anthony Yznaga <[email protected]>
Can confirm this test fails before your patch and passes after, so LGTM :) Reviewed-by: Lorenzo Stoakes (Oracle) <[email protected]> Tested-by: Lorenzo Stoakes (Oracle) <[email protected]> > --- > tools/testing/selftests/mm/mlock2-tests.c | 78 ++++++++++++++++++++--- > 1 file changed, 69 insertions(+), 9 deletions(-) > > diff --git a/tools/testing/selftests/mm/mlock2-tests.c > b/tools/testing/selftests/mm/mlock2-tests.c > index b474f2b20def..b5790e717dd6 100644 > --- a/tools/testing/selftests/mm/mlock2-tests.c > +++ b/tools/testing/selftests/mm/mlock2-tests.c > @@ -1,6 +1,7 @@ > // SPDX-License-Identifier: GPL-2.0 > #define _GNU_SOURCE > #include <sys/mman.h> > +#include <linux/mman.h> > #include <stdint.h> > #include <unistd.h> > #include <string.h> > @@ -163,14 +164,17 @@ static int lock_check(unsigned long addr) > return (vma_rss == vma_size); > } > > -static int unlock_lock_check(char *map) > +static int unlock_lock_check(char *map, bool mlock_supported) > { > - if (is_vmflag_set((unsigned long)map, LOCKED)) { > + if (!is_vmflag_set((unsigned long)map, LOCKED)) > + return 0; > + > + if (mlock_supported) > ksft_print_msg("VMA flag %s is present on page 1 after > unlock\n", LOCKED); > - return 1; > - } > + else > + ksft_print_msg("VMA flag %s is present on an unsupported > VMA\n", LOCKED); > > - return 0; > + return 1; > } > > static void test_mlock_lock(void) > @@ -196,7 +200,7 @@ static void test_mlock_lock(void) > ksft_exit_fail_msg("munlock(): %s\n", strerror(errno)); > } > > - ksft_test_result(!unlock_lock_check(map), "%s: Unlocked\n", __func__); > + ksft_test_result(!unlock_lock_check(map, true), "%s: Unlocked\n", > __func__); > munmap(map, 2 * page_size); > } > > @@ -296,7 +300,7 @@ static void test_munlockall0(void) > ksft_exit_fail_msg("munlockall(): %s\n", strerror(errno)); > } > > - ksft_test_result(!unlock_lock_check(map), "%s: No locked memory\n", > __func__); > + ksft_test_result(!unlock_lock_check(map, true), "%s: No locked > memory\n", __func__); > munmap(map, 2 * page_size); > } > > @@ -336,7 +340,61 @@ static void test_munlockall1(void) > ksft_exit_fail_msg("munlockall() %s\n", strerror(errno)); > } > > - ksft_test_result(!unlock_lock_check(map), "%s: No locked memory\n", > __func__); > + ksft_test_result(!unlock_lock_check(map, true), "%s: No locked > memory\n", __func__); > + munmap(map, 2 * page_size); > +} > + > +/* > + * Droppable memory should not be lockable. > + */ > +static void test_mlock_droppable(void) > +{ > + char *map; > + unsigned long page_size = getpagesize(); > + > + /* > + * Ensure MCL_FUTURE is not set. > + */ > + if (mlockall(MCL_CURRENT)) > + ksft_exit_fail_msg("mlockall(MCL_CURRENT): %s\n", > strerror(errno)); > + if (munlockall()) > + ksft_exit_fail_msg("munlockall() %s\n", strerror(errno)); > + > + map = mmap(NULL, 2 * page_size, PROT_READ | PROT_WRITE, > + MAP_ANONYMOUS | MAP_DROPPABLE, -1, 0); > + if (map == MAP_FAILED) > + ksft_exit_fail_msg("mmap error: %s", strerror(errno)); > + > + if (mlock2_(map, 2 * page_size, 0)) { > + munmap(map, 2 * page_size); > + ksft_exit_fail_msg("mlock2(0): %s\n", strerror(errno)); > + } > + > + ksft_test_result(!unlock_lock_check(map, false), "%s: droppable memory > not locked\n", > + __func__); > + > + munmap(map, 2 * page_size); > +} > + > +static void test_mlockall_future_droppable(void) > +{ > + char *map; > + unsigned long page_size = getpagesize(); > + > + if (mlockall(MCL_CURRENT | MCL_FUTURE)) > + ksft_exit_fail_msg("mlockall(MCL_CURRENT | MCL_FUTURE): %s\n", > strerror(errno)); > + > + map = mmap(NULL, 2 * page_size, PROT_READ | PROT_WRITE, > + MAP_ANONYMOUS | MAP_DROPPABLE, -1, 0); > + > + ksft_test_result(!unlock_lock_check(map, false), "%s: droppable memory > not locked\n", > + __func__); > + > + if (munlockall()) { > + munmap(map, 2 * page_size); > + ksft_exit_fail_msg("munlockall() %s\n", strerror(errno)); > + } > + > munmap(map, 2 * page_size); > } > > @@ -442,7 +500,7 @@ int main(int argc, char **argv) > > munmap(map, size); > > - ksft_set_plan(13); > + ksft_set_plan(15); > > test_mlock_lock(); > test_mlock_onfault(); > @@ -451,6 +509,8 @@ int main(int argc, char **argv) > test_lock_onfault_of_present(); > test_vma_management(true); > test_mlockall(); > + test_mlock_droppable(); > + test_mlockall_future_droppable(); > > ksft_finished(); > } > -- > 2.47.3 >

