Hi Youssef,Sandbox restrictions that exist today should be preserved.If a thread is running at priority PT in a process with priority PP1, it should also be running at priority PT after changing the process' priority to PP2 and then back to PP1. The OS can support this by keeping track of priorities set for each thread independently from the effective priority of each thread.Concrete example:Thread T1 in Process P1, [t1 requested priority = normal, t1 effective priority = normal, p1 priority = normal]Priority is set to Background for Process P1, [t1 requested priority = normal, t1 effective priority = background, p1 priority = background]Priority is set to Normal Process P1, [t1 requested priority = normal, t1 effective priority = normal, p1 priority = normal]Do you think this should be implemented in Chrome OS instead of Chrome Browser?Thanks,FrançoisOn Wed, Aug 3, 2022 at 4:00 PM Youssef Esmat <yousse...@google.com> wrote:Hi All,Picking this up again. When you say "kernel do this instead", what do you mean by "this"?I do agree that ideally the browser process should not have to manage the different cgroups (cpuset/cpu) and the nice values. That could translate to a different set of APIs exposed by the OS where the browser process could tell the OS that the renderer process should be in "foreground" or "background" and the OS would place the process in the correct cgroups. We could also have a similar API at the thread level allowing some threads to be higher priority than others.However, the second part of the problem is, which process is allowed to make these calls to the OS? The renderer process is currently sandboxed. So should the browser process make the calls on the behalf of the renderer process or should the renderer process threads be allowed to change their own priorities?Thanks,YoussefOn Tue, Jul 5, 2022 at 3:27 PM Gabriel Charette <g...@google.com> wrote:Why can't the kernel do this instead of the browser process though?i.e. SetCurrenThreadPriority() should merely be a hint to the OS which it should then apply based on context (process state -- set by the browser process)On Wed, Jun 29, 2022 at 12:52 PM Youssef Esmat <yousse...@google.com> wrote:The problem today is that the cpuset cgroup is tied to thread priority and not a property of the process. If the entire process is either in urgent or non-urgent this would be easy by writing the process PID to the cgroup.procs file. However, a high priority thread is placed in the urgent cgroup whereas a low priority thread is placed in the non-urgent cgroup. So we have two factors that move the threads cpuset cgroup:
- The thread priority
- The process state (renderer is foreground or background).
So we need some entity to keep track of both the thread priority and the process state and set the cgroup accordingly.In the past, we tried setting the priority from the child process, but it didn't work well because a background child process would take too much time to process the Mojo message asking it to increase its priorityToday this rule does not exactly hold in all cases. The threadpool in the renderer process sets the thread priorities by calling SetCurrentThreadPriority which adjusts the nice values but fails to adjust the cgroup because of the sandbox.I think this is the part we need to fix. Only one entity can be in charge of thread priority and process state. For now that should mean the browser process and that when a new thread is created in the renderer the browser process needs to be called to adjust the priority and cgroup value.--On Wed, Jun 29, 2022 at 8:19 AM François Doray <fdo...@google.com> wrote:Hi Youssef,Today, on all platforms, the browser process is responsible for setting the priority of child processes [code]. In the past, we tried setting the priority from the child process, but it didn't work well because a background child process would take too much time to process the Mojo message asking it to increase its priority. Therefore, I suggest that we keep the call to set the priority of child processes in the browser process.Ideally, the existing API to set the c-group of a process by writing to /sys/fs/cgroup/cpuset/ would be adjusted such that moving a process from the "normal" to the "non-urgent" group and moving a process from the "non-urgent" to the "normal" group would be inverse operations (applying both operations brings all threads to their initial state).We can adjust thread properties from Chrome to palliate for the fact that moving a process from "normal" > "non-urgent" and moving a process from "non-urgent" > "normal" aren't inverse operations. However, since nothing prevents thread creation, destruction or priority adjustment while Chrome is adjusting thread properties, it's hard to be convinced that this solution will be correct in all cases today and in the future. This is why I would like to understand what's required to fix the /sys/fs/cgroup/cpuset/ API instead of implementing thread priority adjustments inside Chrome.Have a nice day,FrançoisOn Tue, Jun 28, 2022 at 4:30 PM Youssef Esmat <yousse...@google.com> wrote:Thanks for starting this thread Francois!I agree that a lot of this should be pushed to OS wherever possible. Digging deeper on your suggestion, when you say handled by the OS do you mean the OS will handle the call from the renderer process or from the browser or both?On Tue, Jun 28, 2022 at 12:45 PM François Doray <fdo...@google.com> wrote:Hi!On ChromeOS, PlatformThread::SetCurrentThreadPriority() doesn't work from renderers due to restrictions on setting c-groups and nice values. This dry run on this CL highlights the failures. Priority is set correctly only when the operation is proxied through the browser process via RenderMessageFilter.SetThreadPriority.A contributor from Intel proposes using c-groups to throttle background renderers [CL]. Under the hood, changing the c-group of a process changes the c-group of all its threads, effectively overriding any c-group previously set via RenderMessageFilter.SetThreadPriority. The contributor suggests re-applying c-groups previously set via RenderMessageFilter.SetThreadPriority when foregrounding a process.Example:Initial => t1 [normal], t2 [display], t3 [background] *Process is backgrounded => t1 [background], t2 [background], t3 [background]Process is foregrounded => t1 [normal], t2 [normal], t3 [normal]Thread priorities are re-applied => t1 [normal], t2 [display], t3 [background]It is possible to implement this solution without race by performing all process and thread priority changes from the same sequence in the browser process.However, it seems that the correct layer to implement this is inside the OS, not in Chrome. @Youssef Esmat as ChromeOS expert: What are the implications of implementing this in the OS instead of in Chrome?Have a nice day,François
You received this message because you are subscribed to the Google Groups "chrome-scheduler" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chrome-schedul...@google.com.
To view this discussion on the web visit https://groups.google.com/a/google.com/d/msgid/chrome-scheduler/CALUeGD3HBxAxoyug92g%3Dfx5Oxcu%3DcoE6G4zdFSVT4GG%2BCzji5g%40mail.gmail.com.
Hi All,Picking this up again. When you say "kernel do this instead", what do you mean by "this"?
I do agree that ideally the browser process should not have to manage the different cgroups (cpuset/cpu) and the nice values. That could translate to a different set of APIs exposed by the OS where the browser process could tell the OS that the renderer process should be in "foreground" or "background" and the OS would place the process in the correct cgroups. We could also have a similar API at the thread level allowing some threads to be higher priority than others.However, the second part of the problem is, which process is allowed to make these calls to the OS? The renderer process is currently sandboxed. So should the browser process make the calls on the behalf of the renderer process or should the renderer process threads be allowed to change their own priorities?
Thanks for clarifying and I think we are on the same page. My feeling right now is we should move this logic to the OS (for chromeOS this looks like resrouceD because of other work going on with cgroups over there).This will mean adding new apis to manage process/thread priorities. This API will not be available to sandboxed processes. Meaning that calling this API from the renderer will result in a no-op. Today, setting the thread priority in the renderer is broken because its a semi no-op, the nice values take affect and the cgroup changes to not. Moving forward the whole API will be a no-op. Do we agree there?