Re: [PATCH] tests/qtest/migrate-test: Use regular file file for shared-memory tests

2024-05-28 Thread Peter Xu
On Wed, May 29, 2024 at 10:05:32AM +1000, Nicholas Piggin wrote:
> I think that's good if you _need_ shm (e.g., for a uffd test), but
> we should permit tests that only require a memory file.

Yes there's no reason to forbid that, it's just that we're not adding new
tests but we can potentially change any future use_shmem to not test shmem
anymore.. instead we test something we don't suggest users to use..

The only concern is a small /dev/shm mount, am I right?  Would it work if
switch to memory-backend-memfd,shared=on?

Thanks,

-- 
Peter Xu




Re: [PATCH] tests/qtest/migrate-test: Use regular file file for shared-memory tests

2024-05-28 Thread Nicholas Piggin
On Wed May 29, 2024 at 2:05 AM AEST, Peter Xu wrote:
> On Tue, May 28, 2024 at 09:35:22AM -0400, Peter Xu wrote:
> > On Tue, May 28, 2024 at 02:27:57PM +1000, Nicholas Piggin wrote:
> > > There is no need to use /dev/shm for file-backed memory devices, and
> > > it is too small to be usable in gitlab CI. Switch to using a regular
> > > file in /tmp/ which will usually have more space available.
> > > 
> > > Signed-off-by: Nicholas Piggin 
> > > ---
> > > Am I missing something? AFAIKS there is not even any point using
> > > /dev/shm aka tmpfs anyway, there is not much special about it as a
> > > filesystem. This applies on top of the series just sent, and passes
> > > gitlab CI qtests including aarch64.
> > 
> > I think it's just that /dev/shm guarantees shmem usage, while the var
> > "tmpfs" implies g_dir_make_tmp() which may be another non-ram based file
> > system, while that'll be slightly different comparing to what a real user
> > would use - we don't suggest user to put guest RAM on things like btrfs.

Right, these days I think /tmp usually is not tmpfs but just a regular
filesystem. For these tests that's okay though. And it gets us working
with gitlab CI. The ignore-shared test works and is verified to skip the
copy (according to counters and some tracing I did) so I think it's a
good step.

> > 
> > One real implication is if we add a postcopy test it'll fail with
> > g_dir_make_tmp() when it is not pointing to a shmem mount, as
> > UFFDIO_REGISTER will fail there.  But that test doesn't yet exist as the
> > QEMU paths should be the same even if Linux will trigger different paths
> > when different types of mem is used (anonymous v.s. shmem).

Ah okay userfault. I guess that would require real tmpfs. We could just
add a new option to the harness for require_uffd when it comes up?

> > If the goal here is to properly handle the case where tmpfs doesn't have
> > enough space, how about what I suggested in the other email?
> > 
> > https://lore.kernel.org/r/ZlSppKDE6wzjCF--@x1n
> > 
> > IOW, try populate the shmem region before starting the guest, skip if
> > population failed.  Would that work?

I think that's good if you _need_ shm (e.g., for a uffd test), but
we should permit tests that only require a memory file.

Thanks,
Nick



Re: [PATCH] tests/qtest/migrate-test: Use regular file file for shared-memory tests

2024-05-28 Thread Fabiano Rosas
Peter Xu  writes:

> On Tue, May 28, 2024 at 09:35:22AM -0400, Peter Xu wrote:
>> On Tue, May 28, 2024 at 02:27:57PM +1000, Nicholas Piggin wrote:
>> > There is no need to use /dev/shm for file-backed memory devices, and
>> > it is too small to be usable in gitlab CI. Switch to using a regular
>> > file in /tmp/ which will usually have more space available.
>> > 
>> > Signed-off-by: Nicholas Piggin 
>> > ---
>> > Am I missing something? AFAIKS there is not even any point using
>> > /dev/shm aka tmpfs anyway, there is not much special about it as a
>> > filesystem. This applies on top of the series just sent, and passes
>> > gitlab CI qtests including aarch64.
>> 
>> I think it's just that /dev/shm guarantees shmem usage, while the var
>> "tmpfs" implies g_dir_make_tmp() which may be another non-ram based file
>> system, while that'll be slightly different comparing to what a real user
>> would use - we don't suggest user to put guest RAM on things like btrfs.
>> 
>> One real implication is if we add a postcopy test it'll fail with
>> g_dir_make_tmp() when it is not pointing to a shmem mount, as
>> UFFDIO_REGISTER will fail there.  But that test doesn't yet exist as the
>> QEMU paths should be the same even if Linux will trigger different paths
>> when different types of mem is used (anonymous v.s. shmem).
>> 
>> If the goal here is to properly handle the case where tmpfs doesn't have
>> enough space, how about what I suggested in the other email?
>> 
>> https://lore.kernel.org/r/ZlSppKDE6wzjCF--@x1n
>> 
>> IOW, try populate the shmem region before starting the guest, skip if
>> population failed.  Would that work?
>
> Let me append some more info here..
>
> I think madvise() isn't needed as fallocate() should do the population work
> already, afaiu, then it means we pass the shmem path to QEMU and QEMU
> should notice this memory-backend-file existed, open() directly.
>
> I quicked walk the QEMU memory code and so far it looks all applicable, so
> that QEMU should just start the guest with the pre-populated shmem page
> caches.
>
> There's one trick where qemu_ram_mmap() will map some extra pages, on x86
> 4k, and I don't yet know why we did that..
>
> /*
>  * Note: this always allocates at least one extra page of virtual address
>  * space, even if size is already aligned.
>  */
> total = size + align;

