Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags   |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * config.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Helper functions for parsing config items.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Originally copied from GIT source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Copyright (C) Linus Torvalds, 2005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Copyright (C) Johannes Schindelin, 2005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <sys/param.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "cache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "callchain.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <subcmd/exec-cmd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "util/event.h"  /* proc_map_timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "util/hist.h"  /* perf_hist_config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "util/llvm-utils.h"   /* perf_llvm_config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "util/stat.h"  /* perf_stat__set_big_num */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "build-id.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "config.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define MAXNAME (256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define DEBUG_CACHE_DIR ".debug"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) char buildid_dir[MAXPATHLEN]; /* root dir for buildid, binary cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static FILE *config_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static const char *config_file_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) static int config_linenr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static int config_file_eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) static struct perf_config_set *config_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) const char *config_exclusive_filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static int get_next_char(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	FILE *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	c = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	if ((f = config_file) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		c = fgetc(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		if (c == '\r') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 			/* DOS like systems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 			c = fgetc(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			if (c != '\n') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 				ungetc(c, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 				c = '\r';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		if (c == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 			config_linenr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		if (c == EOF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 			config_file_eof = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 			c = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	return c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) static char *parse_value(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	static char value[1024];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	int quote = 0, comment = 0, space = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	size_t len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		int c = get_next_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		if (len >= sizeof(value) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		if (c == '\n') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			if (quote)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 				return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 			value[len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		if (comment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		if (isspace(c) && !quote) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			space = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		if (!quote) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			if (c == ';' || c == '#') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 				comment = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		if (space) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			if (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 				value[len++] = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			space = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		if (c == '\\') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			c = get_next_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			switch (c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 			case '\n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			case 't':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 				c = '\t';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			case 'b':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 				c = '\b';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 				c = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			/* Some characters escape as themselves */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			case '\\': case '"':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 			/* Reject unknown escape sequences */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 				return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			value[len++] = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		if (c == '"') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			quote = 1-quote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		value[len++] = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static inline int iskeychar(int c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	return isalnum(c) || c == '-' || c == '_';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	char *value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	/* Get the full name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		c = get_next_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		if (config_file_eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		if (!iskeychar(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		name[len++] = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		if (len >= MAXNAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	name[len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	while (c == ' ' || c == '\t')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		c = get_next_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	value = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (c != '\n') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		if (c != '=')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		value = parse_value();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		if (!value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	return fn(name, value, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int get_extended_base_var(char *name, int baselen, int c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		if (c == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		c = get_next_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	} while (isspace(c));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	/* We require the format to be '[base "extension"]' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	if (c != '"')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	name[baselen++] = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		int ch = get_next_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		if (ch == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		if (ch == '"')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		if (ch == '\\') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			ch = get_next_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 			if (ch == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 				return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		name[baselen++] = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		if (baselen > MAXNAME / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	/* Final ']' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	if (get_next_char() != ']')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	return baselen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static int get_base_var(char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	int baselen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		int c = get_next_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		if (config_file_eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		if (c == ']')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			return baselen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		if (isspace(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			return get_extended_base_var(name, baselen, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		if (!iskeychar(c) && c != '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		if (baselen > MAXNAME / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		name[baselen++] = tolower(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static int perf_parse_file(config_fn_t fn, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	int comment = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	int baselen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	static char var[MAXNAME];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	/* U+FEFF Byte Order Mark in UTF8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	const unsigned char *bomptr = utf8_bom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		int line, c = get_next_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		if (bomptr && *bomptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			/* We are at the file beginning; skip UTF8-encoded BOM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			 * if present. Sane editors won't put this in on their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			 * own, but e.g. Windows Notepad will do it happily. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			if ((unsigned char) c == *bomptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 				bomptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 				/* Do not tolerate partial BOM. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 				if (bomptr != utf8_bom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 				/* No BOM at file beginning. Cool. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 				bomptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		if (c == '\n') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			if (config_file_eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			comment = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		if (comment || isspace(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		if (c == '#' || c == ';') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 			comment = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		if (c == '[') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 			baselen = get_base_var(var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 			if (baselen <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 			var[baselen++] = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			var[baselen] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		if (!isalpha(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		var[baselen] = tolower(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		 * The get_value function might or might not reach the '\n',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		 * so saving the current line number for error reporting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		line = config_linenr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		if (get_value(fn, data, var, baselen+1) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			config_linenr = line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	pr_err("bad config file line %d in %s\n", config_linenr, config_file_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static int parse_unit_factor(const char *end, unsigned long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	if (!*end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	else if (!strcasecmp(end, "k")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		*val *= 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	else if (!strcasecmp(end, "m")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		*val *= 1024 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	else if (!strcasecmp(end, "g")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		*val *= 1024 * 1024 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static int perf_parse_llong(const char *value, long long *ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	if (value && *value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		char *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		long long val = strtoll(value, &end, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		unsigned long factor = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		if (!parse_unit_factor(end, &factor))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		*ret = val * factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static int perf_parse_long(const char *value, long *ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	if (value && *value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		char *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		long val = strtol(value, &end, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		unsigned long factor = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		if (!parse_unit_factor(end, &factor))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		*ret = val * factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static void bad_config(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	if (config_file_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		pr_warning("bad config value for '%s' in %s, ignoring...\n", name, config_file_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		pr_warning("bad config value for '%s', ignoring...\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int perf_config_u64(u64 *dest, const char *name, const char *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	long long ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	if (!perf_parse_llong(value, &ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		bad_config(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	*dest = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int perf_config_int(int *dest, const char *name, const char *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	long ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	if (!perf_parse_long(value, &ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		bad_config(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	*dest = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int perf_config_u8(u8 *dest, const char *name, const char *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	long ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (!perf_parse_long(value, &ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		bad_config(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	*dest = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static int perf_config_bool_or_int(const char *name, const char *value, int *is_bool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	*is_bool = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	if (!value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	if (!*value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	if (!strcasecmp(value, "true") || !strcasecmp(value, "yes") || !strcasecmp(value, "on"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	if (!strcasecmp(value, "false") || !strcasecmp(value, "no") || !strcasecmp(value, "off"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	*is_bool = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	return perf_config_int(&ret, name, value) < 0 ? -1 : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int perf_config_bool(const char *name, const char *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	int discard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	return !!perf_config_bool_or_int(name, value, &discard);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static const char *perf_config_dirname(const char *name, const char *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static int perf_buildid_config(const char *var, const char *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	/* same dir for all commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	if (!strcmp(var, "buildid.dir")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		const char *dir = perf_config_dirname(var, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		if (!dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			pr_err("Invalid buildid directory!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		strncpy(buildid_dir, dir, MAXPATHLEN-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		buildid_dir[MAXPATHLEN-1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static int perf_default_core_config(const char *var __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 				    const char *value __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	if (!strcmp(var, "core.proc-map-timeout"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		proc_map_timeout = strtoul(value, NULL, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	/* Add other config variables here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static int perf_ui_config(const char *var, const char *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	/* Add other config variables here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	if (!strcmp(var, "ui.show-headers"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		symbol_conf.show_hist_headers = perf_config_bool(var, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static int perf_stat_config(const char *var, const char *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	if (!strcmp(var, "stat.big-num"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		perf_stat__set_big_num(perf_config_bool(var, value));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	/* Add other config variables here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int perf_default_config(const char *var, const char *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			void *dummy __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	if (strstarts(var, "core."))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		return perf_default_core_config(var, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	if (strstarts(var, "hist."))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		return perf_hist_config(var, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	if (strstarts(var, "ui."))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		return perf_ui_config(var, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	if (strstarts(var, "call-graph."))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		return perf_callchain_config(var, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	if (strstarts(var, "llvm."))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		return perf_llvm_config(var, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	if (strstarts(var, "buildid."))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		return perf_buildid_config(var, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	if (strstarts(var, "stat."))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		return perf_stat_config(var, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	/* Add other config variables here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) int perf_config_from_file(config_fn_t fn, const char *filename, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	FILE *f = fopen(filename, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	if (f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		config_file = f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		config_file_name = filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		config_linenr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		config_file_eof = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		ret = perf_parse_file(fn, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		fclose(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		config_file_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) const char *perf_etc_perfconfig(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	static const char *system_wide;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	if (!system_wide)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		system_wide = system_path(ETC_PERFCONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	return system_wide;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static int perf_env_bool(const char *k, int def)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	const char *v = getenv(k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	return v ? perf_config_bool(k, v) : def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static int perf_config_system(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	return !perf_env_bool("PERF_CONFIG_NOSYSTEM", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static int perf_config_global(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static struct perf_config_section *find_section(struct list_head *sections,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 						const char *section_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	struct perf_config_section *section;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	list_for_each_entry(section, sections, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		if (!strcmp(section->name, section_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 			return section;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static struct perf_config_item *find_config_item(const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 						 struct perf_config_section *section)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	struct perf_config_item *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	list_for_each_entry(item, &section->items, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		if (!strcmp(item->name, name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 			return item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static struct perf_config_section *add_section(struct list_head *sections,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 					       const char *section_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	struct perf_config_section *section = zalloc(sizeof(*section));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	if (!section)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	INIT_LIST_HEAD(&section->items);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	section->name = strdup(section_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	if (!section->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		pr_debug("%s: strdup failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		free(section);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	list_add_tail(&section->node, sections);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	return section;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static struct perf_config_item *add_config_item(struct perf_config_section *section,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 						const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	struct perf_config_item *item = zalloc(sizeof(*item));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	if (!item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	item->name = strdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	if (!item->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		pr_debug("%s: strdup failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		free(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	list_add_tail(&item->node, &section->items);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	return item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static int set_value(struct perf_config_item *item, const char *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	char *val = strdup(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	zfree(&item->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	item->value = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static int collect_config(const char *var, const char *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 			  void *perf_config_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	char *ptr, *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	char *section_name, *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	struct perf_config_section *section = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	struct perf_config_item *item = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	struct perf_config_set *set = perf_config_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	struct list_head *sections;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	if (set == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	sections = &set->sections;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	key = ptr = strdup(var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	if (!key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		pr_debug("%s: strdup failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	section_name = strsep(&ptr, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	name = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	if (name == NULL || value == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	section = find_section(sections, section_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	if (!section) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		section = add_section(sections, section_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		if (!section)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 			goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	item = find_config_item(name, section);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	if (!item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		item = add_config_item(section, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 		if (!item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 			goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	/* perf_config_set can contain both user and system config items.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	 * So we should know where each value is from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	 * The classification would be needed when a particular config file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	 * is overwrited by setting feature i.e. set_config().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	if (strcmp(config_file_name, perf_etc_perfconfig()) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		section->from_system_config = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		item->from_system_config = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		section->from_system_config = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 		item->from_system_config = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	ret = set_value(item, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	free(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) int perf_config_set__collect(struct perf_config_set *set, const char *file_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 			     const char *var, const char *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	config_file_name = file_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	return collect_config(var, value, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) static int perf_config_set__init(struct perf_config_set *set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	const char *home = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	char *user_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	struct stat st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	/* Setting $PERF_CONFIG makes perf read _only_ the given config file. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	if (config_exclusive_filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		return perf_config_from_file(collect_config, config_exclusive_filename, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 		if (perf_config_from_file(collect_config, perf_etc_perfconfig(), set) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	home = getenv("HOME");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	 * Skip reading user config if:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	 *   - there is no place to read it from (HOME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	 *   - we are asked not to (PERF_CONFIG_NOGLOBAL=1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	if (!home || !*home || !perf_config_global())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	user_config = strdup(mkpath("%s/.perfconfig", home));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	if (user_config == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		pr_warning("Not enough memory to process %s/.perfconfig, ignoring it.", home);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	if (stat(user_config, &st) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 		if (errno == ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 			ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	if (st.st_uid && (st.st_uid != geteuid())) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 		pr_warning("File %s not owned by current user or root, ignoring it.", user_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	if (st.st_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		ret = perf_config_from_file(collect_config, user_config, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	free(user_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) struct perf_config_set *perf_config_set__new(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	struct perf_config_set *set = zalloc(sizeof(*set));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	if (set) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		INIT_LIST_HEAD(&set->sections);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 		perf_config_set__init(set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	return set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) static int perf_config__init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	if (config_set == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 		config_set = perf_config_set__new();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	return config_set == NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) int perf_config(config_fn_t fn, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	char key[BUFSIZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	struct perf_config_section *section;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	struct perf_config_item *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	if (config_set == NULL && perf_config__init())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	perf_config_set__for_each_entry(config_set, section, item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 		char *value = item->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 		if (value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 			scnprintf(key, sizeof(key), "%s.%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 				  section->name, item->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 			ret = fn(key, value, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 				pr_err("Error: wrong config key-value pair %s=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 				       key, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 				 * Can't be just a 'break', as perf_config_set__for_each_entry()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 				 * expands to two nested for() loops.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) void perf_config__exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	perf_config_set__delete(config_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	config_set = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) void perf_config__refresh(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	perf_config__exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	perf_config__init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) static void perf_config_item__delete(struct perf_config_item *item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 	zfree(&item->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	zfree(&item->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	free(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) static void perf_config_section__purge(struct perf_config_section *section)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	struct perf_config_item *item, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 	list_for_each_entry_safe(item, tmp, &section->items, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 		list_del_init(&item->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 		perf_config_item__delete(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static void perf_config_section__delete(struct perf_config_section *section)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 	perf_config_section__purge(section);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	zfree(&section->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	free(section);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static void perf_config_set__purge(struct perf_config_set *set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	struct perf_config_section *section, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	list_for_each_entry_safe(section, tmp, &set->sections, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 		list_del_init(&section->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 		perf_config_section__delete(section);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) void perf_config_set__delete(struct perf_config_set *set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	if (set == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	perf_config_set__purge(set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	free(set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)  * Call this to report error for your variable that should not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)  * get a boolean value (i.e. "[my] var" means "true").
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) int config_error_nonbool(const char *var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	pr_err("Missing value for '%s'", var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) void set_buildid_dir(const char *dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	if (dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 		scnprintf(buildid_dir, MAXPATHLEN, "%s", dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 	/* default to $HOME/.debug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 	if (buildid_dir[0] == '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 		char *home = getenv("HOME");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 		if (home) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 			snprintf(buildid_dir, MAXPATHLEN, "%s/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 				 home, DEBUG_CACHE_DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 			strncpy(buildid_dir, DEBUG_CACHE_DIR, MAXPATHLEN-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 		buildid_dir[MAXPATHLEN-1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	/* for communicating with external commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 	setenv("PERF_BUILDID_DIR", buildid_dir, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }