-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
Hi,
as described in #1028 the window content of VM windows get sometimes
trashed.
The problem is that the pages with the windows content need to be pinned
to a physical page when being mapped with xc_map_foreign_pages. To
archive this the current code calls mlock(). Unfortunately this only
ensures that the page doesn't get swapped out but the kernel can still
move the page.
- From [0]:
> A page that has been locked into memory with a call like mlock() is
> required to always be physically present in the system's RAM. [...].
> But there is nothing that requires a locked page to always be present
> in the same place; the kernel is free to move a locked page if the
> need arises.
So when a VM window looks corrupted the VM kernel has moved the page and
it has now a new physical address and in dom0 you now see the new
content of the old physical page.
If you want to monitor the effect you can use the attached script. It
shows the mapping of virtual addresses to physical addresses of a given
memory range for a given process. So call strace on Xorg to get the
mlock() call and pass those arguments to the script. Now either wait
until you have "luck" or provoke it by
'echo 1 > /proc/sys/vm/compact_memory'
Unfortunately the patch from [0] didn't got into the kernel, so there
is no easy way to pin a page similar to mlock().
One workaround is to disable memory compactation of unevictable (i.e.
mlocked) pages:
echo 0 > /proc/sys/vm/compact_unevictable_allowed
This has two downsides:
a) While I didn't observed the effect anymore with this setting I'm not
sure if this prevents all cases in which the kernel moves pages. (A
bit grepping suggest that it ignores this flag when allocating
hugepages but I'm not sure about this.)
b) Given that VMs in Qubes are often low on memory I'm a bit uneasy to
change memory management options without knowing the side effects.
Properly pinning is not that easy since there seems to be no way to flag
a page as unmovable. The common way seems to be to call
get_user_pages() to increment the reference counter and thereby pin it.
The problem is that then the u2mfn module needs to be changed
significantly to track allocation and deallocation since else the pages
never get freed.
If somebody (who is familiar with the linux kernel) knows another
solution this would be great.
#2185 mentions that you want do get rid of u2mfn anyway. How does the
new solution should work?
Unless somebody knows a better way to lock pages the best thing for R3.2
is probably to use the above mentioned work-around and implement a
better solution in R4.
HW42
[0]:
https://lwn.net/Articles/600502/
-----BEGIN PGP SIGNATURE-----
iQIcBAEBCgAGBQJXmk+pAAoJEOSsySeKZGgWfgsQAKtHepI4CTnjtDx4xLoZlYAq
l3kdbtU7JEWERVnGZyAx8jwE5lL0olJQmf43eXID5bjuBFgXucYFKWsQFYC2rzjJ
EIuRuVdk1FjyXQc5T72Vtj1xJtXL07PByKgCao3GeL0iCaJDCZAR0w9Yb1l5uTsP
LAyR5GUmLHzqlv1S/qrmrCVCflENzWG309BdiPL6X203UaS8yOGgo5SY4MTiz9dL
1jPDwam/eH0Sguh7nBYJqhek5E3Dz1Vh7c2x7vOZXOgrxdU4NpOwFVcYEgY3m/9D
3ZobtaF+QDXU8VDjpapNLOXwL7IzKcI+lMj7lxIRiXU9CcfaiVWQsraWlHv6JYix
myetT04F7zTEu2YX+/9izn9EQ7u0y40K2/5918m8pRdWZjPJKtked0Z1R7+xOgpZ
+ZUn6hbHwZT8PzxtW3TKWmiHBMdjmlSFDNnqXcM+T+LV7JKwxf6/QKg9mYtqiAKI
mtr/BjXvPesfsIVY5ArHFf4DDjdX4Inuip1EC9EC0Scp4RSmZqX/9lcUUfexkr1w
yCVxATHi2wk5y22KNd62pVwxsIbaskEMVfHDbzrtD/VXPgLjGipyZogdxAIX6mWM
bC7FiZOD3FNyp49TH6KdNeM8mcjoXgj2CFZ++qTRoRsrtJaWV6jbDjaUsVydPauE
7diqcF+NyrSwT2meuMG/
=7zde
-----END PGP SIGNATURE-----