At the end of the function:

/*
 * Leave a single PROT_NONE page allocated after the RAM block, to serve as
 * a guard page guarding against potential buffer overflows.
 */



Re: [PATCH] tests/qtest/migrate-test: Use regular file file for shared-memory tests

2024-05-28 Thread Peter Xu
On Tue, May 28, 2024 at 09:35:22AM -0400, Peter Xu wrote:
> On Tue, May 28, 2024 at 02:27:57PM +1000, Nicholas Piggin wrote:
> > There is no need to use /dev/shm for file-backed memory devices, and
> > it is too small to be usable in gitlab CI. Switch to using a regular
> > file in /tmp/ which will usually have more space available.
> > 
> > Signed-off-by: Nicholas Piggin 
> > ---
> > Am I missing something? AFAIKS there is not even any point using
> > /dev/shm aka tmpfs anyway, there is not much special about it as a
> > filesystem. This applies on top of the series just sent, and passes
> > gitlab CI qtests including aarch64.
> 
> I think it's just that /dev/shm guarantees shmem usage, while the var
> "tmpfs" implies g_dir_make_tmp() which may be another non-ram based file
> system, while that'll be slightly different comparing to what a real user
> would use - we don't suggest user to put guest RAM on things like btrfs.
> 
> One real implication is if we add a postcopy test it'll fail with
> g_dir_make_tmp() when it is not pointing to a shmem mount, as
> UFFDIO_REGISTER will fail there.  But that test doesn't yet exist as the
> QEMU paths should be the same even if Linux will trigger different paths
> when different types of mem is used (anonymous v.s. shmem).
> 
> If the goal here is to properly handle the case where tmpfs doesn't have
> enough space, how about what I suggested in the other email?
> 
> https://lore.kernel.org/r/ZlSppKDE6wzjCF--@x1n
> 
> IOW, try populate the shmem region before starting the guest, skip if
> population failed.  Would that work?

Let me append some more info here..

I think madvise() isn't needed as fallocate() should do the population work
already, afaiu, then it means we pass the shmem path to QEMU and QEMU
should notice this memory-backend-file existed, open() directly.

I quicked walk the QEMU memory code and so far it looks all applicable, so
that QEMU should just start the guest with the pre-populated shmem page
caches.

There's one trick where qemu_ram_mmap() will map some extra pages, on x86
4k, and I don't yet know why we did that..

/*
 * Note: this always allocates at least one extra page of virtual address
 * space, even if size is already aligned.
 */
total = size + align;

But that was only used in mmap_reserve() not mmap_activate(), so the real
mmap() should still be exactly what we fallocate()ed.

Thanks,

-- 
Peter Xu




Re: [PATCH] tests/qtest/migrate-test: Use regular file file for shared-memory tests

2024-05-28 Thread Fabiano Rosas
Nicholas Piggin  writes:

> There is no need to use /dev/shm for file-backed memory devices, and
> it is too small to be usable in gitlab CI. Switch to using a regular
> file in /tmp/ which will usually have more space available.
>
> Signed-off-by: Nicholas Piggin 
> ---
> Am I missing something? AFAIKS there is not even any point using
> /dev/shm aka tmpfs anyway, there is not much special about it as a
> filesystem. This applies on top of the series just sent, and passes
> gitlab CI qtests including aarch64.

/dev/shm however will be mounted on tmpfs while /tmp may not. I don't
know if this has any implication to this test. Probably not.

