After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 766341 - Do not rely on memfd as it requires a fairly recent kernel
Do not rely on memfd as it requires a fairly recent kernel
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: Wayland
3.20.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2016-05-12 18:04 UTC by Emanuele Aina
Modified: 2016-06-16 16:03 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
wayland: fall back to shm_open if memfd unavailable (7.77 KB, patch)
2016-05-12 19:54 UTC, Ray Strode [halfline]
none Details | Review
wayland: fall back to shm_open if memfd unavailable (7.76 KB, patch)
2016-05-13 12:49 UTC, Ray Strode [halfline]
none Details | Review
wayland: fall back to shm_open if memfd unavailable (7.98 KB, patch)
2016-05-16 13:28 UTC, Ray Strode [halfline]
none Details | Review
wayland: fix error handling for memfd_create (3.26 KB, patch)
2016-05-16 14:50 UTC, Ray Strode [halfline]
none Details | Review
wayland: fall back to shm_open if memfd unavailable (7.84 KB, patch)
2016-05-16 14:50 UTC, Ray Strode [halfline]
none Details | Review
wayland: fix error handling for memfd_create (3.26 KB, patch)
2016-05-16 16:04 UTC, Ray Strode [halfline]
none Details | Review
wayland: fall back to shm_open if memfd unavailable (7.84 KB, patch)
2016-05-16 16:04 UTC, Ray Strode [halfline]
none Details | Review
wayland: fix error handling for memfd_create (3.26 KB, patch)
2016-05-16 18:32 UTC, Ray Strode [halfline]
committed Details | Review
wayland: fall back to shm_open if memfd unavailable (7.77 KB, patch)
2016-05-16 18:32 UTC, Ray Strode [halfline]
none Details | Review
wayland: fall back to shm_open if memfd unavailable (7.77 KB, patch)
2016-05-16 18:42 UTC, Ray Strode [halfline]
committed Details | Review

Description Emanuele Aina 2016-05-12 18:04:25 UTC
In the 3.19.x cycle the Wayland backend has been switched to memfd_create() to avoid a number of issue with tmpdir[1]. Unfortunately memfd_create() is available only from linux 3.17, while Debian stable (and many others) are stuck with 3.16 or earlier.

Reintroducing the old mechanism as a fallback if memfd_create() fails would be great.


[1] https://git.gnome.org/browse/gtk+/commit/?id=df70e28d92e7c
Comment 1 Matthias Clasen 2016-05-12 18:08:48 UTC
do you have a patch so we can see how bad this looks in practice ? If it is just a simple ifdef, I don't think there would be much opposition to this idea.
Comment 2 Emanuele Aina 2016-05-12 18:14:09 UTC
No patch at the moment, sorry.

