Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf llvm: Extract helpers in llvm-utils.c

The following commits will use builtin clang to compile BPF scripts.

llvm__get_kbuild_opts() and llvm__get_nr_cpus() are extracted to help
building '-DKERNEL_VERSION_CODE' and '-D__NR_CPUS__' macros.

Doing object dumping in bpf loader, so further builtin clang compiling
needn't consider it.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Joe Stringer <joe@ovn.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/20161126070354.141764-7-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Wang Nan and committed by
Arnaldo Carvalho de Melo
2bd42de0 8ad85e9e

+68 -18
+4
tools/perf/util/bpf-loader.c
··· 90 90 if (err) 91 91 return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE); 92 92 obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename); 93 + 94 + if (!IS_ERR(obj) && llvm_param.dump_obj) 95 + llvm__dump_obj(filename, obj_buf, obj_buf_sz); 96 + 93 97 free(obj_buf); 94 98 } else 95 99 obj = bpf_object__open(filename);
+58 -18
tools/perf/util/llvm-utils.c
··· 7 7 #include <limits.h> 8 8 #include <stdio.h> 9 9 #include <stdlib.h> 10 + #include <linux/err.h> 10 11 #include "debug.h" 11 12 #include "llvm-utils.h" 12 13 #include "config.h" ··· 283 282 "rm -rf $TMPDIR\n" 284 283 "exit $RET\n"; 285 284 286 - static inline void 287 - get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts) 285 + void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts) 288 286 { 287 + static char *saved_kbuild_dir; 288 + static char *saved_kbuild_include_opts; 289 289 int err; 290 290 291 291 if (!kbuild_dir || !kbuild_include_opts) ··· 295 293 *kbuild_dir = NULL; 296 294 *kbuild_include_opts = NULL; 297 295 296 + if (saved_kbuild_dir && saved_kbuild_include_opts && 297 + !IS_ERR(saved_kbuild_dir) && !IS_ERR(saved_kbuild_include_opts)) { 298 + *kbuild_dir = strdup(saved_kbuild_dir); 299 + *kbuild_include_opts = strdup(saved_kbuild_include_opts); 300 + 301 + if (*kbuild_dir && *kbuild_include_opts) 302 + return; 303 + 304 + zfree(kbuild_dir); 305 + zfree(kbuild_include_opts); 306 + /* 307 + * Don't fall through: it may breaks saved_kbuild_dir and 308 + * saved_kbuild_include_opts if detect them again when 309 + * memory is low. 310 + */ 311 + return; 312 + } 313 + 298 314 if (llvm_param.kbuild_dir && !llvm_param.kbuild_dir[0]) { 299 315 pr_debug("[llvm.kbuild-dir] is set to \"\" deliberately.\n"); 300 316 pr_debug("Skip kbuild options detection.\n"); 301 - return; 317 + goto errout; 302 318 } 303 319 304 320 err = detect_kbuild_dir(kbuild_dir); ··· 326 306 "Hint:\tSet correct kbuild directory using 'kbuild-dir' option in [llvm]\n" 327 307 " \tsection of ~/.perfconfig or set it to \"\" to suppress kbuild\n" 328 308 " \tdetection.\n\n"); 329 - return; 309 + goto errout; 330 310 } 331 311 332 312 pr_debug("Kernel build dir is set to %s\n", *kbuild_dir); ··· 345 325 346 326 free(*kbuild_dir); 347 327 *kbuild_dir = NULL; 348 - return; 328 + goto errout; 349 329 } 350 330 351 331 pr_debug("include option is set to %s\n", *kbuild_include_opts); 332 + 333 + saved_kbuild_dir = strdup(*kbuild_dir); 334 + saved_kbuild_include_opts = strdup(*kbuild_include_opts); 335 + 336 + if (!saved_kbuild_dir || !saved_kbuild_include_opts) { 337 + zfree(&saved_kbuild_dir); 338 + zfree(&saved_kbuild_include_opts); 339 + } 340 + return; 341 + errout: 342 + saved_kbuild_dir = ERR_PTR(-EINVAL); 343 + saved_kbuild_include_opts = ERR_PTR(-EINVAL); 352 344 } 353 345 354 - static void 355 - dump_obj(const char *path, void *obj_buf, size_t size) 346 + int llvm__get_nr_cpus(void) 347 + { 348 + static int nr_cpus_avail = 0; 349 + char serr[STRERR_BUFSIZE]; 350 + 351 + if (nr_cpus_avail > 0) 352 + return nr_cpus_avail; 353 + 354 + nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF); 355 + if (nr_cpus_avail <= 0) { 356 + pr_err( 357 + "WARNING:\tunable to get available CPUs in this system: %s\n" 358 + " \tUse 128 instead.\n", str_error_r(errno, serr, sizeof(serr))); 359 + nr_cpus_avail = 128; 360 + } 361 + return nr_cpus_avail; 362 + } 363 + 364 + void llvm__dump_obj(const char *path, void *obj_buf, size_t size) 356 365 { 357 366 char *obj_path = strdup(path); 358 367 FILE *fp; ··· 455 406 * This is an optional work. Even it fail we can continue our 456 407 * work. Needn't to check error return. 457 408 */ 458 - get_kbuild_opts(&kbuild_dir, &kbuild_include_opts); 409 + llvm__get_kbuild_opts(&kbuild_dir, &kbuild_include_opts); 459 410 460 - nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF); 461 - if (nr_cpus_avail <= 0) { 462 - pr_err( 463 - "WARNING:\tunable to get available CPUs in this system: %s\n" 464 - " \tUse 128 instead.\n", str_error_r(errno, serr, sizeof(serr))); 465 - nr_cpus_avail = 128; 466 - } 411 + nr_cpus_avail = llvm__get_nr_cpus(); 467 412 snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d", 468 413 nr_cpus_avail); 469 414 ··· 495 452 496 453 free(kbuild_dir); 497 454 free(kbuild_include_opts); 498 - 499 - if (llvm_param.dump_obj) 500 - dump_obj(path, obj_buf, obj_buf_sz); 501 455 502 456 if (!p_obj_buf) 503 457 free(obj_buf);
+6
tools/perf/util/llvm-utils.h
··· 50 50 51 51 /* This function is for test__llvm() use only */ 52 52 int llvm__search_clang(void); 53 + 54 + /* Following functions are reused by builtin clang support */ 55 + void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts); 56 + int llvm__get_nr_cpus(void); 57 + 58 + void llvm__dump_obj(const char *path, void *obj_buf, size_t size); 53 59 #endif