>
> Thanks,
> Nick
>
>  tests/qtest/migration-test.c | 41 
>  1 file changed, 13 insertions(+), 28 deletions(-)
>
> diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
> index 45830eb213..86eace354e 100644
> --- a/tests/qtest/migration-test.c
> +++ b/tests/qtest/migration-test.c
> @@ -552,7 +552,7 @@ typedef struct {
>   * unconditionally, because it means the user would like to be verbose.
>   */
>  bool hide_stderr;
> -bool use_shmem;
> +bool use_memfile;
>  /* only launch the target process */
>  bool only_target;
>  /* Use dirty ring if true; dirty logging otherwise */
> @@ -672,29 +672,14 @@ static int test_migrate_start(QTestState **from, 
> QTestState **to,
>  g_autofree gchar *cmd_source = NULL;
>  g_autofree gchar *cmd_target = NULL;
>  const gchar *ignore_stderr;
> -g_autofree char *shmem_opts = NULL;
> -g_autofree char *shmem_path = NULL;
> +g_autofree char *memfile_opts = NULL;
> +g_autofree char *memfile_path = NULL;
>  const char *kvm_opts = NULL;
>  const char *arch = qtest_get_arch();
>  const char *memory_size;
>  const char *machine_alias, *machine_opts = "";
>  g_autofree char *machine = NULL;
>  
> -if (args->use_shmem) {
> -if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
> -g_test_skip("/dev/shm is not supported");
> -return -1;
> -}
> -if (getenv("GITLAB_CI")) {
> -/*
> - * Gitlab runners are limited to 64MB shm size. See:
> - * https://lore.kernel.org/all/87ttq5fvh7@suse.de/
> - */
> -g_test_skip("/dev/shm is not supported in Gitlab CI 
> environment");
> -return -1;
> -}
> -}
> -
>  dst_state = (QTestMigrationState) { };
>  src_state = (QTestMigrationState) { };
>  bootfile_create(tmpfs, args->suspend_me);
> @@ -754,12 +739,12 @@ static int test_migrate_start(QTestState **from, 
> QTestState **to,
>  ignore_stderr = "";
>  }
>  
> -if (args->use_shmem) {
> -shmem_path = g_strdup_printf("/dev/shm/qemu-%d", getpid());
> -shmem_opts = g_strdup_printf(
> +if (args->use_memfile) {
> +memfile_path = g_strdup_printf("/%s/qemu-%d", tmpfs, getpid());

The variable tmpfs already contains the leading slash. Strictly speaking
we don't need the pid because 'tmpfs' is unique for each migration-test
run. If you use a fixed string such as qemu-mem, you can then clean it
up at test_migrate_end() along with the others.

> +memfile_opts = g_strdup_printf(
>  "-object memory-backend-file,id=mem0,size=%s"
>  ",mem-path=%s,share=on -numa node,memdev=mem0",
> -memory_size, shmem_path);
> +memory_size, memfile_path);
>  }
>  
>  if (args->use_dirty_ring) {
> @@ -788,7 +773,7 @@ static int test_migrate_start(QTestState **from, 
> QTestState **to,
>   memory_size, tmpfs,
>   arch_opts ? arch_opts : "",
>   arch_source ? arch_source : "",
> - shmem_opts ? shmem_opts : "",
> + memfile_opts ? memfile_opts : "",
>   args->opts_source ? args->opts_source : "",
>   ignore_stderr);
>  if (!args->only_target) {
> @@ -810,7 +795,7 @@ static int test_migrate_start(QTestState **from, 
> QTestState **to,
>   memory_size, tmpfs, uri,
>   arch_opts ? arch_opts : "",
>   arch_target ? arch_target : "",
> - shmem_opts ? shmem_opts : "",
> + memfile_opts ? memfile_opts : "",
>   args->opts_target ? args->opts_target : "",
>   ignore_stderr);
>  *to = qtest_init_with_env(QEMU_ENV_DST, cmd_target);
> @@ -822,8 +807,8 @@ static int test_migrate_start(QTestState **from, 
> QTestState **to,
>   * Remove shmem file immediately to avoid memory leak in test failed 
> case.
>   * It's valid because QEMU has already opened this file
>   */

I'm 

Re: [PATCH] tests/qtest/migrate-test: Use regular file file for shared-memory tests

2024-05-28 Thread Peter Xu
On Tue, May 28, 2024 at 02:27:57PM +1000, Nicholas Piggin wrote:
> There is no need to use /dev/shm for file-backed memory devices, and
> it is too small to be usable in gitlab CI. Switch to using a regular
> file in /tmp/ which will usually have more space available.
> 
> Signed-off-by: Nicholas Piggin 
> ---
> Am I missing something? AFAIKS there is not even any point using
> /dev/shm aka tmpfs anyway, there is not much special about it as a
> filesystem. This applies on top of the series just sent, and passes
> gitlab CI qtests including aarch64.

I think it's just that /dev/shm guarantees shmem usage, while the var
"tmpfs" implies g_dir_make_tmp() which may be another non-ram based file
system, while that'll be slightly different comparing to what a real user
would use - we don't suggest user to put guest RAM on things like btrfs.

One real implication is if we add a postcopy test it'll fail with
g_dir_make_tmp() when it is not pointing to a shmem mount, as
UFFDIO_REGISTER will fail there.  But that test doesn't yet exist as the
QEMU paths should be the same even if Linux will trigger different paths
when different types of mem is used (anonymous v.s. shmem).

If the goal here is to properly handle the case where tmpfs doesn't have
enough space, how about what I suggested in the other email?

https://lore.kernel.org/r/ZlSppKDE6wzjCF--@x1n

IOW, try populate the shmem region before starting the guest, skip if
population failed.  Would that work?

Thanks,

> 
> Thanks,
> Nick
> 
>  tests/qtest/migration-test.c | 41 
>  1 file changed, 13 insertions(+), 28 deletions(-)
> 
> diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
> index 45830eb213..86eace354e 100644
> --- a/tests/qtest/migration-test.c
> +++ b/tests/qtest/migration-test.c
> @@ -552,7 +552,7 @@ typedef struct {
>   * unconditionally, because it means the user would like to be verbose.
>   */
>  bool hide_stderr;
> -bool use_shmem;
> +bool use_memfile;
>  /* only launch the target process */
>  bool only_target;
>  /* Use dirty ring if true; dirty logging otherwise */
> @@ -672,29 +672,14 @@ static int test_migrate_start(QTestState **from, 
> QTestState **to,
>  g_autofree gchar *cmd_source = NULL;
>  g_autofree gchar *cmd_target = NULL;
>  const gchar *ignore_stderr;
> -g_autofree char *shmem_opts = NULL;
> -g_autofree char *shmem_path = NULL;
> +g_autofree char *memfile_opts = NULL;
> +g_autofree char *memfile_path = NULL;
>  const char *kvm_opts = NULL;
>  const char *arch = qtest_get_arch();
>  const char *memory_size;
>  const char *machine_alias, *machine_opts = "";
>  g_autofree char *machine = NULL;
>  
> -if (args->use_shmem) {
> -if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
> -g_test_skip("/dev/shm is not supported");
> -return -1;
> -}
> -if (getenv("GITLAB_CI")) {
> -/*
> - * Gitlab runners are limited to 64MB shm size. See:
> - * https://lore.kernel.org/all/87ttq5fvh7@suse.de/
> - */
> -g_test_skip("/dev/shm is not supported in Gitlab CI 
> environment");
> -return -1;
> -}
> -}
> -
>  dst_state = (QTestMigrationState) { };
>  src_state = (QTestMigrationState) { };
>  bootfile_create(tmpfs, args->suspend_me);
> @@ -754,12 +739,12 @@ static int test_migrate_start(QTestState **from, 
> QTestState **to,
>  ignore_stderr = "";
>  }
>  
> -if (args->use_shmem) {
> -shmem_path = g_strdup_printf("/dev/shm/qemu-%d", getpid());
> -shmem_opts = g_strdup_printf(
> +if (args->use_memfile) {
> +memfile_path = g_strdup_printf("/%s/qemu-%d", tmpfs, getpid());
> +memfile_opts = g_strdup_printf(
>  "-object memory-backend-file,id=mem0,size=%s"
>  ",mem-path=%s,share=on -numa node,memdev=mem0",
> -memory_size, shmem_path);
> +memory_size, memfile_path);
>  }
>  
>  if (args->use_dirty_ring) {
> @@ -788,7 +773,7 @@ static int test_migrate_start(QTestState **from, 
> QTestState **to,
>   memory_size, tmpfs,
>   arch_opts ? arch_opts : "",
>   arch_source ? arch_source : "",
> - shmem_opts ? shmem_opts : "",
> + memfile_opts ? memfile_opts : "",
>   args->opts_source ? args->opts_source : "",
>   ignore_stderr);
>  if (!args->only_target) {
> @@ -810,7 +795,7 @@ static int test_migrate_start(QTestState **from, 
> QTestState **to,
>   memory_size, tmpfs, uri,
>   arch_opts ? arch_opts : "",
>   arch_target ? arch_target : "",
> -  

[PATCH] tests/qtest/migrate-test: Use regular file file for shared-memory tests

2024-05-27 Thread Nicholas Piggin
There is no need to use /dev/shm for file-backed memory devices, and
it is too small to be usable in gitlab CI. Switch to using a regular
file in /tmp/ which will usually have more space available.

Signed-off-by: Nicholas Piggin 
---
Am I missing something? AFAIKS there is not even any point using
/dev/shm aka tmpfs anyway, there is not much special about it as a
filesystem. This applies on top of the series just sent, and passes
gitlab CI qtests including aarch64.

Thanks,
Nick

 tests/qtest/migration-test.c | 41 
 1 file changed, 13 insertions(+), 28 deletions(-)

diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index 45830eb213..86eace354e 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -552,7 +552,7 @@ typedef struct {
  * unconditionally, because it means the user would like to be verbose.
  */
 bool hide_stderr;
-bool use_shmem;
+bool use_memfile;
 /* only launch the target process */
 bool only_target;
 /* Use dirty ring if true; dirty logging otherwise */
@@ -672,29 +672,14 @@ static int test_migrate_start(QTestState **from, 
QTestState **to,
 g_autofree gchar *cmd_source = NULL;
 g_autofree gchar *cmd_target = NULL;
 const gchar *ignore_stderr;
-g_autofree char *shmem_opts = NULL;
-g_autofree char *shmem_path = NULL;
+g_autofree char *memfile_opts = NULL;
+g_autofree char *memfile_path = NULL;
 const char *kvm_opts = NULL;
 const char *arch = qtest_get_arch();
 const char *memory_size;
 const char *machine_alias, *machine_opts = "";
 g_autofree char *machine = NULL;
 
-if (args->use_shmem) {
-if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
-g_test_skip("/dev/shm is not supported");
-return -1;
-}
-if (getenv("GITLAB_CI")) {
-/*
- * Gitlab runners are limited to 64MB shm size. See:
- * https://lore.kernel.org/all/87ttq5fvh7@suse.de/
- */
-g_test_skip("/dev/shm is not supported in Gitlab CI environment");
-return -1;
-}
-}
-
 dst_state = (QTestMigrationState) { };
 src_state = (QTestMigrationState) { };
 bootfile_create(tmpfs, args->suspend_me);
@@ -754,12 +739,12 @@ static int test_migrate_start(QTestState **from, 
QTestState **to,
 ignore_stderr = "";
 }
 
-if (args->use_shmem) {
-shmem_path = g_strdup_printf("/dev/shm/qemu-%d", getpid());
-shmem_opts = g_strdup_printf(
+if (args->use_memfile) {
+memfile_path = g_strdup_printf("/%s/qemu-%d", tmpfs, getpid());
+memfile_opts = g_strdup_printf(
 "-object memory-backend-file,id=mem0,size=%s"
 ",mem-path=%s,share=on -numa node,memdev=mem0",
-memory_size, shmem_path);
+memory_size, memfile_path);
 }
 
 if (args->use_dirty_ring) {
@@ -788,7 +773,7 @@ static int test_migrate_start(QTestState **from, QTestState 
**to,
  memory_size, tmpfs,
  arch_opts ? arch_opts : "",
  arch_source ? arch_source : "",
- shmem_opts ? shmem_opts : "",
+ memfile_opts ? memfile_opts : "",
  args->opts_source ? args->opts_source : "",
  ignore_stderr);
 if (!args->only_target) {
@@ -810,7 +795,7 @@ static int test_migrate_start(QTestState **from, QTestState 
**to,
  memory_size, tmpfs, uri,
  arch_opts ? arch_opts : "",
  arch_target ? arch_target : "",
- shmem_opts ? shmem_opts : "",
+ memfile_opts ? memfile_opts : "",
  args->opts_target ? args->opts_target : "",
  ignore_stderr);
 *to = qtest_init_with_env(QEMU_ENV_DST, cmd_target);
@@ -822,8 +807,8 @@ static int test_migrate_start(QTestState **from, QTestState 
**to,
  * Remove shmem file immediately to avoid memory leak in test failed case.
  * It's valid because QEMU has already opened this file
  */
-if (args->use_shmem) {
-unlink(shmem_path);
+if (args->use_memfile) {
+unlink(memfile_path);
 }
 
 return 0;
@@ -1875,7 +1860,7 @@ static void test_ignore_shared(void)
 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
 QTestState *from, *to;
 MigrateStart args = {
-.use_shmem = true,
+.use_memfile = true,
 };
 
 if (test_migrate_start(, , uri, )) {
@@ -2033,7 +2018,7 @@ static void test_mode_reboot(void)
 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
FILE_TEST_FILENAME);
 MigrateCommon