Skip to content

Commit

Permalink
Fixed global perf counters in presence of offline CPUs
Browse files Browse the repository at this point in the history
  • Loading branch information
apangin committed Nov 27, 2022
1 parent c956664 commit b64852e
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 35 deletions.
34 changes: 18 additions & 16 deletions src/one/nio/os/Cpus.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,43 @@

package one.nio.os;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import one.nio.util.Utf8;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import one.nio.util.Utf8;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.BitSet;

public class Cpus {
private static final Log log = LogFactory.getLog(Cpus.class);

public static final int ONLINE = cpus("/sys/devices/system/cpu/online");
public static final int POSSIBLE = cpus("/sys/devices/system/cpu/possible");
public static final int PRESENT = cpus("/sys/devices/system/cpu/present");

private static int cpus(String rangeFile) {
public static final BitSet ONLINE = cpus("/sys/devices/system/cpu/online");
public static final BitSet PRESENT = cpus("/sys/devices/system/cpu/present");
public static final BitSet POSSIBLE = cpus("/sys/devices/system/cpu/possible");
public static final int COUNT = POSSIBLE.cardinality();

private static BitSet cpus(String rangeFile) {
try {
byte[] bytes = Files.readAllBytes(Paths.get(rangeFile));
String rangeStr = Utf8.read(bytes, 0, bytes.length).trim();
int cpus = 0;
BitSet cpus = new BitSet();
for (String range : rangeStr.split(",")) {
String[] s = range.split("-");
if (s.length == 1) {
cpus++;
} else {
cpus += 1 + Integer.parseInt(s[1]) - Integer.parseInt(s[0]);
}
int from = Integer.parseInt(s[0]);
int to = s.length == 1 ? from : Integer.parseInt(s[1]);
cpus.set(from, to);
}
return cpus;
} catch (IOException e) {
if (log.isDebugEnabled()) {
log.debug("Failed to read " + rangeFile, e);
}
return Runtime.getRuntime().availableProcessors();
BitSet cpus = new BitSet();
cpus.set(0, Runtime.getRuntime().availableProcessors());
return cpus;
}
}
}
2 changes: 1 addition & 1 deletion src/one/nio/os/bpf/BpfMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import java.util.NoSuchElementException;

public class BpfMap extends BpfObj implements Closeable {
public static final int CPUS = Cpus.POSSIBLE;
public static final int CPUS = Cpus.COUNT;
public static final int ARRAY_KEY_SIZE = 4;

public final MapType type;
Expand Down
8 changes: 3 additions & 5 deletions src/one/nio/os/native/perf.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,6 @@ Java_one_nio_os_perf_Perf_openEvent(JNIEnv* env, jclass cls, jint pid, jint cpu,
attr.config = config;
}

if (type == PERF_TYPE_SOFTWARE) {
attr.precise_ip = 2;
}

unsigned long flags = parse_perf_options(env, options, &attr);

int fd = syscall(__NR_perf_event_open, &attr, pid, cpu, group, flags);
Expand Down Expand Up @@ -180,5 +176,7 @@ Java_one_nio_os_perf_Perf_getValue(JNIEnv* env, jclass cls, jint fd, jlongArray

JNIEXPORT void JNICALL
Java_one_nio_os_perf_Perf_ioctl(JNIEnv* env, jclass cls, jint fd, jint cmd, jint arg) {
ioctl(fd, ioctl_cmd[cmd], arg);
if (ioctl(fd, ioctl_cmd[cmd], arg) < 0) {
throw_io_exception(env);
}
}
2 changes: 2 additions & 0 deletions src/one/nio/os/perf/LocalValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package one.nio.os.perf;

public class LocalValue implements CounterValue {
public static final LocalValue ZERO = new LocalValue(0, 0, 0);

public final long value;
public final long running;
public final long enabled;
Expand Down
8 changes: 5 additions & 3 deletions src/one/nio/os/perf/Perf.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,15 @@ public static PerfCounter open(PerfEvent event, String cgroup, int cpu, PerfOpti

public static PerfCounterGlobal openGlobal(PerfEvent event, int pid, PerfOption... options) throws IOException {
String optionString = optionString(options);
int[] fds = new int[Cpus.PRESENT];
int[] fds = new int[Cpus.COUNT];

PerfOptionGlobalGroup group = (PerfOptionGlobalGroup) option(options, PerfOption.GROUP_GLOBAL);
try {
for (int cpu = 0; cpu < fds.length; cpu++) {
int groupFd = group == null ? -1 : group.fds[cpu];
fds[cpu] = openEvent(pid, cpu, event.type, event.config, event.breakpoint, groupFd, optionString);
if (Cpus.ONLINE.get(cpu)) {
int groupFd = group == null ? -1 : group.fds[cpu];
fds[cpu] = openEvent(pid, cpu, event.type, event.config, event.breakpoint, groupFd, optionString);
}
}
} catch (Throwable e) {
for (int fd : fds) {
Expand Down
38 changes: 28 additions & 10 deletions src/one/nio/os/perf/PerfCounterGlobal.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ public void close() {
for (int i = 0; i < fds.length; i++) {
int fd = fds[i];
fds[i] = -1;
Perf.close(fd);
if (fd > 0) {
Perf.close(fd);
}
}
}
}
Expand All @@ -44,7 +46,9 @@ public void close() {
public long get() throws IOException {
long sum = 0;
for (int fd : fds) {
sum += Perf.get(fd);
if (fd > 0) {
sum += Perf.get(fd);
}
}
return sum;
}
Expand All @@ -54,18 +58,25 @@ public CounterValue getValue() throws IOException {
int vals = hasReadFormat(ReadFormat.TOTAL_TIME_RUNNING | ReadFormat.TOTAL_TIME_ENABLED) ? 3 : 1;
long[] buf = new long[3 * fds.length];
for (int cpu = 0; cpu < fds.length; cpu++) {
Perf.getValue(fds[cpu], buf, cpu * 3, vals);
int fd = fds[cpu];
if (fd > 0) {
Perf.getValue(fd, buf, cpu * 3, vals);
}
}
return new GlobalValue(buf);
}

public long getForCpu(int cpu) throws IOException {
return Perf.get(fds[cpu]);
int fd = fds[cpu];
return fd > 0 ? Perf.get(fd) : 0;
}

public LocalValue getValueForCpu(int cpu) throws IOException {
int fd = fds[cpu];
if (fd <= 0) return LocalValue.ZERO;

long[] buf = newBuffer();
Perf.getValue(fds[cpu], buf, 0, buf.length);
Perf.getValue(fd, buf, 0, buf.length);
return toValue(buf);
}

Expand All @@ -74,9 +85,11 @@ protected long[] getRawValue() throws IOException {
long[] buf = newBuffer();
long[] total = newBuffer();
for (int fd : fds) {
Perf.getValue(fd, buf, 0, buf.length);
for (int i = 0; i < buf.length; i++) {
total[i] += buf[i];
if (fd > 0) {
Perf.getValue(fd, buf, 0, buf.length);
for (int i = 0; i < buf.length; i++) {
total[i] += buf[i];
}
}
}
return total;
Expand All @@ -85,7 +98,9 @@ protected long[] getRawValue() throws IOException {
@Override
void ioctl(int cmd, int arg) throws IOException {
for (int fd : fds) {
Perf.ioctl(fd, cmd, arg);
if (fd > 0) {
Perf.ioctl(fd, cmd, arg);
}
}
}

Expand All @@ -101,6 +116,9 @@ public void storeTo(BpfMap map, int cpu) throws IOException {
throw new IllegalArgumentException();
}

map.put(BpfMap.bytes(cpu), BpfMap.bytes(fds[cpu]));
int fd = fds[cpu];
if (fd > 0) {
map.put(BpfMap.bytes(cpu), BpfMap.bytes(fd));
}
}
}

0 comments on commit b64852e

Please sign in to comment.