mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Prevent memory leaks in ilist
When list elements are removed from a list but not discarded, it becomes important to invalidate the references they hold to their former neighbors to prevent memory leaks. PiperOrigin-RevId: 299412421
This commit is contained in:
committed by
gVisor bot
parent
18d41cf153
commit
6fa5cee82c
+6
-2
@@ -169,8 +169,9 @@ func (l *List) InsertBefore(a, e Element) {
|
||||
|
||||
// Remove removes e from l.
|
||||
func (l *List) Remove(e Element) {
|
||||
prev := ElementMapper{}.linkerFor(e).Prev()
|
||||
next := ElementMapper{}.linkerFor(e).Next()
|
||||
linker := ElementMapper{}.linkerFor(e)
|
||||
prev := linker.Prev()
|
||||
next := linker.Next()
|
||||
|
||||
if prev != nil {
|
||||
ElementMapper{}.linkerFor(prev).SetNext(next)
|
||||
@@ -183,6 +184,9 @@ func (l *List) Remove(e Element) {
|
||||
} else {
|
||||
l.tail = prev
|
||||
}
|
||||
|
||||
linker.SetNext(nil)
|
||||
linker.SetPrev(nil)
|
||||
}
|
||||
|
||||
// Entry is a default implementation of Linker. Users can add anonymous fields
|
||||
|
||||
@@ -101,8 +101,6 @@ func (c *DirentCache) remove(d *Dirent) {
|
||||
panic(fmt.Sprintf("trying to remove %v, which is not in the dirent cache", d))
|
||||
}
|
||||
c.list.Remove(d)
|
||||
d.SetPrev(nil)
|
||||
d.SetNext(nil)
|
||||
d.DecRef()
|
||||
c.currentSize--
|
||||
if c.limit != nil {
|
||||
|
||||
@@ -143,7 +143,10 @@ func (i *Inotify) Read(ctx context.Context, _ *File, dst usermem.IOSequence, _ i
|
||||
}
|
||||
|
||||
var writeLen int64
|
||||
for event := i.events.Front(); event != nil; event = event.Next() {
|
||||
for it := i.events.Front(); it != nil; {
|
||||
event := it
|
||||
it = it.Next()
|
||||
|
||||
// Does the buffer have enough remaining space to hold the event we're
|
||||
// about to write out?
|
||||
if dst.NumBytes() < int64(event.sizeOf()) {
|
||||
|
||||
@@ -38,11 +38,14 @@ func (e *EventPoll) afterLoad() {
|
||||
}
|
||||
}
|
||||
|
||||
for it := e.waitingList.Front(); it != nil; it = it.Next() {
|
||||
if it.id.File.Readiness(it.mask) != 0 {
|
||||
e.waitingList.Remove(it)
|
||||
e.readyList.PushBack(it)
|
||||
it.curList = &e.readyList
|
||||
for it := e.waitingList.Front(); it != nil; {
|
||||
entry := it
|
||||
it = it.Next()
|
||||
|
||||
if entry.id.File.Readiness(entry.mask) != 0 {
|
||||
e.waitingList.Remove(entry)
|
||||
e.readyList.PushBack(entry)
|
||||
entry.curList = &e.readyList
|
||||
e.Notify(waiter.EventIn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,10 +115,12 @@ func (f *Fragmentation) Process(id uint32, first, last uint16, more bool, vv buf
|
||||
// Evict reassemblers if we are consuming more memory than highLimit until
|
||||
// we reach lowLimit.
|
||||
if f.size > f.highLimit {
|
||||
tail := f.rList.Back()
|
||||
for f.size > f.lowLimit && tail != nil {
|
||||
for f.size > f.lowLimit {
|
||||
tail := f.rList.Back()
|
||||
if tail == nil {
|
||||
break
|
||||
}
|
||||
f.release(tail)
|
||||
tail = tail.Prev()
|
||||
}
|
||||
}
|
||||
f.mu.Unlock()
|
||||
|
||||
Reference in New Issue
Block a user