* [PATCH v4 0/5] backends/hostmem: Report more errors on failures
@ 2024-06-05 10:44 Michal Privoznik
2024-06-05 10:44 ` [PATCH v4 1/5] meson: Don't even detect posix_madvise() on Darwin Michal Privoznik
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: Michal Privoznik @ 2024-06-05 10:44 UTC (permalink / raw)
To: qemu-devel
v4 of:
https://mail.gnu.org/archive/html/qemu-devel/2024-05/msg06511.html
diff to v3:
- In 2/5 instead of fixing up posix_madvise() retval at runtime, just
don't use posix_madvise() on Darwin at all (resulted in new patch 1/5).
Since 2/5 is now the same as 1/4 from v2 I'm including David's
Reviewed-by line.
- The last patch was tested by Mario, so I've included his Tested-by
line. Thanks!
Michal Privoznik (5):
meson: Don't even detect posix_madvise() on Darwin
osdep: Make qemu_madvise() to set errno in all cases
osdep: Make qemu_madvise() return ENOSYS on unsupported OSes
backends/hostmem: Report error on qemu_madvise() failures
backends/hostmem: Report error when memory size is unaligned
backends/hostmem.c | 46 ++++++++++++++++++++++++++++++++++++++--------
meson.build | 14 ++++++++++----
util/osdep.c | 9 +++++++--
3 files changed, 55 insertions(+), 14 deletions(-)
--
2.44.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v4 1/5] meson: Don't even detect posix_madvise() on Darwin
2024-06-05 10:44 [PATCH v4 0/5] backends/hostmem: Report more errors on failures Michal Privoznik
@ 2024-06-05 10:44 ` Michal Privoznik
2024-06-05 10:44 ` [PATCH v4 2/5] osdep: Make qemu_madvise() to set errno in all cases Michal Privoznik
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Michal Privoznik @ 2024-06-05 10:44 UTC (permalink / raw)
To: qemu-devel
On Darwin, posix_madvise() has the same return semantics as plain
madvise() [1]. That's not really what our usage expects.
Fortunately, madvise() is available and preferred anyways so we
may stop detecting posix_madvise() on Darwin.
1: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man2/madvise.2.auto.html
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
meson.build | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/meson.build b/meson.build
index 6386607144..49962cce88 100644
--- a/meson.build
+++ b/meson.build
@@ -2552,10 +2552,16 @@ config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
#else
int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
#endif'''))
-config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
- #include <sys/mman.h>
- #include <stddef.h>
- int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
+
+# On Darwin posix_madvise() has the same return semantics as plain madvise(),
+# i.e. errno is set and -1 is returned. That's not really how POSIX defines the
+# function. On the flip side, it has madvise() which is preferred anyways.
+if host_os != 'darwin'
+ config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
+ #include <sys/mman.h>
+ #include <stddef.h>
+ int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
+endif
config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
#include <pthread.h>
--
2.44.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 2/5] osdep: Make qemu_madvise() to set errno in all cases
2024-06-05 10:44 [PATCH v4 0/5] backends/hostmem: Report more errors on failures Michal Privoznik
2024-06-05 10:44 ` [PATCH v4 1/5] meson: Don't even detect posix_madvise() on Darwin Michal Privoznik
@ 2024-06-05 10:44 ` Michal Privoznik
2024-06-05 10:44 ` [PATCH v4 3/5] osdep: Make qemu_madvise() return ENOSYS on unsupported OSes Michal Privoznik
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Michal Privoznik @ 2024-06-05 10:44 UTC (permalink / raw)
To: qemu-devel
The unspoken premise of qemu_madvise() is that errno is set on
error. And it is mostly the case except for posix_madvise() which
is documented to return either zero (on success) or a positive
error number. This means, we must set errno ourselves. And while
at it, make the function return a negative value on error, just
like other error paths do.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
---
util/osdep.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/util/osdep.c b/util/osdep.c
index e996c4744a..e42f4e8121 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -57,7 +57,12 @@ int qemu_madvise(void *addr, size_t len, int advice)
#if defined(CONFIG_MADVISE)
return madvise(addr, len, advice);
#elif defined(CONFIG_POSIX_MADVISE)
- return posix_madvise(addr, len, advice);
+ int rc = posix_madvise(addr, len, advice);
+ if (rc) {
+ errno = rc;
+ return -1;
+ }
+ return 0;
#else
errno = EINVAL;
return -1;
--
2.44.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 3/5] osdep: Make qemu_madvise() return ENOSYS on unsupported OSes
2024-06-05 10:44 [PATCH v4 0/5] backends/hostmem: Report more errors on failures Michal Privoznik
2024-06-05 10:44 ` [PATCH v4 1/5] meson: Don't even detect posix_madvise() on Darwin Michal Privoznik
2024-06-05 10:44 ` [PATCH v4 2/5] osdep: Make qemu_madvise() to set errno in all cases Michal Privoznik
@ 2024-06-05 10:44 ` Michal Privoznik
2024-06-05 10:44 ` [PATCH v4 4/5] backends/hostmem: Report error on qemu_madvise() failures Michal Privoznik
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Michal Privoznik @ 2024-06-05 10:44 UTC (permalink / raw)
To: qemu-devel
Not every OS is capable of madvise() or posix_madvise() even. In
that case, errno should be set to ENOSYS as it reflects the cause
better.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
---
util/osdep.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/util/osdep.c b/util/osdep.c
index e42f4e8121..5d23bbfbec 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -64,7 +64,7 @@ int qemu_madvise(void *addr, size_t len, int advice)
}
return 0;
#else
- errno = EINVAL;
+ errno = ENOSYS;
return -1;
#endif
}
--
2.44.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 4/5] backends/hostmem: Report error on qemu_madvise() failures
2024-06-05 10:44 [PATCH v4 0/5] backends/hostmem: Report more errors on failures Michal Privoznik
` (2 preceding siblings ...)
2024-06-05 10:44 ` [PATCH v4 3/5] osdep: Make qemu_madvise() return ENOSYS on unsupported OSes Michal Privoznik
@ 2024-06-05 10:44 ` Michal Privoznik
2024-06-05 10:44 ` [PATCH v4 5/5] backends/hostmem: Report error when memory size is unaligned Michal Privoznik
2024-06-06 7:36 ` [PATCH v4 0/5] backends/hostmem: Report more errors on failures Paolo Bonzini
5 siblings, 0 replies; 8+ messages in thread
From: Michal Privoznik @ 2024-06-05 10:44 UTC (permalink / raw)
To: qemu-devel
If user sets .merge or .dump attributes qemu_madvise() is called
with corresponding advice. But it is never checked for failure
which may mislead users into thinking the attribute is set
correctly. Report an appropriate error.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
---
backends/hostmem.c | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/backends/hostmem.c b/backends/hostmem.c
index eb9682b4a8..012a8c190f 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -178,8 +178,14 @@ static void host_memory_backend_set_merge(Object *obj, bool value, Error **errp)
void *ptr = memory_region_get_ram_ptr(&backend->mr);
uint64_t sz = memory_region_size(&backend->mr);
- qemu_madvise(ptr, sz,
- value ? QEMU_MADV_MERGEABLE : QEMU_MADV_UNMERGEABLE);
+ if (qemu_madvise(ptr, sz,
+ value ? QEMU_MADV_MERGEABLE : QEMU_MADV_UNMERGEABLE)) {
+ error_setg_errno(errp, errno,
+ "Couldn't change property 'merge' on '%s'",
+ object_get_typename(obj));
+ return;
+ }
+
backend->merge = value;
}
}
@@ -204,8 +210,14 @@ static void host_memory_backend_set_dump(Object *obj, bool value, Error **errp)
void *ptr = memory_region_get_ram_ptr(&backend->mr);
uint64_t sz = memory_region_size(&backend->mr);
- qemu_madvise(ptr, sz,
- value ? QEMU_MADV_DODUMP : QEMU_MADV_DONTDUMP);
+ if (qemu_madvise(ptr, sz,
+ value ? QEMU_MADV_DODUMP : QEMU_MADV_DONTDUMP)) {
+ error_setg_errno(errp, errno,
+ "Couldn't change property 'dump' on '%s'",
+ object_get_typename(obj));
+ return;
+ }
+
backend->dump = value;
}
}
@@ -337,11 +349,19 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
ptr = memory_region_get_ram_ptr(&backend->mr);
sz = memory_region_size(&backend->mr);
- if (backend->merge) {
- qemu_madvise(ptr, sz, QEMU_MADV_MERGEABLE);
+ if (backend->merge &&
+ qemu_madvise(ptr, sz, QEMU_MADV_MERGEABLE)) {
+ error_setg_errno(errp, errno,
+ "Couldn't set property 'merge' on '%s'",
+ object_get_typename(OBJECT(uc)));
+ return;
}
- if (!backend->dump) {
- qemu_madvise(ptr, sz, QEMU_MADV_DONTDUMP);
+ if (!backend->dump &&
+ qemu_madvise(ptr, sz, QEMU_MADV_DONTDUMP)) {
+ error_setg_errno(errp, errno,
+ "Couldn't set property 'dump' on '%s'",
+ object_get_typename(OBJECT(uc)));
+ return;
}
#ifdef CONFIG_NUMA
unsigned long lastbit = find_last_bit(backend->host_nodes, MAX_NODES);
--
2.44.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 5/5] backends/hostmem: Report error when memory size is unaligned
2024-06-05 10:44 [PATCH v4 0/5] backends/hostmem: Report more errors on failures Michal Privoznik
` (3 preceding siblings ...)
2024-06-05 10:44 ` [PATCH v4 4/5] backends/hostmem: Report error on qemu_madvise() failures Michal Privoznik
@ 2024-06-05 10:44 ` Michal Privoznik
2024-06-06 5:54 ` Mario Casquero
2024-06-06 7:36 ` [PATCH v4 0/5] backends/hostmem: Report more errors on failures Paolo Bonzini
5 siblings, 1 reply; 8+ messages in thread
From: Michal Privoznik @ 2024-06-05 10:44 UTC (permalink / raw)
To: qemu-devel
If memory-backend-{file,ram} has a size that's not aligned to
underlying page size it is not only wasteful, but also may lead
to hard to debug behaviour. For instance, in case
memory-backend-file and hugepages, madvise() and mbind() fail.
Rightfully so, page is the smallest unit they can work with. And
even though an error is reported, the root cause it not very
clear:
qemu-system-x86_64: Couldn't set property 'dump' on 'memory-backend-file': Invalid argument
After this commit:
qemu-system-x86_64: backend 'memory-backend-file' memory size must be multiple of 2 MiB
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Mario Casquero <mcasquer@redhat.com>
---
backends/hostmem.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 012a8c190f..4d6c69fe4d 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -20,6 +20,7 @@
#include "qom/object_interfaces.h"
#include "qemu/mmap-alloc.h"
#include "qemu/madvise.h"
+#include "qemu/cutils.h"
#include "hw/qdev-core.h"
#ifdef CONFIG_NUMA
@@ -337,6 +338,7 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(uc);
void *ptr;
uint64_t sz;
+ size_t pagesize;
bool async = !phase_check(PHASE_LATE_BACKENDS_CREATED);
if (!bc->alloc) {
@@ -348,6 +350,14 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
ptr = memory_region_get_ram_ptr(&backend->mr);
sz = memory_region_size(&backend->mr);
+ pagesize = qemu_ram_pagesize(backend->mr.ram_block);
+
+ if (!QEMU_IS_ALIGNED(sz, pagesize)) {
+ g_autofree char *pagesize_str = size_to_str(pagesize);
+ error_setg(errp, "backend '%s' memory size must be multiple of %s",
+ object_get_typename(OBJECT(uc)), pagesize_str);
+ return;
+ }
if (backend->merge &&
qemu_madvise(ptr, sz, QEMU_MADV_MERGEABLE)) {
--
2.44.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v4 5/5] backends/hostmem: Report error when memory size is unaligned
2024-06-05 10:44 ` [PATCH v4 5/5] backends/hostmem: Report error when memory size is unaligned Michal Privoznik
@ 2024-06-06 5:54 ` Mario Casquero
0 siblings, 0 replies; 8+ messages in thread
From: Mario Casquero @ 2024-06-06 5:54 UTC (permalink / raw)
To: Michal Privoznik; +Cc: qemu-devel
This patch has been successfully tested. Try to allocate some 2M
hugepages in the host, then boot up a VM with the memory size
unaligned and backed by a file, QEMU prompts the following message:
qemu-system-x86_64: backend 'memory-backend-file' memory size must be
multiple of 2 MiB
Tested-by: Mario Casquero <mcasquer@redhat.com>
On Wed, Jun 5, 2024 at 12:45 PM Michal Privoznik <mprivozn@redhat.com> wrote:
>
> If memory-backend-{file,ram} has a size that's not aligned to
> underlying page size it is not only wasteful, but also may lead
> to hard to debug behaviour. For instance, in case
> memory-backend-file and hugepages, madvise() and mbind() fail.
> Rightfully so, page is the smallest unit they can work with. And
> even though an error is reported, the root cause it not very
> clear:
>
> qemu-system-x86_64: Couldn't set property 'dump' on 'memory-backend-file': Invalid argument
>
> After this commit:
>
> qemu-system-x86_64: backend 'memory-backend-file' memory size must be multiple of 2 MiB
>
> Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Tested-by: Mario Casquero <mcasquer@redhat.com>
> ---
> backends/hostmem.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/backends/hostmem.c b/backends/hostmem.c
> index 012a8c190f..4d6c69fe4d 100644
> --- a/backends/hostmem.c
> +++ b/backends/hostmem.c
> @@ -20,6 +20,7 @@
> #include "qom/object_interfaces.h"
> #include "qemu/mmap-alloc.h"
> #include "qemu/madvise.h"
> +#include "qemu/cutils.h"
> #include "hw/qdev-core.h"
>
> #ifdef CONFIG_NUMA
> @@ -337,6 +338,7 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
> HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(uc);
> void *ptr;
> uint64_t sz;
> + size_t pagesize;
> bool async = !phase_check(PHASE_LATE_BACKENDS_CREATED);
>
> if (!bc->alloc) {
> @@ -348,6 +350,14 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
>
> ptr = memory_region_get_ram_ptr(&backend->mr);
> sz = memory_region_size(&backend->mr);
> + pagesize = qemu_ram_pagesize(backend->mr.ram_block);
> +
> + if (!QEMU_IS_ALIGNED(sz, pagesize)) {
> + g_autofree char *pagesize_str = size_to_str(pagesize);
> + error_setg(errp, "backend '%s' memory size must be multiple of %s",
> + object_get_typename(OBJECT(uc)), pagesize_str);
> + return;
> + }
>
> if (backend->merge &&
> qemu_madvise(ptr, sz, QEMU_MADV_MERGEABLE)) {
> --
> 2.44.1
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 0/5] backends/hostmem: Report more errors on failures
2024-06-05 10:44 [PATCH v4 0/5] backends/hostmem: Report more errors on failures Michal Privoznik
` (4 preceding siblings ...)
2024-06-05 10:44 ` [PATCH v4 5/5] backends/hostmem: Report error when memory size is unaligned Michal Privoznik
@ 2024-06-06 7:36 ` Paolo Bonzini
5 siblings, 0 replies; 8+ messages in thread
From: Paolo Bonzini @ 2024-06-06 7:36 UTC (permalink / raw)
To: Michal Privoznik; +Cc: qemu-devel
Queued, thanks.
Paolo
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-06-06 7:38 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-05 10:44 [PATCH v4 0/5] backends/hostmem: Report more errors on failures Michal Privoznik
2024-06-05 10:44 ` [PATCH v4 1/5] meson: Don't even detect posix_madvise() on Darwin Michal Privoznik
2024-06-05 10:44 ` [PATCH v4 2/5] osdep: Make qemu_madvise() to set errno in all cases Michal Privoznik
2024-06-05 10:44 ` [PATCH v4 3/5] osdep: Make qemu_madvise() return ENOSYS on unsupported OSes Michal Privoznik
2024-06-05 10:44 ` [PATCH v4 4/5] backends/hostmem: Report error on qemu_madvise() failures Michal Privoznik
2024-06-05 10:44 ` [PATCH v4 5/5] backends/hostmem: Report error when memory size is unaligned Michal Privoznik
2024-06-06 5:54 ` Mario Casquero
2024-06-06 7:36 ` [PATCH v4 0/5] backends/hostmem: Report more errors on failures Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).