From 16e310076564ef55e15452ebcc6832b261b247d5 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Tue, 2 Jan 2024 18:08:13 +0530 Subject: [PATCH 1/5] Capture transparent hugepages config in health report Add a new node `thp-config` under `sys -> config` and inside it add values from following config files: /sys/kernel/mm/transparent_hugepage/enabled /sys/kernel/mm/transparent_hugepage/defrag /sys/kernel/mm/transparent_hugepage/khugepaged/max_ptes_none ref: https://tip.golang.org/doc/gc-guide#Linux_transparent_huge_pages --- health.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/health.go b/health.go index 7ceba7a..e6abc2e 100644 --- a/health.go +++ b/health.go @@ -396,6 +396,17 @@ type XFSErrorConfig struct { MaxRetries int `json:"max_retries"` } +// THPConfigs - stores transparent huge pages (THP) related configs +type THPConfigs struct { + // /sys/kernel/mm/transparent_hugepage/enabled + Enabled string `json:"enabled"` + // /sys/kernel/mm/transparent_hugepage/defrag + Defrag string `json:"defrag"` + // /sys/kernel/mm/transparent_hugepage/khugepaged/max_ptes_none + MaxPtesNone int `json:"max_ptes_none"` + Error string `json:"error,omitempty"` +} + // GetOSInfo returns linux only operating system's information. func GetOSInfo(ctx context.Context, addr string) OSInfo { if runtime.GOOS != "linux" { @@ -467,6 +478,8 @@ func GetSysConfig(_ context.Context, addr string) SysConfig { sc.Config["xfs-error-config"] = xfsErrorConfigs } + sc.Config["thp-config"] = getTHPConfigs() + return sc } @@ -487,6 +500,31 @@ func readIntFromFile(filePath string) (num int, err error) { return strconv.Atoi(strings.TrimSpace(string(data))) } +func getTHPConfigs() THPConfigs { + data, err := os.ReadFile("/sys/kernel/mm/transparent_hugepage/enabled") + if err != nil { + return THPConfigs{Error: err.Error()} + } + configs := THPConfigs{Enabled: strings.TrimSpace(string(data))} + + data, err = os.ReadFile("/sys/kernel/mm/transparent_hugepage/defrag") + if err != nil { + return THPConfigs{Error: err.Error()} + } + configs.Defrag = strings.TrimSpace(string(data)) + + data, err = os.ReadFile("/sys/kernel/mm/transparent_hugepage/khugepaged/max_ptes_none") + if err != nil { + return THPConfigs{Error: err.Error()} + } + + configs.MaxPtesNone, err = strconv.Atoi(strings.TrimSpace(string(data))) + if err != nil { + return THPConfigs{Error: err.Error()} + } + return configs +} + func getXFSErrorMaxRetries() XFSErrorConfigs { xfsErrCfgPattern := "/sys/fs/xfs/*/error/metadata/*/max_retries" configFiles, err := filepath.Glob(xfsErrCfgPattern) From d0e70c748f517e9cf8ffcb1dbde4c4e7c4552b62 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Wed, 3 Jan 2024 17:42:10 +0530 Subject: [PATCH 2/5] Use generic data structure (map) for THP configs --- health.go | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/health.go b/health.go index e6abc2e..4fed6e4 100644 --- a/health.go +++ b/health.go @@ -396,17 +396,6 @@ type XFSErrorConfig struct { MaxRetries int `json:"max_retries"` } -// THPConfigs - stores transparent huge pages (THP) related configs -type THPConfigs struct { - // /sys/kernel/mm/transparent_hugepage/enabled - Enabled string `json:"enabled"` - // /sys/kernel/mm/transparent_hugepage/defrag - Defrag string `json:"defrag"` - // /sys/kernel/mm/transparent_hugepage/khugepaged/max_ptes_none - MaxPtesNone int `json:"max_ptes_none"` - Error string `json:"error,omitempty"` -} - // GetOSInfo returns linux only operating system's information. func GetOSInfo(ctx context.Context, addr string) OSInfo { if runtime.GOOS != "linux" { @@ -500,28 +489,30 @@ func readIntFromFile(filePath string) (num int, err error) { return strconv.Atoi(strings.TrimSpace(string(data))) } -func getTHPConfigs() THPConfigs { +func getTHPConfigs() map[string]interface{} { + configs := map[string]interface{}{} data, err := os.ReadFile("/sys/kernel/mm/transparent_hugepage/enabled") if err != nil { - return THPConfigs{Error: err.Error()} + return map[string]interface{}{"error": err.Error()} } - configs := THPConfigs{Enabled: strings.TrimSpace(string(data))} + configs["enabled"] = strings.TrimSpace(string(data)) data, err = os.ReadFile("/sys/kernel/mm/transparent_hugepage/defrag") if err != nil { - return THPConfigs{Error: err.Error()} + return map[string]interface{}{"error": err.Error()} } - configs.Defrag = strings.TrimSpace(string(data)) + configs["defrag"] = strings.TrimSpace(string(data)) data, err = os.ReadFile("/sys/kernel/mm/transparent_hugepage/khugepaged/max_ptes_none") if err != nil { - return THPConfigs{Error: err.Error()} + return map[string]interface{}{"error": err.Error()} } - configs.MaxPtesNone, err = strconv.Atoi(strings.TrimSpace(string(data))) + configs["max_ptes_none"], err = strconv.Atoi(strings.TrimSpace(string(data))) if err != nil { - return THPConfigs{Error: err.Error()} + return map[string]interface{}{"error": err.Error()} } + return configs } From fc2cf40cd46cd48943291007a24985dcc3237a5e Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Fri, 5 Jan 2024 16:29:52 +0530 Subject: [PATCH 3/5] Do not fail on error in capturing one config --- health.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/health.go b/health.go index 4fed6e4..0ed9ff8 100644 --- a/health.go +++ b/health.go @@ -493,24 +493,26 @@ func getTHPConfigs() map[string]interface{} { configs := map[string]interface{}{} data, err := os.ReadFile("/sys/kernel/mm/transparent_hugepage/enabled") if err != nil { - return map[string]interface{}{"error": err.Error()} + configs["enabled_error"] = err.Error() + } else { + configs["enabled"] = strings.TrimSpace(string(data)) } - configs["enabled"] = strings.TrimSpace(string(data)) data, err = os.ReadFile("/sys/kernel/mm/transparent_hugepage/defrag") if err != nil { - return map[string]interface{}{"error": err.Error()} + configs["defrag_error"] = err.Error() + } else { + configs["defrag"] = strings.TrimSpace(string(data)) } - configs["defrag"] = strings.TrimSpace(string(data)) data, err = os.ReadFile("/sys/kernel/mm/transparent_hugepage/khugepaged/max_ptes_none") if err != nil { - return map[string]interface{}{"error": err.Error()} - } - - configs["max_ptes_none"], err = strconv.Atoi(strings.TrimSpace(string(data))) - if err != nil { - return map[string]interface{}{"error": err.Error()} + configs["max_ptes_none_error"] = err.Error() + } else { + configs["max_ptes_none"], err = strconv.Atoi(strings.TrimSpace(string(data))) + if err != nil { + configs["max_ptes_none_error"] = err.Error() + } } return configs From 981537049cc8347bc2f8df736bc60309926812da Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Fri, 19 Jan 2024 10:14:46 +0530 Subject: [PATCH 4/5] Use map[string]string for THP config --- health.go | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/health.go b/health.go index 0ed9ff8..5a7d725 100644 --- a/health.go +++ b/health.go @@ -489,33 +489,22 @@ func readIntFromFile(filePath string) (num int, err error) { return strconv.Atoi(strings.TrimSpace(string(data))) } -func getTHPConfigs() map[string]interface{} { - configs := map[string]interface{}{} - data, err := os.ReadFile("/sys/kernel/mm/transparent_hugepage/enabled") - if err != nil { - configs["enabled_error"] = err.Error() - } else { - configs["enabled"] = strings.TrimSpace(string(data)) - } - - data, err = os.ReadFile("/sys/kernel/mm/transparent_hugepage/defrag") - if err != nil { - configs["defrag_error"] = err.Error() - } else { - configs["defrag"] = strings.TrimSpace(string(data)) - } +func getTHPConfigs() map[string]string { + configs := map[string]string{} + captureTHPConfig(configs, "/sys/kernel/mm/transparent_hugepage/enabled", "enabled") + captureTHPConfig(configs, "/sys/kernel/mm/transparent_hugepage/defrag", "defrag") + captureTHPConfig(configs, "/sys/kernel/mm/transparent_hugepage/khugepaged/max_ptes_none", "max_ptes_none") + return configs +} - data, err = os.ReadFile("/sys/kernel/mm/transparent_hugepage/khugepaged/max_ptes_none") +func captureTHPConfig(configs map[string]string, filePath string, cfgName string) { + errFieldName := "cfgName" + "_error" + data, err := os.ReadFile(filePath) if err != nil { - configs["max_ptes_none_error"] = err.Error() - } else { - configs["max_ptes_none"], err = strconv.Atoi(strings.TrimSpace(string(data))) - if err != nil { - configs["max_ptes_none_error"] = err.Error() - } + configs[errFieldName] = err.Error() + return } - - return configs + configs[cfgName] = strings.TrimSpace(string(data)) } func getXFSErrorMaxRetries() XFSErrorConfigs { From aad3edda55abe45d1a3a6743f05465fb250e74b8 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 18 Jan 2024 21:34:42 -0800 Subject: [PATCH 5/5] Update health.go Co-authored-by: Shubhendu --- health.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health.go b/health.go index 5a7d725..910f314 100644 --- a/health.go +++ b/health.go @@ -498,7 +498,7 @@ func getTHPConfigs() map[string]string { } func captureTHPConfig(configs map[string]string, filePath string, cfgName string) { - errFieldName := "cfgName" + "_error" + errFieldName := cfgName + "_error" data, err := os.ReadFile(filePath) if err != nil { configs[errFieldName] = err.Error()