brintos

brintos / linux-shallow public Read only

0
0
Text · 5.2 KiB · 82c1214 Raw
155 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2023 Ventana Micro Systems Inc.4 *5 * Test the RISCV_HWPROBE_WHICH_CPUS flag of hwprobe. Also provides a command6 * line interface to get the cpu list for arbitrary hwprobe pairs.7 */8#define _GNU_SOURCE9#include <stdio.h>10#include <stdlib.h>11#include <string.h>12#include <sched.h>13#include <unistd.h>14#include <assert.h>15 16#include "hwprobe.h"17#include "../../kselftest.h"18 19static void help(void)20{21	printf("\n"22	       "which-cpus: [-h] [<key=value> [<key=value> ...]]\n\n"23	       "   Without parameters, tests the RISCV_HWPROBE_WHICH_CPUS flag of hwprobe.\n"24	       "   With parameters, where each parameter is a hwprobe pair written as\n"25	       "   <key=value>, outputs the cpulist for cpus which all match the given set\n"26	       "   of pairs.  'key' and 'value' should be in numeric form, e.g. 4=0x3b\n");27}28 29static void print_cpulist(cpu_set_t *cpus)30{31	int start = 0, end = 0;32 33	if (!CPU_COUNT(cpus)) {34		printf("cpus: None\n");35		return;36	}37 38	printf("cpus:");39	for (int i = 0, c = 0; i < CPU_COUNT(cpus); i++, c++) {40		if (start != end && !CPU_ISSET(c, cpus))41			printf("-%d", end);42 43		while (!CPU_ISSET(c, cpus))44			++c;45 46		if (i != 0 && c == end + 1) {47			end = c;48			continue;49		}50 51		printf("%c%d", i == 0 ? ' ' : ',', c);52		start = end = c;53	}54	if (start != end)55		printf("-%d", end);56	printf("\n");57}58 59static void do_which_cpus(int argc, char **argv, cpu_set_t *cpus)60{61	struct riscv_hwprobe *pairs;62	int nr_pairs = argc - 1;63	char *start, *end;64	int rc;65 66	pairs = malloc(nr_pairs * sizeof(struct riscv_hwprobe));67	assert(pairs);68 69	for (int i = 0; i < nr_pairs; i++) {70		start = argv[i + 1];71		pairs[i].key = strtol(start, &end, 0);72		assert(end != start && *end == '=');73		start = end + 1;74		pairs[i].value = strtoul(start, &end, 0);75		assert(end != start && *end == '\0');76	}77 78	rc = riscv_hwprobe(pairs, nr_pairs, sizeof(cpu_set_t), (unsigned long *)cpus, RISCV_HWPROBE_WHICH_CPUS);79	assert(rc == 0);80	print_cpulist(cpus);81	free(pairs);82}83 84int main(int argc, char **argv)85{86	struct riscv_hwprobe pairs[2];87	cpu_set_t cpus_aff, cpus;88	__u64 ext0_all;89	long rc;90 91	rc = sched_getaffinity(0, sizeof(cpu_set_t), &cpus_aff);92	assert(rc == 0);93 94	if (argc > 1) {95		if (!strcmp(argv[1], "-h"))96			help();97		else98			do_which_cpus(argc, argv, &cpus_aff);99		return 0;100	}101 102	ksft_print_header();103	ksft_set_plan(7);104 105	pairs[0] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_BASE_BEHAVIOR, };106	rc = riscv_hwprobe(pairs, 1, 0, NULL, 0);107	assert(rc == 0 && pairs[0].key == RISCV_HWPROBE_KEY_BASE_BEHAVIOR &&108	       pairs[0].value == RISCV_HWPROBE_BASE_BEHAVIOR_IMA);109 110	pairs[0] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_IMA_EXT_0, };111	rc = riscv_hwprobe(pairs, 1, 0, NULL, 0);112	assert(rc == 0 && pairs[0].key == RISCV_HWPROBE_KEY_IMA_EXT_0);113	ext0_all = pairs[0].value;114 115	pairs[0] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_BASE_BEHAVIOR, .value = RISCV_HWPROBE_BASE_BEHAVIOR_IMA, };116	CPU_ZERO(&cpus);117	rc = riscv_hwprobe(pairs, 1, 0, (unsigned long *)&cpus, RISCV_HWPROBE_WHICH_CPUS);118	ksft_test_result(rc == -EINVAL, "no cpusetsize\n");119 120	pairs[0] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_BASE_BEHAVIOR, .value = RISCV_HWPROBE_BASE_BEHAVIOR_IMA, };121	rc = riscv_hwprobe(pairs, 1, sizeof(cpu_set_t), NULL, RISCV_HWPROBE_WHICH_CPUS);122	ksft_test_result(rc == -EINVAL, "NULL cpus\n");123 124	pairs[0] = (struct riscv_hwprobe){ .key = 0xbadc0de, };125	CPU_ZERO(&cpus);126	rc = riscv_hwprobe(pairs, 1, sizeof(cpu_set_t), (unsigned long *)&cpus, RISCV_HWPROBE_WHICH_CPUS);127	ksft_test_result(rc == 0 && CPU_COUNT(&cpus) == 0, "unknown key\n");128 129	pairs[0] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_BASE_BEHAVIOR, .value = RISCV_HWPROBE_BASE_BEHAVIOR_IMA, };130	pairs[1] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_BASE_BEHAVIOR, .value = RISCV_HWPROBE_BASE_BEHAVIOR_IMA, };131	CPU_ZERO(&cpus);132	rc = riscv_hwprobe(pairs, 2, sizeof(cpu_set_t), (unsigned long *)&cpus, RISCV_HWPROBE_WHICH_CPUS);133	ksft_test_result(rc == 0, "duplicate keys\n");134 135	pairs[0] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_BASE_BEHAVIOR, .value = RISCV_HWPROBE_BASE_BEHAVIOR_IMA, };136	pairs[1] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_IMA_EXT_0, .value = ext0_all, };137	CPU_ZERO(&cpus);138	rc = riscv_hwprobe(pairs, 2, sizeof(cpu_set_t), (unsigned long *)&cpus, RISCV_HWPROBE_WHICH_CPUS);139	ksft_test_result(rc == 0 && CPU_COUNT(&cpus) == sysconf(_SC_NPROCESSORS_ONLN), "set all cpus\n");140 141	pairs[0] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_BASE_BEHAVIOR, .value = RISCV_HWPROBE_BASE_BEHAVIOR_IMA, };142	pairs[1] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_IMA_EXT_0, .value = ext0_all, };143	memcpy(&cpus, &cpus_aff, sizeof(cpu_set_t));144	rc = riscv_hwprobe(pairs, 2, sizeof(cpu_set_t), (unsigned long *)&cpus, RISCV_HWPROBE_WHICH_CPUS);145	ksft_test_result(rc == 0 && CPU_EQUAL(&cpus, &cpus_aff), "set all affinity cpus\n");146 147	pairs[0] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_BASE_BEHAVIOR, .value = RISCV_HWPROBE_BASE_BEHAVIOR_IMA, };148	pairs[1] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_IMA_EXT_0, .value = ~ext0_all, };149	memcpy(&cpus, &cpus_aff, sizeof(cpu_set_t));150	rc = riscv_hwprobe(pairs, 2, sizeof(cpu_set_t), (unsigned long *)&cpus, RISCV_HWPROBE_WHICH_CPUS);151	ksft_test_result(rc == 0 && CPU_COUNT(&cpus) == 0, "clear all cpus\n");152 153	ksft_finished();154}155