I was thinking more about a runtime fallback if memfd_create() returns -1 and errno is set to ENOSYS rather than a ifdef.
Comment 3 Ray Strode [halfline] 2016-05-12 18:23:13 UTC
reintroducing that code would reintroduce the bug the commit was addressing, right  ?  if we care about supporting 3.16 kernels, I think a better fall back strategy would probably be to use shm_open instead (there's a patch for that on bug 761095).  But, personally, I'm not convinced fall back makes sense !  

wayland is a chance to get away from technical baggage, so it seems a little strange to me to try to work on platforms that don't offer features that have been around for years.
Comment 4 Ray Strode [halfline] 2016-05-12 18:23:59 UTC
Emanuele if you don't have an #ifdef won't it fail to build because of the #include <linux/memfd.h> ?
Comment 5 Simon McVittie 2016-05-12 19:00:16 UTC
(In reply to Ray Strode [halfline] from comment #4)
> Emanuele if you don't have an #ifdef won't it fail to build because of the
> #include <linux/memfd.h> ?

#ifdef protects you from failing to compile with an old libc, a runtime fallback on ENOSYS protects you from failing to run with an old kernel. They complement each other. Whether you need neither, one or both depends on how long ago the syscall was added to libc and the kernel.

(In reply to Ray Strode [halfline] from comment #3)
> reintroducing that code would reintroduce the bug the commit was addressing,
> right  ?

From Bug #761095:

"If it fills then desktop will start crashing with SIGBUS errors."

This is obviously not ideal, but seems better than crashing immediately? :-)

(In reply to Ray Strode [halfline] from comment #3)
> wayland is a chance to get away from technical baggage, so it seems a little
> strange to me to try to work on platforms that don't offer features that
> have been around for years.

memfds were new in Linux 3.17 (~ 18 months old) which is really fairly new. Distributions typically try to support running release N on the kernel from release N-1, because otherwise upgrading is a pain (if there's a regression in the new kernel on your hardware, it's desirable to be able to boot with the old one). In particular, in Debian 9 we're hoping to have GNOME defaulting to Wayland, but if that crashes horribly under the 3.16 kernel from Debian 8, it's unhelpful.

The other factor that makes support for older kernels desirable is that outside the x86 + nVidia/AMD/Intel desktop hardware bubble, it often isn't practical to use a new kernel, because hardware frequently doesn't work with a mainline kernel, and hardware-vendor kernels are usually something rather old patched to within an inch of its life. This is not a desirable situation, but unfortunately it's the situation the industry is in right now :-(
Comment 6 Simon McVittie 2016-05-12 19:03:37 UTC
(In reply to Ray Strode [halfline] from comment #3)
> I think a better fall
> back strategy would probably be to use shm_open instead (there's a patch for
> that on bug 761095)

That would indeed be less prone to running out of space due to random apps writing out temp files, although I believe shm_open() is implemented in terms of writing to /dev/shm, which is just another tmpfs with its own separate quota.
Comment 7 Ray Strode [halfline] 2016-05-12 19:36:01 UTC
okay i'm going to withdraw my objections, but we should add a big comment saying that the code is slated for removal.
Comment 8 Ray Strode [halfline] 2016-05-12 19:54:08 UTC
Created attachment 327740 [details] [review]
wayland: fall back to shm_open if memfd unavailable

Debian stable currently ships with a 3.16 kernel, so
it doesn't have memfd available.

This commit adds shm_open fall back code for that case
(for now).
Comment 9 Ray Strode [halfline] 2016-05-12 19:54:29 UTC
^ that's untested, can someone with debian stable try it ?
Comment 10 Emanuele Aina 2016-05-12 20:05:28 UTC
I'll give it a shot shortly, thanks!
Comment 11 Ray Strode [halfline] 2016-05-13 11:44:36 UTC
we may have to check for EPERM in addition to ENOSYS.  see this, oddly coincidental, irc log from this morning:

[07:15:26] <memeka> i fail to run GTK3 apps under wayland - it crashes with "creating shared memory file failed: Operation not permitted"
[07:16:37] <memeka> it crashes in create_shm_pool in gdkdisplay-wayland.c
[07:26:40] <halfline> memeka: what's the output of 'uname -a' ?
[07:27:11] <memeka> kernel 3.10.96, armv7l
[07:27:37] <halfline> memeka: and the version of gtk3 ?
[07:27:52] <memeka> i'm running debian, only created a root user
[07:27:55] <memeka> gtk3.20
[07:28:19] <pq> halfline, shouldn't that cause something like ENOSYS rather than EPERM?
[07:28:46] <halfline> memeka: sounds like you're hitting https://bugzilla.gnome.org/show_bug.cgi?id=766341
[07:28:49] <halfline> pq: you'd think
[07:28:55] <pq> :-p
[07:29:14] <halfline> pq: but apparently not ...his kernel is too old for memfd_create
[07:29:18] <halfline> and he's getting EPERM
[07:29:41] <pq> right, that confused me
[07:32:18] <halfline> pq: i wonder if __NR_memfd_create maps to a different syscall
[07:32:35] <halfline> pq: (say it's accidentally getting the x86 number or something)
Comment 12 Simon McVittie 2016-05-13 11:55:58 UTC
(In reply to Ray Strode [halfline] from comment #11)
> we may have to check for EPERM in addition to ENOSYS.  see this, oddly
> coincidental, irc log from this morning

I'd be tempted to ignore errno and just assume that any memfd_create() failure should result in fallback... is there any reason memfd_create() could fail where trying shm_open() wouldn't be a valid fallback?

Looking at the memfd_create man page, EMFILE/ENFILE would fail in the same way for shm_open(), ENOMEM would probably have the same result for shm_open() too, and EINVAL can only happen if it's used wrong.
Comment 13 Ray Strode [halfline] 2016-05-13 12:49:30 UTC
Created attachment 327791 [details] [review]
wayland: fall back to shm_open if memfd unavailable

Debian stable currently ships with a 3.16 kernel, so
it doesn't have memfd available.

This commit adds shm_open fall back code for that case
(for now).
Comment 14 Matthias Clasen 2016-05-15 17:03:58 UTC
Review of attachment 327791 [details] [review]:

Other than that, looks fine.

::: gdk/wayland/gdkdisplay-wayland.c
@@ +1100,3 @@
+          random_byte == '/')
+        continue;
+

This looks a bit manual and wasteful to me. Instead of throwing away most of the randomness and using only one byte at a time, I'd probably translate the whole random int into hex digits in one go. No need to look out for / and \0 either then.
Comment 15 Ray Strode [halfline] 2016-05-16 13:28:59 UTC
Created attachment 327976 [details] [review]
wayland: fall back to shm_open if memfd unavailable

Debian stable currently ships with a 3.16 kernel, so
it doesn't have memfd available.

This commit adds shm_open fall back code for that case
(for now).
Comment 16 Ray Strode [halfline] 2016-05-16 13:39:38 UTC
So attachment 327976 [details] [review] does it in a way that minimizes the number of thrown away random bits.

It might be a little over engineered, i'll do one more pass that is slightly more likely to lead to unhandled collisions but much simpler.
Comment 17 Ray Strode [halfline] 2016-05-16 13:49:27 UTC
Review of attachment 327976 [details] [review]:

::: gdk/wayland/gdkdisplay-wayland.c
@@ +1132,1 @@
   ret = syscall (__NR_memfd_create, "gdk-wayland", MFD_CLOEXEC);

so i'm not handling EINTR here, which means we could end up using yucky shm fds on memfd systems sporatically.  I'm also not remembering to use fall back for subsequent calls so users stuck with yucky shm fds will do futile memfd_create calls every time.
Comment 18 Ray Strode [halfline] 2016-05-16 14:17:22 UTC
(In reply to Ray Strode [halfline] from comment #11)
> we may have to check for EPERM in addition to ENOSYS.  see this, oddly
> coincidental, irc log from this morning:
So this turns out to be a bug in the code, I thought syscall() returned the error code (inverted), but it sets errno.
Comment 19 Ray Strode [halfline] 2016-05-16 14:50:48 UTC
Created attachment 327984 [details] [review]
wayland: fix error handling for memfd_create

We currently use syscall() directly to invoke memfd_create,
since the function isn't available in libc headers yet.

The code, though, mishandles how errors are passed from syscall().
It assumes syscall returns the error code directly (but negative),
when in fact, syscall() uses errno.

Also, the code fails to retry on EINTR.

This commit moves the handling of memfd create to a helper function,
and changes the code to use errno and handle EINTR.
Comment 20 Ray Strode [halfline] 2016-05-16 14:50:53 UTC
Created attachment 327985 [details] [review]
wayland: fall back to shm_open if memfd unavailable

Debian stable currently ships with a 3.16 kernel, so
it doesn't have memfd available.

This commit adds shm_open fall back code for that case
(for now).
Comment 21 Ray Strode [halfline] 2016-05-16 14:52:07 UTC
this round should be in better shape, I think. I'd still like Emanuele to test this before we push it, of course.
Comment 22 Ray Strode [halfline] 2016-05-16 16:02:50 UTC
Review of attachment 327984 [details] [review]:

::: gdk/wayland/gdkdisplay-wayland.c
@@ +1087,3 @@
+      ret = syscall (__NR_memfd_create, "gdk-wayland", MFD_CLOEXEC);
+    }
+  while (ret < 0 && errno != EINTR);

that should be == EINTR not != EINTR
Comment 23 Ray Strode [halfline] 2016-05-16 16:04:39 UTC
Created attachment 327992 [details] [review]
wayland: fix error handling for memfd_create

We currently use syscall() directly to invoke memfd_create,
since the function isn't available in libc headers yet.

The code, though, mishandles how errors are passed from syscall().
It assumes syscall returns the error code directly (but negative),
when in fact, syscall() uses errno.

Also, the code fails to retry on EINTR.

This commit moves the handling of memfd create to a helper function,
and changes the code to use errno and handle EINTR.
Comment 24 Ray Strode [halfline] 2016-05-16 16:04:52 UTC
Created attachment 327993 [details] [review]
wayland: fall back to shm_open if memfd unavailable

Debian stable currently ships with a 3.16 kernel, so
it doesn't have memfd available.

This commit adds shm_open fall back code for that case
(for now).
Comment 25 Matthias Clasen 2016-05-16 17:41:35 UTC
Review of attachment 327992 [details] [review]:

Looks good
Comment 26 Matthias Clasen 2016-05-16 17:42:20 UTC
Review of attachment 327993 [details] [review]:

thanks for bearing with my pedantic review... looks fine to me know (modulo testing).
Comment 27 Ray Strode [halfline] 2016-05-16 18:23:38 UTC
Review of attachment 327992 [details] [review]:

::: gdk/wayland/gdkdisplay-wayland.c
@@ +1092,3 @@
+    {
+      g_critical (G_STRLOC ": creating shared memory file failed: %m");
+      return NULL;

still needs work, this shouldn't say NULL, but should say -1.

@@ -1090,3 @@
-  ret = syscall (__NR_memfd_create, "gdk-wayland", MFD_CLOEXEC);
-
-  if (ret < 0)

we ended up inadvertently losing error handling here.
Comment 28 Ray Strode [halfline] 2016-05-16 18:32:39 UTC
Created attachment 328002 [details] [review]
wayland: fix error handling for memfd_create

We currently use syscall() directly to invoke memfd_create,
since the function isn't available in libc headers yet.

The code, though, mishandles how errors are passed from syscall().
It assumes syscall returns the error code directly (but negative),
when in fact, syscall() uses errno.

Also, the code fails to retry on EINTR.

This commit moves the handling of memfd create to a helper function,
and changes the code to use errno and handle EINTR.
Comment 29 Ray Strode [halfline] 2016-05-16 18:32:46 UTC
Created attachment 328003 [details] [review]
wayland: fall back to shm_open if memfd unavailable

Debian stable currently ships with a 3.16 kernel, so
it doesn't have memfd available.

This commit adds shm_open fall back code for that case
(for now).
Comment 30 Ray Strode [halfline] 2016-05-16 18:42:20 UTC
Review of attachment 328003 [details] [review]:

eek every time i got close the browser tab with the patch i spot something new.

::: gdk/wayland/gdkdisplay-wayland.c
@@ +1102,3 @@
+           * See bug 766341
+           */
+          if (ret < 0 && errno == -ENOSYS)

should be ENOSYS not -ENOSYS
Comment 31 Ray Strode [halfline] 2016-05-16 18:42:52 UTC
Created attachment 328005 [details] [review]
wayland: fall back to shm_open if memfd unavailable

Debian stable currently ships with a 3.16 kernel, so
it doesn't have memfd available.

This commit adds shm_open fall back code for that case
(for now).
Comment 32 Matthias Clasen 2016-05-16 19:18:44 UTC
Review of attachment 328005 [details] [review]:

Stil looks good to me

::: gdk/wayland/gdkdisplay-wayland.c
@@ +1125,3 @@
   if (ret < 0)
+    g_critical (G_STRLOC ": creating shared memory file failed: %m (fallback: %s)",
+                force_shm_open? "true" : "false");

Instead of the meaningless 'fallback', I might reword this as

"creating shared memory file (%s) failed: %m", force_shm_open ? "shm_open" : "memfd_create"
Comment 33 Matthias Clasen 2016-05-16 19:19:31 UTC
Review of attachment 328002 [details] [review]:

still looks good to me
Comment 34 Matthias Clasen 2016-05-18 16:45:37 UTC
Emanuele, do these patches work for you ?
Comment 35 Emanuele Aina 2016-05-19 06:54:03 UTC
Sorry, I got massively distracted by other things and I won't be able to test before the end of next week. :/
Comment 36 Matthias Clasen 2016-05-19 13:15:43 UTC
no worries; the patches will patiently wait here for your testing
Comment 37 Ray Strode [halfline] 2016-05-31 02:01:31 UTC
just a friendly ping, no worries if you're too busy.
Comment 38 Ray Strode [halfline] 2016-06-15 19:02:42 UTC
Emanuele, just another gentle nudge. :-)
Comment 39 Emanuele Aina 2016-06-16 14:55:57 UTC
Sorry for taking so long.

Tested with kernel 3.14, worked flawlessy, thanks!
Comment 40 Ray Strode [halfline] 2016-06-16 16:03:05 UTC
Attachment 328002 [details] pushed as bb2ca3b - wayland: fix error handling for memfd_create
Attachment 328005 [details] pushed as 2f3cb31 - wayland: fall back to shm_open if memfd unavailable