github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/inode/cache.go (about) 1 // Copyright (c) 2015-2021, NVIDIA CORPORATION. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package inode 5 6 import ( 7 "fmt" 8 "time" 9 10 "github.com/swiftstack/ProxyFS/conf" 11 "github.com/swiftstack/ProxyFS/logger" 12 "github.com/swiftstack/ProxyFS/platform" 13 ) 14 15 func adoptVolumeGroupReadCacheParameters(confMap conf.ConfMap) (err error) { 16 var ( 17 readCacheLineCount uint64 18 readCacheMemSize uint64 19 readCacheQuotaFraction float64 20 readCacheTotalSize uint64 21 readCacheWeightSum uint64 22 totalMemSize uint64 23 volumeGroup *volumeGroupStruct 24 ) 25 26 readCacheWeightSum = 0 27 28 for _, volumeGroup = range globals.volumeGroupMap { 29 if 0 < volumeGroup.numServed { 30 readCacheWeightSum += volumeGroup.readCacheWeight 31 } 32 } 33 34 readCacheQuotaFraction, err = confMap.FetchOptionValueFloat64("Peer:"+globals.whoAmI, "ReadCacheQuotaFraction") 35 if nil != err { 36 return 37 } 38 if (0 > readCacheQuotaFraction) || (1 < readCacheQuotaFraction) { 39 err = fmt.Errorf("%s.ReadCacheQuotaFraction (%v) must be between 0 and 1", globals.whoAmI, readCacheQuotaFraction) 40 return 41 } 42 43 totalMemSize = platform.MemSize() 44 45 readCacheMemSize = uint64(float64(totalMemSize) * readCacheQuotaFraction / platform.GoHeapAllocationMultiplier) 46 47 logger.Infof("Adopting ReadCache Parameters: ReadCacheQuotaFraction(%v) of memSize(0x%016X) totals 0x%016X", 48 readCacheQuotaFraction, totalMemSize, readCacheMemSize) 49 50 for _, volumeGroup = range globals.volumeGroupMap { 51 if 0 < volumeGroup.numServed { 52 readCacheTotalSize = readCacheMemSize * volumeGroup.readCacheWeight / readCacheWeightSum 53 54 readCacheLineCount = readCacheTotalSize / volumeGroup.readCacheLineSize 55 if 0 == readCacheLineCount { 56 logger.Infof("Computed 0 ReadCacheLines for Volume Group %v; increasing to 1", 57 volumeGroup.name) 58 readCacheLineCount = 1 59 } 60 61 volumeGroup.Lock() 62 volumeGroup.readCacheLineCount = readCacheLineCount 63 volumeGroup.capReadCacheWhileLocked() 64 volumeGroup.Unlock() 65 66 logger.Infof("Volume Group %s: %d cache lines (each of size 0x%08X) totalling 0x%016X", 67 volumeGroup.name, 68 volumeGroup.readCacheLineCount, volumeGroup.readCacheLineSize, 69 volumeGroup.readCacheLineCount*volumeGroup.readCacheLineSize) 70 } 71 } 72 73 err = nil 74 return 75 } 76 77 func startInodeCacheDiscard(confMap conf.ConfMap, volume *volumeStruct, volumeSectionName string) (err error) { 78 var ( 79 LRUCacheMaxBytes uint64 80 LRUDiscardTimeInterval time.Duration 81 ) 82 83 LRUCacheMaxBytes, err = confMap.FetchOptionValueUint64(volumeSectionName, "MaxBytesInodeCache") 84 if nil != err { 85 LRUCacheMaxBytes = 10485760 // TODO - Remove setting a default value 86 err = nil 87 } 88 volume.inodeCacheLRUMaxBytes = LRUCacheMaxBytes 89 90 LRUDiscardTimeInterval, err = confMap.FetchOptionValueDuration(volumeSectionName, "InodeCacheEvictInterval") 91 if nil != err { 92 LRUDiscardTimeInterval = 1 * time.Second // TODO - Remove setting a default value 93 err = nil 94 } 95 96 if LRUDiscardTimeInterval != 0 { 97 volume.inodeCacheLRUTickerInterval = LRUDiscardTimeInterval 98 volume.inodeCacheLRUTicker = time.NewTicker(volume.inodeCacheLRUTickerInterval) 99 100 logger.Infof("Inode cache discard ticker for 'volume: %v' is: %v MaxBytesInodeCache: %v", 101 volume.volumeName, volume.inodeCacheLRUTickerInterval, volume.inodeCacheLRUMaxBytes) 102 103 // Start ticker for inode cache discard thread 104 volume.inodeCacheWG.Add(1) 105 go func() { 106 for { 107 select { 108 case _ = <-volume.inodeCacheLRUTicker.C: 109 _, _, _, _ = volume.inodeCacheDiscard() 110 case _, _ = <-volume.inodeCacheStopChan: 111 volume.inodeCacheWG.Done() 112 return 113 } 114 } 115 }() 116 } else { 117 logger.Infof("Inode cache discard ticker for 'volume: %v' is disabled.", 118 volume.volumeName) 119 return 120 } 121 122 return 123 } 124 125 func stopInodeCacheDiscard(volume *volumeStruct) { 126 if volume.inodeCacheLRUTicker != nil { 127 volume.inodeCacheLRUTicker.Stop() 128 close(volume.inodeCacheStopChan) 129 volume.inodeCacheWG.Wait() 130 logger.Infof("Inode cache discard ticker for 'volume: %v' stopped.", 131 volume.volumeName) 132 } 133 }