move blkio stat gathering to loop

Signed-off-by: Piotr Wagner <piotr.wagner@intel.com>
This commit is contained in:
Piotr Wagner
2020-08-24 21:04:40 +02:00
committed by Kir Kolyshkin
parent 990a6c57f1
commit 31b0151fc9
2 changed files with 173 additions and 148 deletions
+117 -148
View File
@@ -157,165 +157,134 @@ func getBlkioStat(dir, file string) ([]cgroups.BlkioStatEntry, error) {
}
func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error {
// Try to read BFQ stats with debug files enabled first
if moveToNextMethod, err := getBFQDebugStats(path, stats); !moveToNextMethod {
return err
type blkioStatInfo struct {
filename string
blkioStatEntriesPtr *[]cgroups.BlkioStatEntry
}
// Try to read BFQ stats with debug files disabled
if moveToNextMethod, err := getBFQStats(path, stats); !moveToNextMethod {
return err
var bfqDebugStats = []blkioStatInfo{
{
filename: "blkio.bfq.sectors_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.SectorsRecursive,
},
{
filename: "blkio.bfq.io_service_time_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoServiceTimeRecursive,
},
{
filename: "blkio.bfq.io_wait_time_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoWaitTimeRecursive,
},
{
filename: "blkio.bfq.io_merged_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoMergedRecursive,
},
{
filename: "blkio.bfq.io_queued_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoQueuedRecursive,
},
{
filename: "blkio.bfq.time_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoTimeRecursive,
},
{
filename: "blkio.bfq.io_serviced_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive,
},
{
filename: "blkio.bfq.io_service_bytes_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive,
},
}
// Try to read CFQ stats available on all CFQ enabled kernels
if moveToNextMethod, err := getCFQStats(path, stats); !moveToNextMethod {
return err
var bfqStats = []blkioStatInfo{
{
filename: "blkio.bfq.io_serviced_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive,
},
{
filename: "blkio.bfq.io_service_bytes_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive,
},
}
// Try to read recursive version of generic stats
if moveToNextMethod, err := getRecursiveThrottleStats(path, stats); !moveToNextMethod {
return err
var cfqStats = []blkioStatInfo{
{
filename: "blkio.sectors_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.SectorsRecursive,
},
{
filename: "blkio.io_service_time_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoServiceTimeRecursive,
},
{
filename: "blkio.io_wait_time_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoWaitTimeRecursive,
},
{
filename: "blkio.io_merged_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoMergedRecursive,
},
{
filename: "blkio.io_queued_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoQueuedRecursive,
},
{
filename: "blkio.time_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoTimeRecursive,
},
{
filename: "blkio.io_serviced_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive,
},
{
filename: "blkio.io_service_bytes_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive,
},
}
return getBaseStats(path, stats) // Use generic stats as fallback
}
func getBFQStats(path string, stats *cgroups.Stats) (bool, error) {
var blkioStats []cgroups.BlkioStatEntry
var err error
var moveToNextMethod = false
if blkioStats, err = getBlkioStat(path, "blkio.bfq.io_serviced_recursive"); err != nil || blkioStats == nil {
moveToNextMethod = true
return moveToNextMethod, err
var throttleRecursiveStats = []blkioStatInfo{
{
filename: "blkio.throttle.io_serviced_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive,
},
{
filename: "blkio.throttle.io_service_bytes_recursive",
blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive,
},
}
stats.BlkioStats.IoServicedRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.bfq.io_service_bytes_recursive"); err != nil {
return moveToNextMethod, err
var baseStats = []blkioStatInfo{
{
filename: "blkio.throttle.io_serviced",
blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive,
},
{
filename: "blkio.throttle.io_service_bytes",
blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive,
},
}
stats.BlkioStats.IoServiceBytesRecursive = blkioStats
return moveToNextMethod, nil
}
func getBFQDebugStats(path string, stats *cgroups.Stats) (bool, error) {
var blkioStats []cgroups.BlkioStatEntry
var err error
var moveToNextMethod = false
if blkioStats, err = getBlkioStat(path, "blkio.bfq.sectors_recursive"); err != nil || blkioStats == nil {
moveToNextMethod = true
return moveToNextMethod, err
var orderedStats = [][]blkioStatInfo{
bfqDebugStats,
bfqStats,
cfqStats,
throttleRecursiveStats,
baseStats,
}
stats.BlkioStats.SectorsRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.bfq.io_service_time_recursive"); err != nil {
return moveToNextMethod, err
}
stats.BlkioStats.IoServiceTimeRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.bfq.io_wait_time_recursive"); err != nil {
return moveToNextMethod, err
}
stats.BlkioStats.IoWaitTimeRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.bfq.io_merged_recursive"); err != nil {
return moveToNextMethod, err
}
stats.BlkioStats.IoMergedRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.bfq.io_queued_recursive"); err != nil {
return moveToNextMethod, err
}
stats.BlkioStats.IoQueuedRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.bfq.time_recursive"); err != nil {
return moveToNextMethod, err
}
stats.BlkioStats.IoTimeRecursive = blkioStats
_, err = getBFQStats(path, stats)
return moveToNextMethod, err
}
func getCFQStats(path string, stats *cgroups.Stats) (bool, error) {
var blkioStats []cgroups.BlkioStatEntry
var err error
var moveToNextMethod = false
if blkioStats, err = getBlkioStat(path, "blkio.sectors_recursive"); err != nil || blkioStats == nil {
moveToNextMethod = true
return moveToNextMethod, err
}
stats.BlkioStats.SectorsRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.io_service_bytes_recursive"); err != nil {
return moveToNextMethod, err
}
stats.BlkioStats.IoServiceBytesRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.io_serviced_recursive"); err != nil {
return moveToNextMethod, err
}
stats.BlkioStats.IoServicedRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.io_queued_recursive"); err != nil {
return moveToNextMethod, err
}
stats.BlkioStats.IoQueuedRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.io_service_time_recursive"); err != nil {
return moveToNextMethod, err
}
stats.BlkioStats.IoServiceTimeRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.io_wait_time_recursive"); err != nil {
return moveToNextMethod, err
}
stats.BlkioStats.IoWaitTimeRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.io_merged_recursive"); err != nil {
return moveToNextMethod, err
}
stats.BlkioStats.IoMergedRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.time_recursive"); err != nil {
return moveToNextMethod, err
}
stats.BlkioStats.IoTimeRecursive = blkioStats
return moveToNextMethod, nil
}
func getRecursiveThrottleStats(path string, stats *cgroups.Stats) (bool, error) {
var blkioStats []cgroups.BlkioStatEntry
var err error
var moveToNextMethod = false
if blkioStats, err = getBlkioStat(path, "blkio.throttle.io_service_bytes_recursive"); err != nil || blkioStats == nil {
moveToNextMethod = true
return moveToNextMethod, err
}
stats.BlkioStats.IoServiceBytesRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.throttle.io_serviced_recursive"); err != nil {
return moveToNextMethod, err
}
stats.BlkioStats.IoServicedRecursive = blkioStats
return moveToNextMethod, nil
}
func getBaseStats(path string, stats *cgroups.Stats) error {
var blkioStats []cgroups.BlkioStatEntry
var err error
if blkioStats, err = getBlkioStat(path, "blkio.throttle.io_service_bytes"); err != nil {
return err
for _, statGroup := range orderedStats {
for i, statInfo := range statGroup {
if blkioStats, err = getBlkioStat(path, statInfo.filename); err != nil || blkioStats == nil {
// if error occurs on first file, move to next group
if i == 0 {
break
}
return err
}
*statInfo.blkioStatEntriesPtr = blkioStats
//finish if all stats are gathered
if i == len(statGroup)-1 {
return nil
}
}
}
stats.BlkioStats.IoServiceBytesRecursive = blkioStats
if blkioStats, err = getBlkioStat(path, "blkio.throttle.io_serviced"); err != nil {
return err
}
stats.BlkioStats.IoServicedRecursive = blkioStats
return nil
}
+56
View File
@@ -322,6 +322,62 @@ func TestBlkioBFQDebugStats(t *testing.T) {
expectBlkioStatsEquals(t, expectedStats, actualStats.BlkioStats)
}
func TestBlkioMultipleStatsFiles(t *testing.T) {
helper := NewCgroupTestUtil("blkio", t)
defer helper.cleanup()
helper.writeFileContents(blkioBFQDebugStatsTestFiles)
helper.writeFileContents(blkioCFQStatsTestFiles)
blkio := &BlkioGroup{}
actualStats := *cgroups.NewStats()
err := blkio.GetStats(helper.CgroupPath, &actualStats)
if err != nil {
t.Fatal(err)
}
expectedStats := cgroups.BlkioStats{}
appendBlkioStatEntry(&expectedStats.SectorsRecursive, 8, 0, 2048, "")
appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1100, "Read")
appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1200, "Write")
appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1300, "Sync")
appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1500, "Async")
appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1500, "Total")
appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 11, "Read")
appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 41, "Write")
appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 21, "Sync")
appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 31, "Async")
appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 51, "Total")
appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 2, "Read")
appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 3, "Write")
appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 4, "Sync")
appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 5, "Async")
appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 6, "Total")
appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 173959, "Read")
appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 0, "Write")
appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 0, "Sync")
appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 173, "Async")
appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 174, "Total")
appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 1557, "Read")
appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 0, "Write")
appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 0, "Sync")
appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 1557, "Async")
appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 1557, "Total")
appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 51, "Read")
appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 101, "Write")
appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 0, "Sync")
appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 0, "Async")
appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 151, "Total")
appendBlkioStatEntry(&expectedStats.IoTimeRecursive, 8, 0, 16, "")
expectBlkioStatsEquals(t, expectedStats, actualStats.BlkioStats)
}
func TestBlkioBFQStats(t *testing.T) {
helper := NewCgroupTestUtil("blkio", t)
defer helper.cleanup()