__GL_YIELD possibly not defaulting to using sched_yield()

nvidia readme files say __GL_YIELD defaults to using sched_yield() but can be set to NOTHING (don’t yield) or USLEEP (use sleep()).

Around 381.09 timeframe, this was correct because __GL_YIELD definitely used sched_yield() back then according to gdb.

Now nvidia seems to silently default to NOTHING with no documented way of setting it to use sched_yield(). I verified this using gdb on gnome-shell process.

For further testing, I made sure glibc 2.26 isn’t mangling sched_yield() though a plan C example with sched_yield() in main and another example using pthreads. So it seems sched_yield() can still be called. Nvidia driver just doesn’t call it anymore.

I am using nvidia driver 387.22
Would a developer mind taking a look please?

Very interesting issue, but i cannot reproduce it. How did you inspect it?
Could you let me know the exact steps to reproduce your issue?

I’ve just tested by using LD_PRELOAD as follows.
(I’m using 387.22 too)

$ cat< src.c
#include <stdio.h>
int sched_yield(void)
return 0;

$ gcc -shared -fPIC src.c -o lib.so

$ unset __GL_YIELD

LD_PRELOAD=./lib.so glxgears __GL_YIELD=NOTHING LD_PRELOAD=./lib.so glxgears

The behavior seems to be same as the documented.

  1. install the latest driver and start gnome-shell.
  2. Start a 3d game that uses glx and opengl or glxgears and make sure they are constantly drawning (not paused). It needs to be windowed. full screen bypasses the compositor.
  3. note the cpu usage of gnome-shell.
  4. keep the game or glxgears open and switch to tty (ctrl-alt-f4) and back.
  5. note the cpu usage of gnome-shell is constantly 20% higher.
  6. su -c ‘gdb --batch --ex “thread apply all bt full” -pid=pidof gnome-shell &>bt.txt’

Notice the lack of sched_yield() in bt.txt.

now install a very old driver, repeat the above steps, notice sched_yield() calls are there in the gdb call and the cpu usage is not higher (no spikes).

I tried your test. It did not print “yield”.

I’m using libglvnd and nvidia-utils from Arch Linux.

Thanks. But, I could not still reproduce your issue.

You mean that glxgears doesn’t call sched_yield() even though __GL_YIELD is unset?

I think we need more simple and clear step to reproduce your issue.

Oops. I forgot to unset __GL_YIELD before running your test.
Ok, it does print ‘yield’ now. But how come sched_yield() is no longer in gnome-shell bt?
Is there any way to know why the sudden rise in cpu usage in gnome-shell if I switch tty while running a game? The CPU usage goes back down if I alt-f2 -> r.
I showed Gnome developers the perf data and backtraces but they can’t do anything without the debug symbols missing in nvidia libraries.

We’re not aware of any regression regarding __GL_YIELD. pyopyopyo’s comment #2 matches my observations: __GL_YIELD is still behaving as expected.


su -c ‘gdb --batch --ex “thread apply all bt full” -pid=pidof gnome-shell &>bt.txt’

isn’t proof that sched_yield isn’t getting called, all it proves is that sched_yield isn’t being called at the exact time when you run the command.

I’m unclear on what the bug is supposed to be, exactly. Can you please describe the behavior you’re observing, and explain how it differs from what you would expect (or were observing before), with detailed - and minimal - instructions to reproduce?
If it appears to be a driver regression, please also pinpoint which release appears to be responsible.


ahuillet, I can post reproduction steps:

  1. Start gnome-shell.
  2. Open a 3d game. It has to be windowed (not full screen since full screen bypasses compositor).
  3. Open gnome-system-monitor and note the gnome-shell cpu usage. it should be relatively low (2 to 3%).
  4. Ctrl-alt-f4 to switch to tty and then ctrl-alt-f1 back to the gnome session (Xorg).
  5. Notice the CPU usage of gnome-shell is stuck at ~20%.

(Alt-f2 -> r) which re-executes the window manager brings back the CPU usage down to 2%. Closing the active 3d application or game also brings down the CPU usage.

Alternatively, setting __GL_YIELD to usleep stops the CPU spikes.
This started around 381.09 or just after it when gl threading was turned off by default again.

What distribution (and specifically what gnome-shell version), and what GPU?
What discussions have you had with the gnome-shell developers so far that led them to conclude that it was probably a NVIDIA bug? If you still have the ‘perf’ data that prominently shows the NVIDIA driver as responsible for the CPU usage, maybe we can decode the stack and investigate from there.

What does “alt-f2 -> r” do exactly?
When you talk about setting __GL_YIELD to usleep - where do you do that? Are you setting it for the 3D game or for gnome-shell? Also, what 3D game specifically are you using for your test?

Alt-f2 brings up the ‘enter a command’ dialog in gnome-shell. type r in the dialog and press Enter to re-execute the Gnome window manager. It is similar to restarting KWin on KDE.
I set __GL_YIELD in /etc/environment and rebooted.
I’ll send you a link to the game via PM.

  • __GL_YIELD="USLEEP" is set in /etc/environment so it affects both gnome-shell and the game.
  • Issue was on 730GT and persists on 1050TI GTX.
  • I am using gnome-shell/mutter 3.26.2 on arch linux
  • I showed the decoded perf data and previously a gdb.txt file. Based upon the perf data, they suggested I report it to NVIDIA.
  • Alt-f2 brings up the 'enter a command' dialog in gnome-shell. type r in the dialog and press Enter to re-execute the Gnome window manager. It gets re-executed under same PID so no session data loss.
  • I'll attach the perf data that I had emailed the Gnome developer to this thread.

perfdata.zip (292 KB)

I have tried your reproduction steps with EternalLands on mutter 3.26.2 on ArchLinux, and cannot reproduce your findings.
When EternalLands is running, gnome-shell consumes about 20% CPU, and that doesn’t change following a VT-switch and back.

Does the 20% go down if you globally set __GL_THREADED_OPTIMIZATIONS=0?
gnome-shell barely uses any CPU here unless I’m in the middle of alt-tabbing between windows.
In any case, thank for checking. I suppose I will just stick to __GL_YIELD=“USLEEP”.