Skip to content

Commit

Permalink
cache: avoid concurrent maps write on prune
Browse files Browse the repository at this point in the history
remove() needs to be called while holding the manager lock

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
  • Loading branch information
tonistiigi committed Jun 15, 2021
1 parent 6a4a14b commit 5429fe1
Showing 1 changed file with 17 additions and 9 deletions.
26 changes: 17 additions & 9 deletions cache/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,22 @@ func (cm *cacheManager) prune(ctx context.Context, ch chan client.UsageInfo, opt
return nil
}

// calculate sizes here so that lock does not need to be held for slow process
for _, cr := range toDelete {
size := getSize(cr.md)

if size == sizeUnknown && cr.equalImmutable != nil {
size = getSize(cr.equalImmutable.md) // benefit from DiskUsage calc
}
if size == sizeUnknown {
// calling size will warm cache for next call
if _, err := cr.Size(ctx); err != nil {
return err
}
}
}

cm.mu.Lock()
var err error
for _, cr := range toDelete {
cr.mu.Lock()
Expand All @@ -794,15 +810,6 @@ func (cm *cacheManager) prune(ctx context.Context, ch chan client.UsageInfo, opt
if c.Size == sizeUnknown && cr.equalImmutable != nil {
c.Size = getSize(cr.equalImmutable.md) // benefit from DiskUsage calc
}
if c.Size == sizeUnknown {
cr.mu.Unlock() // all the non-prune modifications already protected by cr.dead
s, err := cr.Size(ctx)
if err != nil {
return err
}
c.Size = s
cr.mu.Lock()
}

opt.totalSize -= c.Size

Expand All @@ -820,6 +827,7 @@ func (cm *cacheManager) prune(ctx context.Context, ch chan client.UsageInfo, opt
}
cr.mu.Unlock()
}
cm.mu.Unlock()
if err != nil {
return err
}
Expand Down

0 comments on commit 5429fe1

Please sign in to comment.