]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: only poll network from one P at a time in findRunnable
authorIan Lance Taylor <iant@golang.org>
Thu, 15 Feb 2024 01:54:00 +0000 (17:54 -0800)
committerMichael Pratt <mpratt@google.com>
Tue, 22 Apr 2025 09:49:42 +0000 (02:49 -0700)
For #65064

Change-Id: Ifecd7e332d2cf251750752743befeda4ed396f33
Reviewed-on: https://go-review.googlesource.com/c/go/+/564197
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Artur M. Wolff <artur.m.wolff@gmail.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
src/runtime/proc.go
src/runtime/runtime2.go

index db7a5b2bb1c654568139595b070de4c9dab24c3f..44c6d0b4e43ca3a3e9202c5df620bc4d3a8e60aa 100644 (file)
@@ -3387,8 +3387,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 e56b45053e122e9fc3046b200a438e997ff5aa47..27d14b890bd654708d7f630c4621c1e34fe738f3 100644 (file)
@@ -757,9 +757,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