| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | package intelgpu |
| 4 | |
| 5 | import ( |
| 6 | "fmt" |
| 7 | "strings" |
| 8 | |
| 9 | "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi" |
| 10 | ) |
| 11 | |
| 12 | const ( |
| 13 | prioGPUFrequency = collectorapi.Priority + iota |
| 14 | prioGPUPower |
| 15 | prioGPUEngineBusy |
| 16 | ) |
| 17 | |
| 18 | var charts = collectorapi.Charts{ |
| 19 | intelGPUFrequencyChart.Copy(), |
| 20 | intelGPUPowerGPUChart.Copy(), |
| 21 | } |
| 22 | |
| 23 | var intelGPUFrequencyChart = collectorapi.Chart{ |
| 24 | ID: "igpu_frequency", |
| 25 | Title: "Intel GPU frequency", |
| 26 | Units: "MHz", |
| 27 | Fam: "frequency", |
| 28 | Ctx: "intelgpu.frequency", |
| 29 | Type: collectorapi.Line, |
| 30 | Priority: prioGPUFrequency, |
| 31 | Dims: collectorapi.Dims{ |
| 32 | {ID: "frequency_actual", Name: "frequency", Div: precision}, |
| 33 | }, |
| 34 | } |
| 35 | |
| 36 | var intelGPUPowerGPUChart = collectorapi.Chart{ |
| 37 | ID: "igpu_power_gpu", |
| 38 | Title: "Intel GPU power", |
| 39 | Units: "Watts", |
| 40 | Fam: "power", |
| 41 | Ctx: "intelgpu.power", |
| 42 | Type: collectorapi.Line, |
| 43 | Priority: prioGPUPower, |
| 44 | Dims: collectorapi.Dims{ |
| 45 | {ID: "power_gpu", Name: "gpu", Div: precision}, |
| 46 | {ID: "power_package", Name: "package", Div: precision}, |
| 47 | }, |
| 48 | } |
| 49 | |
| 50 | var intelGPUEngineBusyPercChartTmpl = collectorapi.Chart{ |
| 51 | ID: "igpu_engine_%s_busy_percentage", |
| 52 | Title: "Intel GPU engine busy time percentage", |
| 53 | Units: "percentage", |
| 54 | Fam: "engines", |
| 55 | Ctx: "intelgpu.engine_busy_perc", |
| 56 | Type: collectorapi.Line, |
| 57 | Priority: prioGPUEngineBusy, |
| 58 | Dims: collectorapi.Dims{ |
| 59 | {ID: "engine_%s_busy", Name: "busy", Div: precision}, |
| 60 | }, |
| 61 | } |
| 62 | |
| 63 | func (c *Collector) addEngineCharts(engine string) { |
| 64 | chart := intelGPUEngineBusyPercChartTmpl.Copy() |
| 65 | |
| 66 | s := strings.ToLower(engine) |
| 67 | s = strings.ReplaceAll(s, "/", "_") |
| 68 | |
| 69 | chart.ID = fmt.Sprintf(chart.ID, s) |
| 70 | chart.Labels = []collectorapi.Label{ |
| 71 | {Key: "engine_class", Value: engineClassName(engine)}, |
| 72 | {Key: "engine_instance", Value: engine}, |
| 73 | } |
| 74 | for _, dim := range chart.Dims { |
| 75 | dim.ID = fmt.Sprintf(dim.ID, engine) |
| 76 | } |
| 77 | |
| 78 | if err := c.Charts().Add(chart); err != nil { |
| 79 | c.Warning(err) |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | func engineClassName(engine string) string { |
| 84 | // https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/blob/master/tools/intel_gpu_top.c#L431 |
| 85 | engines := []string{"Render/3D", "Blitter", "VideoEnhance", "Video", "Compute"} |
| 86 | for _, name := range engines { |
| 87 | if strings.HasPrefix(engine, name) { |
| 88 | return name |
| 89 | } |
| 90 | } |
| 91 | return "unknown" |
| 92 | } |