Hello,
On Fri, Feb 24, 2017 at 05:27:14PM +0000, Daniel P. Berrange wrote:
> diff --git a/util/oslib-posix.c b/util/oslib-posix.c
> index 35012b9..2a5bb93 100644
> --- a/util/oslib-posix.c
> +++ b/util/oslib-posix.c
> @@ -355,7 +355,20 @@ void os_mem_prealloc(int fd, char *area, size_t memory,
> Error **errp)
>
> /* MAP_POPULATE silently ignores failures */
> for (i = 0; i < numpages; i++) {
> - memset(area + (hpagesize * i), 0, 1);
> + /*
> + * Read & write back the same value, so we don't
> + * corrupt existinng user/app data that might be
> + * stored.
> + *
> + * 'volatile' to stop compiler optimizing this away
> + * to a no-op
> + *
> + * TODO: get a better solution from kernel so we
> + * don't need to write at all so we don't cause
> + * wear on the storage backing the region...
> + */
It would be better that if MAP_POPULATE failed like mlock does, at
least for those get_user_pages errors like -ENOMEM that are already a
retval for mmap it sounds weird that it's not being forwarded. It'd be
enough to call do_munmap to rollback all mmap work before returning
-ENOMEM from mmap instead of succees.
-EFAULT or other get_user_pages errors are more troublesome, as mmap
wouldn't otherwise return -EFAULT, but those would generally be qemu
bugs or hardware errors and MAP_POPULATE I doubt is meant to be a
debug/robustness aid. All we care about here is memory resource
management and not to risk -ENOMEM at runtime and immediate peak
performance. So perhaps a kernel patch that forwards -ENOMEM from
__mm_populate to mmap retval would be enough to make it usable?
> + volatile char val = *(area + (hpagesize * i));
> + *(area + (hpagesize * i)) = val;
It's not "var" that should be volatile, nor the pointer, but only the
memory area you write to, because the write to the memory are is the
only thing we care about.
If "val" is volatile gcc could read the memory area and cache the
value of the memory area, write it into the volatile var, then read
the volatile var again, compare it with the cached value and skip the
write to the memory if it's equal. In practice it's likely not doing
that, and making var volatile has the same effect, so it's probably
only a theoretical issue of course.
I would suggest this to correct it (untested):
char *tmparea = area + (hpagesize * i);
*(volatile char *)tmparea = *tmparea;
Thanks,
Andrea