Re: [PATCH v5 5/5] selftests/mm: add UFFDIO_MOVE ioctl test

From: Ryan Roberts
Date: Sat Dec 02 2023 - 03:07:12 EST


On 01/12/2023 16:26, Suren Baghdasaryan wrote:
> On Fri, Dec 1, 2023 at 1:29 AM Ryan Roberts <ryan.roberts@xxxxxxx> wrote:
>>
>> On 21/11/2023 17:16, Suren Baghdasaryan wrote:
>>> Add tests for new UFFDIO_MOVE ioctl which uses uffd to move source
>>> into destination buffer while checking the contents of both after
>>> the move. After the operation the content of the destination buffer
>>> should match the original source buffer's content while the source
>>> buffer should be zeroed. Separate tests are designed for PMD aligned and
>>> unaligned cases because they utilize different code paths in the kernel.
>>>
>>> Signed-off-by: Suren Baghdasaryan <surenb@xxxxxxxxxx>
>>> ---
>>> tools/testing/selftests/mm/uffd-common.c | 24 +++
>>> tools/testing/selftests/mm/uffd-common.h | 1 +
>>> tools/testing/selftests/mm/uffd-unit-tests.c | 189 +++++++++++++++++++
>>> 3 files changed, 214 insertions(+)
>>>
>>> diff --git a/tools/testing/selftests/mm/uffd-common.c b/tools/testing/selftests/mm/uffd-common.c
>>> index fb3bbc77fd00..b0ac0ec2356d 100644
>>> --- a/tools/testing/selftests/mm/uffd-common.c
>>> +++ b/tools/testing/selftests/mm/uffd-common.c
>>> @@ -631,6 +631,30 @@ int copy_page(int ufd, unsigned long offset, bool wp)
>>> return __copy_page(ufd, offset, false, wp);
>>> }
>>>
>>> +int move_page(int ufd, unsigned long offset, unsigned long len)
>>> +{
>>> + struct uffdio_move uffdio_move;
>>> +
>>> + if (offset + len > nr_pages * page_size)
>>> + err("unexpected offset %lu and length %lu\n", offset, len);
>>> + uffdio_move.dst = (unsigned long) area_dst + offset;
>>> + uffdio_move.src = (unsigned long) area_src + offset;
>>> + uffdio_move.len = len;
>>> + uffdio_move.mode = UFFDIO_MOVE_MODE_ALLOW_SRC_HOLES;
>>> + uffdio_move.move = 0;
>>> + if (ioctl(ufd, UFFDIO_MOVE, &uffdio_move)) {
>>> + /* real retval in uffdio_move.move */
>>> + if (uffdio_move.move != -EEXIST)
>>> + err("UFFDIO_MOVE error: %"PRId64,
>>> + (int64_t)uffdio_move.move);
>>
>> Hi Suren,
>>
>> FYI this error is triggering in mm-unstable (715b67adf4c8):
>>
>> Testing move-pmd on anon... ERROR: UFFDIO_MOVE error: -16 (errno=16,
>> @uffd-common.c:648)
>>
>> I'm running in a VM on Apple M2 (arm64). I haven't debugged any further, but
>> happy to go deeper if you can direct.
>
> Hi Ryan,
> Thanks for reporting! Could you please share your kernel config file?

It's arm64 defconfig (so 4K base pages) plus:

# Squashfs for snaps, xfs for large file folios.
./scripts/config --enable CONFIG_SQUASHFS_LZ4
./scripts/config --enable CONFIG_SQUASHFS_LZO
./scripts/config --enable CONFIG_SQUASHFS_XZ
./scripts/config --enable CONFIG_SQUASHFS_ZSTD
./scripts/config --enable CONFIG_XFS_FS

# Useful trace features (on for Ubuntu configs).
./scripts/config --enable CONFIG_FTRACE
./scripts/config --enable CONFIG_FUNCTION_TRACER
./scripts/config --enable CONFIG_KPROBES
./scripts/config --enable CONFIG_HIST_TRIGGERS
./scripts/config --enable CONFIG_FTRACE_SYSCALLS

# For general mm debug.
./scripts/config --enable CONFIG_DEBUG_VM
./scripts/config --enable CONFIG_DEBUG_VM_MAPLE_TREE
./scripts/config --enable CONFIG_DEBUG_VM_RB
./scripts/config --enable CONFIG_DEBUG_VM_PGFLAGS
./scripts/config --enable CONFIG_DEBUG_VM_PGTABLE
./scripts/config --enable CONFIG_PAGE_TABLE_CHECK

# For mm selftests.
./scripts/config --enable CONFIG_USERFAULTFD
./scripts/config --enable CONFIG_TEST_VMALLOC
./scripts/config --enable CONFIG_GUP_TEST

This is the config I always use when running mm selftests. I'll send you the
config file separately.

Then I'm running in a QEMU VM with 12G RAM, equally split across 2 (emulated)
numa nodes. I have these pertinent kernel command line args (intended to ensure
all the mm selftests can run):

transparent_hugepage=madvise secretmem.enable hugepagesz=1G hugepages=0:2,1:2
hugepagesz=32M hugepages=0:2,1:2 default_hugepagesz=2M hugepages=0:64,1:64
hugepagesz=64K hugepages=0:2,1:2


>
> There are several places UFFDIO_MOVE returns EBUSY: 4 places in
> move_pages_huge_pmd(), 2 places in move_present_pte(), 2 places in
> move_pages_pte() and once in move_swap_pte(). While I'm trying to
> reproduce, it would be useful if you could check which place is
> triggering the error.

Happy to, but will have to wait for Monday. I should say, the test fails
consistently for me. But sometimes the failure is EAGAIN (11). Most of the time
it is EBUSY though and I haven't figured out what causes the difference.

> Thanks,
> Suren.
>
>>
>> Thanks,
>> Ryan
>>
>>
>>> + wake_range(ufd, uffdio_move.dst, len);
>>> + } else if (uffdio_move.move != len) {
>>> + err("UFFDIO_MOVE error: %"PRId64, (int64_t)uffdio_move.move);
>>> + } else
>>> + return 1;
>>> + return 0;
>>> +}
>>
>> --
>> To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe@xxxxxxxxxxx.
>>