]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: only poll network from one P at a time in findRunnable
authorCarlos Amedee <carlos@golang.org>
Wed, 30 Apr 2025 19:17:45 +0000 (15:17 -0400)
committerCarlos Amedee <carlos@golang.org>
Tue, 13 May 2025 01:35:25 +0000 (18:35 -0700)
This change reintroduces CL 564197. It was reverted due to a failing
benchmark. That failure has been resolved.

For #65064

Change-Id: Ic88841d2bc24c2717ad324873f0f52699f21dc66
Reviewed-on: https://go-review.googlesource.com/c/go/+/669235
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
src/runtime/proc.go
src/runtime/runtime2.go

index 9753ba5378226dfc687f783671a7aaecf03c8d57..1ca800c5fdb0de599bb65b4c69a2590cf95ac9e6 100644 (file)
@@ -3396,8 +3396,12 @@ top:
        // blocked thread (e.g. it has already returned from netpoll, but does
        // not set lastpoll yet), this thread will do blocking netpoll below
        // anyway.
-       if netpollinited() && netpollAnyWaiters() && sched.lastpoll.Load() != 0 {
-               if list, delta := netpoll(0); !list.empty() { // non-blocking
+       // We only poll from one thread at a time to avoid kernel contention
+       // on machines with many cores.
+       if netpollinited() && netpollAnyWaiters() && sched.lastpoll.Load() != 0 && sched.pollingNet.Swap(1) == 0 {
+               list, delta := netpoll(0)
+               sched.pollingNet.Store(0)
+               if !list.empty() { // non-blocking
                        gp := list.pop()
                        injectglist(&list)
                        netpollAdjustWaiters(delta)
index da6791f9d28547c54d0ef88a8da23b42929b6c55..920437882daf47e837b268c468270c7cc40192b6 100644 (file)
@@ -760,9 +760,10 @@ type p struct {
 }
 
 type schedt struct {
-       goidgen   atomic.Uint64
-       lastpoll  atomic.Int64 // time of last network poll, 0 if currently polling
-       pollUntil atomic.Int64 // time to which current poll is sleeping
+       goidgen    atomic.Uint64
+       lastpoll   atomic.Int64 // time of last network poll, 0 if currently polling
+       pollUntil  atomic.Int64 // time to which current poll is sleeping
+       pollingNet atomic.Int32 // 1 if some P doing non-blocking network poll
 
        lock mutex