mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Avoid busy work in TCP processor.
TCP processor is woken up on unlock if the lock is held by a user syscall goroutine. In such instances there is no need to wake up the processor from the dispatcher or requeue an endpoint that may have more pending endpoints in the processor loop. The former causes a useless processor wakeup which spins needlessly and the latter keeps the current processor spinning till the lock is released. PiperOrigin-RevId: 474664843
This commit is contained in:
committed by
gVisor bot
parent
fc0e4d0a03
commit
41c1b78b2b
@@ -326,9 +326,10 @@ func (p *processor) start(wg *sync.WaitGroup) {
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected tcp state in processor: %v", state))
|
||||
}
|
||||
// If there are more segments to process then
|
||||
// If there are more segments to process and the
|
||||
// endpoint lock is not held by user then
|
||||
// requeue this endpoint for processing.
|
||||
if !ep.segmentQueue.empty() {
|
||||
if !ep.segmentQueue.empty() && !ep.isOwnedByUser() {
|
||||
p.epQ.enqueue(ep)
|
||||
}
|
||||
}
|
||||
@@ -443,7 +444,12 @@ func (d *dispatcher) queuePacket(stackEP stack.TransportEndpoint, id stack.Trans
|
||||
return
|
||||
}
|
||||
|
||||
d.selectProcessor(id).queueEndpoint(ep)
|
||||
// Only wakeup the processor if endpoint lock is not held by a user
|
||||
// goroutine as endpoint.UnlockUser will wake up the processor if the
|
||||
// segment queue is not empty.
|
||||
if !ep.isOwnedByUser() {
|
||||
d.selectProcessor(id).queueEndpoint(ep)
|
||||
}
|
||||
}
|
||||
|
||||
// selectProcessor uses a hash of the transport endpoint ID to queue the
|
||||
|
||||
@@ -605,6 +605,12 @@ func calculateAdvertisedMSS(userMSS uint16, r *stack.Route) uint16 {
|
||||
return maxMSS
|
||||
}
|
||||
|
||||
// isOwnedByUser() returns true if the endpoint lock is currently
|
||||
// held by a user(syscall) goroutine.
|
||||
func (e *endpoint) isOwnedByUser() bool {
|
||||
return e.ownedByUser.Load() == 1
|
||||
}
|
||||
|
||||
// LockUser tries to lock e.mu and if it fails it will check if the lock is held
|
||||
// by another syscall goroutine. If yes, then it will goto sleep waiting for the
|
||||
// lock to be released, if not then it will spin till it acquires the lock or
|
||||
|
||||
Reference in New Issue
Block a user