aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/proc.go8
-rw-r--r--src/runtime/runtime2.go7
2 files changed, 10 insertions, 5 deletions
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 9753ba5378..1ca800c5fd 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -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)
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index da6791f9d2..920437882d 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -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