From 76cb841cb886eef6b3bee341a2266c76578724ad Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 6 May 2024 03:02:30 +0200 Subject: Adding upstream version 4.19.249. Signed-off-by: Daniel Baumann --- tools/testing/selftests/powerpc/utils.c | 136 ++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 tools/testing/selftests/powerpc/utils.c (limited to 'tools/testing/selftests/powerpc/utils.c') diff --git a/tools/testing/selftests/powerpc/utils.c b/tools/testing/selftests/powerpc/utils.c new file mode 100644 index 000000000..ba0959d45 --- /dev/null +++ b/tools/testing/selftests/powerpc/utils.c @@ -0,0 +1,136 @@ +/* + * Copyright 2013-2015, Michael Ellerman, IBM Corp. + * Licensed under GPLv2. + */ + +#define _GNU_SOURCE /* For CPU_ZERO etc. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" + +static char auxv[4096]; + +int read_auxv(char *buf, ssize_t buf_size) +{ + ssize_t num; + int rc, fd; + + fd = open("/proc/self/auxv", O_RDONLY); + if (fd == -1) { + perror("open"); + return -errno; + } + + num = read(fd, buf, buf_size); + if (num < 0) { + perror("read"); + rc = -EIO; + goto out; + } + + if (num > buf_size) { + printf("overflowed auxv buffer\n"); + rc = -EOVERFLOW; + goto out; + } + + rc = 0; +out: + close(fd); + return rc; +} + +void *find_auxv_entry(int type, char *auxv) +{ + ElfW(auxv_t) *p; + + p = (ElfW(auxv_t) *)auxv; + + while (p->a_type != AT_NULL) { + if (p->a_type == type) + return p; + + p++; + } + + return NULL; +} + +void *get_auxv_entry(int type) +{ + ElfW(auxv_t) *p; + + if (read_auxv(auxv, sizeof(auxv))) + return NULL; + + p = find_auxv_entry(type, auxv); + if (p) + return (void *)p->a_un.a_val; + + return NULL; +} + +int pick_online_cpu(void) +{ + int ncpus, cpu = -1; + cpu_set_t *mask; + size_t size; + + ncpus = get_nprocs_conf(); + size = CPU_ALLOC_SIZE(ncpus); + mask = CPU_ALLOC(ncpus); + if (!mask) { + perror("malloc"); + return -1; + } + + CPU_ZERO_S(size, mask); + + if (sched_getaffinity(0, size, mask)) { + perror("sched_getaffinity"); + goto done; + } + + /* We prefer a primary thread, but skip 0 */ + for (cpu = 8; cpu < ncpus; cpu += 8) + if (CPU_ISSET_S(cpu, size, mask)) + goto done; + + /* Search for anything, but in reverse */ + for (cpu = ncpus - 1; cpu >= 0; cpu--) + if (CPU_ISSET_S(cpu, size, mask)) + goto done; + + printf("No cpus in affinity mask?!\n"); + +done: + CPU_FREE(mask); + return cpu; +} + +bool is_ppc64le(void) +{ + struct utsname uts; + int rc; + + errno = 0; + rc = uname(&uts); + if (rc) { + perror("uname"); + return false; + } + + return strcmp(uts.machine, "ppc64le") == 0; +} -- cgit v1.2.3