Revision 230f0b9b7cb4885864d457c82e312489c0a0d3d7 authored by Paul Chaignon on 21 May 2021, 21:10:24 UTC, committed by Nathan Sweet on 04 June 2021, 16:46:12 UTC
[ upstream commit 802d25447fa1d325d3713220f8ad08e7938f6dd4 ]

Commit 50df544 added a new job in the end-to-end workflows to checkout
the tested code and run paths-filter on it. That first job fails when
the workflows are scheduled (vs. triggered by PR comment) because we try
to grab the pull request URL, which doesn't exist:

    curl ${{ github.event.issue.pull_request.url }} > pr.json

results in error:

    Run curl  > pr.json
    curl: try 'curl --help' or 'curl --manual' for more information

We can avoid this by skipping steps in the first job when triggered by
schedule. We can't skip the entire first job because the second job has
a dependency on the first and would fail if we skipped the first.

Fixes: 50df544 (".github: Skip unnecessary ci-xxx tests")
Signed-off-by: Paul Chaignon <paul@cilium.io>
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
1 parent e942366
Raw File
cilium-probe-kernel-hz.c
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2020 Authors of Cilium */

#define _GNU_SOURCE

#include <stdio.h>
#include <unistd.h>
#include <sched.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>

#include <sys/resource.h>

#define __non_bpf_context	1
#include "bpf/compiler.h"

struct cpu_jiffies {
	uint64_t *jiffies;
	uint32_t cpus;
};

static const uint64_t kernel_hz[] = { 100, 250, 300, 1000 };

#define abs(x)	({ x < 0 ? -x : x; })

static int pin_to_cpu(int cpu)
{
	cpu_set_t set;

	CPU_ZERO(&set);
	CPU_SET(cpu, &set);

	return sched_setaffinity(0, sizeof(set), &set);
}

static int fix_priority(void)
{
	struct sched_param sp = {
		.sched_priority = sched_get_priority_max(SCHED_FIFO),
	};

	return sched_setscheduler(0, SCHED_FIFO, &sp);
}

static FILE *timer_list_open(void)
{
	return fopen("/proc/timer_list", "r");
}

static void timer_list_close(FILE *fp)
{
	fclose(fp);
}

static int prep_kern_jiffies(struct cpu_jiffies *before,
			     struct cpu_jiffies *after)
{
	uint64_t jiffies = 0;
	char buff[512];
	int cpus = 0;
	FILE *fp;

	fp = timer_list_open();
	while (fp && fgets(buff, sizeof(buff), fp)) {
		if (sscanf(buff, "jiffies: %lu\n", &jiffies) == 1)
			cpus++;
	}
	timer_list_close(fp);

	if (!cpus) {
		fprintf(stderr, "No procfs support?\n");
		return -EIO;
	}

	before->cpus = after->cpus = cpus;
	before->jiffies = calloc(cpus, sizeof(*before->jiffies));
	after->jiffies  = calloc(cpus, sizeof(*before->jiffies));

	if (!before->jiffies || !after->jiffies) {
		free(before->jiffies);
		free(after->jiffies);
		fprintf(stderr, "Error allocating per CPU jiffies: %s\n",
			strerror(errno));
		return -EIO;
	}

	return 0;
}

static int fetch_kern_jiffies(const struct cpu_jiffies *curr)
{
	char buff[512];
	int cpus = 0;
	FILE *fp;

	fp = timer_list_open();
	while (fp && fgets(buff, sizeof(buff), fp) && cpus < curr->cpus) {
		if (sscanf(buff, "jiffies: %lu\n", &curr->jiffies[cpus]) == 1)
			cpus++;
	}
	timer_list_close(fp);

	if (cpus != curr->cpus) {
		fprintf(stderr, "CPU mismatch when fetching jiffies\n");
		return -EIO;
	}

	return 0;
}

static int dump_kern_jiffies(const struct cpu_jiffies *fixed,
			     const struct cpu_jiffies *result,
			     bool macro)
{
	uint64_t delta, warp = 0;
	int i, j, ret = -1;
	int64_t x;

	for (i = 0; i < result->cpus; i++) {
		result->jiffies[i] -= fixed->jiffies[i];
		for (j = 0, delta = ~0; j < ARRAY_SIZE(kernel_hz); j++) {
			x = abs((int64_t)(kernel_hz[j] - result->jiffies[i]));
			if (x < delta) {
				delta = x;
				fixed->jiffies[i] = kernel_hz[j];
			}
		}
		if (delta > warp)
			warp = delta;
		if (fixed->jiffies[i] != fixed->jiffies[0]) {
			fprintf(stderr, "Probed jiffies mismatch: %lu vs %lu HZ\n",
				fixed->jiffies[i], fixed->jiffies[0]);
			goto out;
		}
	}

	if (macro)
		printf("#define KERNEL_HZ %lu\t/* warp: %lu jiffies */\n", fixed->jiffies[0], warp);
	else
		printf("%lu, %lu\n", fixed->jiffies[0], warp);
	ret = 0;
out:
	free(fixed->jiffies);
	free(result->jiffies);
	return ret;
}

int main(int argc, char **argv)
{
	struct cpu_jiffies before, after;
	struct timespec tv = {
		.tv_sec  = 1,
		.tv_nsec = 0,
	};
	int opt, sig, ret, tries = 4;
	bool macro = false;

	while ((opt = getopt(argc, argv, "m")) != -1) {
		switch (opt) {
		case 'm':
			macro = true;
			break;
		default:
			return -1;
		}
	}

	if (pin_to_cpu(0)) {
		fprintf(stderr, "Cannot pin to CPU 0: %s\n", strerror(errno));
		return -1;
	}
	if (fix_priority()) {
		fprintf(stderr, "Cannot set priority: %s\n", strerror(errno));
		return -1;
	}
	if (prep_kern_jiffies(&before, &after)) {
		fprintf(stderr, "Cannot prep jiffies: %s\n", strerror(errno));
		return -1;
	}

	do {
		ret  = fetch_kern_jiffies(&before);
		sig  = nanosleep(&tv, NULL);
		ret += fetch_kern_jiffies(&after);
	} while (!ret && sig && errno == EINTR && --tries >= 0);

	if (!ret && !sig)
		ret = dump_kern_jiffies(&before, &after, macro);
	return ret;
}
back to top