You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a stream gets a DataFrame and nothing reads data from the stream of the connection, it can't close the connection and leads to memory leak.
When I'm working on https://github.com/cri-o/cri-o memory leak issue, I found that in the situation above, spdy stream server causes memory leak.
The leak happens when it tries to close the connection, and it waits wg.Wait() forever.
// wait for all frame handler workers to indicate they've drained their queues
// before handling the go away frame
wg.Wait()
The cause of the issue is that it can't finish frameHandler() because of the deadlock.
There are some workers calling frameHandler(), and wg.Add() when each worker starts and wg.Done() when each worker is done.
// Ensure frame queue is drained when connection is closed
gofunc(frameQueue*PriorityFrameQueue) {
<-s.closeChan
frameQueue.Drain()
}(frameQueues[i])
wg.Add(1)
gofunc(frameQueue*PriorityFrameQueue) {
// let the WaitGroup know this worker is done
deferwg.Done()
s.frameHandler(frameQueue, newHandler)
}(frameQueues[i])
}
DataFrames queued in a PriorityFrameQueue are processed in frameHandler() and if it is a DataFrame, it is handled by dataFrameHandler() ( = handleDataFrame()).
In the function, it blocks until either the stream is closed or something reads the stream dataChan (e.g. something calls Read() or ReadData())
Otherwise the function can't finish, which means frameHandler() also can't finish, and it never calls wg.Done().
debugMessage("(%p) (%d) Data frame not sent (stream shut down)", stream, stream.streamId)
casestream.dataChan<-frame.Data:
debugMessage("(%p) (%d) Data frame sent", stream, stream.streamId)
}
stream.dataLock.RUnlock()
}
If nothing reads the data from the stream, the only way of blocking it is to close the stream.
However streams in a connection are closed after wg.Wait().
When a stream gets a
DataFrame
and nothing reads data from the stream of the connection, it can't close the connection and leads to memory leak.When I'm working on https://github.com/cri-o/cri-o memory leak issue, I found that in the situation above, spdy stream server causes memory leak.
The leak happens when it tries to close the connection, and it waits
wg.Wait()
forever.spdystream/connection.go
Lines 392 to 394 in 57d1ca2
The cause of the issue is that it can't finish
frameHandler()
because of the deadlock.There are some workers calling
frameHandler()
, andwg.Add()
when each worker starts andwg.Done()
when each worker is done.spdystream/connection.go
Lines 317 to 333 in 57d1ca2
DataFrame
s queued in aPriorityFrameQueue
are processed inframeHandler()
and if it is aDataFrame
, it is handled bydataFrameHandler()
( =handleDataFrame()
).In the function, it blocks until either the stream is closed or something reads the stream
dataChan
(e.g. something callsRead()
orReadData()
)Otherwise the function can't finish, which means
frameHandler()
also can't finish, and it never callswg.Done()
.spdystream/connection.go
Lines 598 to 607 in 57d1ca2
If nothing reads the data from the stream, the only way of blocking it is to close the stream.
However streams in a connection are closed after
wg.Wait()
.spdystream/connection.go
Lines 394 to 409 in 57d1ca2
The simplest fix is to move
stream.closeRemoteChannels()
beforewg.Wait()
, but I'm unsure if it causes other race condition errors.The text was updated successfully, but these errors were encountered: