Skip to content

Commit 954e981

Browse files
authored
Merge pull request #61 from rojkov/avx512
avx: add enablers for detecting AVX-workloads
2 parents 43782df + d6acef1 commit 954e981

File tree

7 files changed

+622
-1
lines changed

7 files changed

+622
-1
lines changed

Makefile

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@ PROTOC := protoc
1414
PROTOBUFS = $(shell find cmd pkg -name \*.proto)
1515
PROTOCODE := $(patsubst %.proto,%.pb.go,$(PROTOBUFS))
1616

17+
CLANG := clang
18+
KERNEL_VERSION ?= $(shell uname -r)
19+
KERNEL_SRC_DIR ?= /usr/src/kernels/$(KERNEL_VERSION)
20+
1721
# Binaries and directories for installation.
1822
PREFIX ?= /usr
1923
BINDIR ?= $(PREFIX)/bin
2024
UNITDIR ?= $(PREFIX)/lib/systemd/system
2125
SYSCONFDIR ?= /etc
22-
INSTALL := install
26+
INSTALL := install
2327

2428
# Directories (in cmd) with go code we'll want to build and install.
2529
BUILD_DIRS = $(shell find cmd -name \*.go | sed 's:cmd/::g;s:/.*::g' | uniq)
@@ -79,6 +83,11 @@ images: $(foreach dir,$(IMAGE_DIRS),image-$(dir))
7983
# Rules for building and installing binaries, or building docker images, and cleaning up.
8084
#
8185

86+
libexec/%.o: elf/%.c
87+
$(Q)echo "Building $@"
88+
$(Q)mkdir -p libexec
89+
$(CLANG) -I$(KERNEL_SRC_DIR)/arch/x86/include -I$(KERNEL_SRC_DIR)/include -O2 -Wall -target bpf -c $< -o $@
90+
8291
bin/%:
8392
$(Q)bin=$(notdir $@); src=cmd/$$bin; \
8493
eval `$(GIT_ID)`; \

elf/avx512.c

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#include <linux/version.h>
2+
#include <uapi/linux/bpf.h>
3+
4+
#include <asm/page_types.h>
5+
6+
/* asm/fpu/types.h assumes __packed is defined */
7+
#define __packed __attribute__((packed))
8+
#include <asm/fpu/types.h>
9+
10+
#define SEC(NAME) __attribute__((section(NAME), used))
11+
12+
#define BUF_SIZE_MAP_NS 256
13+
14+
typedef struct bpf_map_def {
15+
unsigned int type;
16+
unsigned int key_size;
17+
unsigned int value_size;
18+
unsigned int max_entries;
19+
unsigned int map_flags;
20+
unsigned int pinning;
21+
char namespace[BUF_SIZE_MAP_NS];
22+
} bpf_map_def;
23+
24+
static int (*bpf_probe_read)(void *dst, u64 size, const void *unsafe_ptr) =
25+
(void *)BPF_FUNC_probe_read;
26+
27+
static u64 (*bpf_get_current_cgroup_id)(void) = (void *)
28+
BPF_FUNC_get_current_cgroup_id;
29+
30+
static int (*bpf_map_update_elem)(void *map, void *key, void *value,
31+
u64 flags) = (void *)BPF_FUNC_map_update_elem;
32+
33+
static void *(*bpf_map_lookup_elem)(void *map, void *key) = (void *)
34+
BPF_FUNC_map_lookup_elem;
35+
36+
#define bpf_printk(fmt, ...) \
37+
({ \
38+
char ____fmt[] = fmt; \
39+
bpf_trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__); \
40+
})
41+
static int (*bpf_trace_printk)(const char *fmt, int fmt_size,
42+
...) = (void *)BPF_FUNC_trace_printk;
43+
44+
struct bpf_map_def
45+
SEC("maps/all_context_switch_count") all_context_switch_count_hash = {
46+
.type = BPF_MAP_TYPE_HASH,
47+
.key_size = sizeof(u64),
48+
.value_size = sizeof(u32),
49+
.max_entries = 1024,
50+
};
51+
52+
struct bpf_map_def
53+
SEC("maps/avx_context_switch_count") avx_context_switch_count_hash = {
54+
.type = BPF_MAP_TYPE_HASH,
55+
.key_size = sizeof(u64),
56+
.value_size = sizeof(u32),
57+
.max_entries = 1024,
58+
};
59+
60+
struct bpf_map_def
61+
SEC("maps/avx_timestamp") avx_timestamp_hash = {
62+
.type = BPF_MAP_TYPE_HASH,
63+
.key_size = sizeof(u64),
64+
.value_size = sizeof(u32),
65+
.max_entries = 1024,
66+
};
67+
68+
struct bpf_map_def SEC("maps/cpu") cpu_hash = {
69+
.type = BPF_MAP_TYPE_HASH,
70+
.key_size = sizeof(unsigned int),
71+
.value_size = sizeof(u32),
72+
.max_entries = 128,
73+
};
74+
75+
struct sched_switch_args {
76+
u64 pad;
77+
char prev_comm[16];
78+
int prev_pid;
79+
int prev_prio;
80+
long long prev_state;
81+
char next_comm[16];
82+
int next_pid;
83+
int next_prio;
84+
};
85+
86+
SEC("tracepoint/sched/sched_switch")
87+
int tracepoint__sched_switch(struct sched_switch_args *args)
88+
{
89+
u64 cgroup_id = bpf_get_current_cgroup_id();
90+
u32 *count;
91+
u32 new_count = 1;
92+
93+
count = bpf_map_lookup_elem(&all_context_switch_count_hash, &cgroup_id);
94+
if (count) {
95+
__sync_fetch_and_add(count, 1);
96+
} else {
97+
bpf_map_update_elem(&all_context_switch_count_hash, &cgroup_id,
98+
&new_count, BPF_ANY);
99+
}
100+
return 0;
101+
}
102+
103+
struct x86_fpu_args {
104+
u64 pad;
105+
struct fpu *fpu;
106+
bool load_fpu;
107+
u64 xfeatures;
108+
u64 xcomp_bv;
109+
};
110+
111+
SEC("tracepoint/x86_fpu/x86_fpu_regs_deactivated")
112+
int tracepoint__x86_fpu_regs_deactivated(struct x86_fpu_args *args)
113+
{
114+
u32 *counter;
115+
u32 ts;
116+
bpf_probe_read(&ts, sizeof(u32), (void *)&args->fpu->avx512_timestamp);
117+
118+
if (ts == 0) {
119+
return 0;
120+
}
121+
122+
u64 cgroup_id = bpf_get_current_cgroup_id();
123+
124+
u32 ts_prev;
125+
u32 *tsp;
126+
tsp = bpf_map_lookup_elem(&avx_timestamp_hash, &cgroup_id);
127+
128+
ts_prev = tsp ? *tsp : 0;
129+
130+
if (ts == ts_prev) {
131+
return 0;
132+
}
133+
bpf_map_update_elem(&avx_timestamp_hash, &cgroup_id, &ts, BPF_ANY);
134+
135+
unsigned int last_cpu;
136+
bpf_probe_read(&last_cpu, sizeof(last_cpu),
137+
(void *)&args->fpu->last_cpu);
138+
139+
u32 count = 1;
140+
counter = bpf_map_lookup_elem(&cpu_hash, &last_cpu);
141+
if (counter) {
142+
__sync_fetch_and_add(counter, 1);
143+
} else {
144+
bpf_map_update_elem(&cpu_hash, &last_cpu, &count, BPF_ANY);
145+
}
146+
147+
counter = bpf_map_lookup_elem(&avx_context_switch_count_hash, &cgroup_id);
148+
if (counter) {
149+
__sync_fetch_and_add(counter, 1);
150+
} else {
151+
bpf_map_update_elem(&avx_context_switch_count_hash, &cgroup_id,
152+
&count, BPF_ANY);
153+
}
154+
155+
bpf_printk("AVX512 detected in cgroup %llu\n", cgroup_id);
156+
return 0;
157+
}
158+
159+
char _license[] SEC("license") = "GPL";
160+
161+
unsigned int _version SEC("version") = LINUX_VERSION_CODE;

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@ require (
66
contrib.go.opencensus.io/exporter/jaeger v0.1.0
77
contrib.go.opencensus.io/exporter/prometheus v0.1.0
88
github.com/ghodss/yaml v1.0.0
9+
github.com/gogo/protobuf v1.2.0 // indirect
910
github.com/golang/protobuf v1.3.1
1011
github.com/google/go-cmp v0.3.0
1112
github.com/imdario/mergo v0.3.7 // indirect
13+
github.com/iovisor/gobpf v0.0.0-20191024162143-7c8f8e040b4b
1214
github.com/json-iterator/go v1.1.6 // indirect
15+
github.com/onsi/ginkgo v1.7.0 // indirect
16+
github.com/onsi/gomega v1.4.3 // indirect
1317
github.com/pkg/errors v0.8.0
18+
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829
1419
github.com/stretchr/testify v1.3.0 // indirect
1520
go.opencensus.io v0.22.0
1621
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
165165
github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI=
166166
github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
167167
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
168+
github.com/iovisor/gobpf v0.0.0-20191024162143-7c8f8e040b4b h1:a9WN1ZdBLogkie3+xxnMC6obhlg9/ehMAg+Wyj4Opgw=
169+
github.com/iovisor/gobpf v0.0.0-20191024162143-7c8f8e040b4b/go.mod h1:+5U5qu5UOu8YJ5oHVLvWKH7/Dr5QNHU7mZ2RfPEeXg8=
168170
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
169171
github.com/jonboulle/clockwork v0.0.0-20141017032234-72f9bd7c4e0c/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
170172
github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=

0 commit comments

Comments
 (0)