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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
"Misc fixes:

- counter freezing related regression fix

- uprobes race fix

- Intel PMU unusual event combination fix

- .. and diverse tooling fixes"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
uprobes: Fix handle_swbp() vs. unregister() + register() race once more
perf/x86/intel: Disallow precise_ip on BTS events
perf/x86/intel: Add generic branch tracing check to intel_pmu_has_bts()
perf/x86/intel: Move branch tracing setup to the Intel-specific source file
perf/x86/intel: Fix regression by default disabling perfmon v4 interrupt handling
perf tools beauty ioctl: Support new ISO7816 commands
tools uapi asm-generic: Synchronize ioctls.h
tools arch x86: Update tools's copy of cpufeatures.h
tools headers uapi: Synchronize i915_drm.h
perf tools: Restore proper cwd on return from mnt namespace
tools build feature: Check if get_current_dir_name() is available
perf tools: Fix crash on synthesizing the unit

+166 -47
+2 -1
Documentation/admin-guide/kernel-parameters.txt
··· 856 856 causing system reset or hang due to sending 857 857 INIT from AP to BSP. 858 858 859 - disable_counter_freezing [HW] 859 + perf_v4_pmi= [X86,INTEL] 860 + Format: <bool> 860 861 Disable Intel PMU counter freezing feature. 861 862 The feature only exists starting from 862 863 Arch Perfmon v4 (Skylake and newer).
-20
arch/x86/events/core.c
··· 438 438 if (config == -1LL) 439 439 return -EINVAL; 440 440 441 - /* 442 - * Branch tracing: 443 - */ 444 - if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS && 445 - !attr->freq && hwc->sample_period == 1) { 446 - /* BTS is not supported by this architecture. */ 447 - if (!x86_pmu.bts_active) 448 - return -EOPNOTSUPP; 449 - 450 - /* BTS is currently only allowed for user-mode. */ 451 - if (!attr->exclude_kernel) 452 - return -EOPNOTSUPP; 453 - 454 - /* disallow bts if conflicting events are present */ 455 - if (x86_add_exclusive(x86_lbr_exclusive_lbr)) 456 - return -EBUSY; 457 - 458 - event->destroy = hw_perf_lbr_event_destroy; 459 - } 460 - 461 441 hwc->config |= config; 462 442 463 443 return 0;
+52 -16
arch/x86/events/intel/core.c
··· 2306 2306 return handled; 2307 2307 } 2308 2308 2309 - static bool disable_counter_freezing; 2309 + static bool disable_counter_freezing = true; 2310 2310 static int __init intel_perf_counter_freezing_setup(char *s) 2311 2311 { 2312 - disable_counter_freezing = true; 2313 - pr_info("Intel PMU Counter freezing feature disabled\n"); 2312 + bool res; 2313 + 2314 + if (kstrtobool(s, &res)) 2315 + return -EINVAL; 2316 + 2317 + disable_counter_freezing = !res; 2314 2318 return 1; 2315 2319 } 2316 - __setup("disable_counter_freezing", intel_perf_counter_freezing_setup); 2320 + __setup("perf_v4_pmi=", intel_perf_counter_freezing_setup); 2317 2321 2318 2322 /* 2319 2323 * Simplified handler for Arch Perfmon v4: ··· 2474 2470 static struct event_constraint * 2475 2471 intel_bts_constraints(struct perf_event *event) 2476 2472 { 2477 - struct hw_perf_event *hwc = &event->hw; 2478 - unsigned int hw_event, bts_event; 2479 - 2480 - if (event->attr.freq) 2481 - return NULL; 2482 - 2483 - hw_event = hwc->config & INTEL_ARCH_EVENT_MASK; 2484 - bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS); 2485 - 2486 - if (unlikely(hw_event == bts_event && hwc->sample_period == 1)) 2473 + if (unlikely(intel_pmu_has_bts(event))) 2487 2474 return &bts_constraint; 2488 2475 2489 2476 return NULL; ··· 3093 3098 return flags; 3094 3099 } 3095 3100 3101 + static int intel_pmu_bts_config(struct perf_event *event) 3102 + { 3103 + struct perf_event_attr *attr = &event->attr; 3104 + 3105 + if (unlikely(intel_pmu_has_bts(event))) { 3106 + /* BTS is not supported by this architecture. */ 3107 + if (!x86_pmu.bts_active) 3108 + return -EOPNOTSUPP; 3109 + 3110 + /* BTS is currently only allowed for user-mode. */ 3111 + if (!attr->exclude_kernel) 3112 + return -EOPNOTSUPP; 3113 + 3114 + /* BTS is not allowed for precise events. */ 3115 + if (attr->precise_ip) 3116 + return -EOPNOTSUPP; 3117 + 3118 + /* disallow bts if conflicting events are present */ 3119 + if (x86_add_exclusive(x86_lbr_exclusive_lbr)) 3120 + return -EBUSY; 3121 + 3122 + event->destroy = hw_perf_lbr_event_destroy; 3123 + } 3124 + 3125 + return 0; 3126 + } 3127 + 3128 + static int core_pmu_hw_config(struct perf_event *event) 3129 + { 3130 + int ret = x86_pmu_hw_config(event); 3131 + 3132 + if (ret) 3133 + return ret; 3134 + 3135 + return intel_pmu_bts_config(event); 3136 + } 3137 + 3096 3138 static int intel_pmu_hw_config(struct perf_event *event) 3097 3139 { 3098 3140 int ret = x86_pmu_hw_config(event); 3099 3141 3142 + if (ret) 3143 + return ret; 3144 + 3145 + ret = intel_pmu_bts_config(event); 3100 3146 if (ret) 3101 3147 return ret; 3102 3148 ··· 3163 3127 /* 3164 3128 * BTS is set up earlier in this path, so don't account twice 3165 3129 */ 3166 - if (!intel_pmu_has_bts(event)) { 3130 + if (!unlikely(intel_pmu_has_bts(event))) { 3167 3131 /* disallow lbr if conflicting events are present */ 3168 3132 if (x86_add_exclusive(x86_lbr_exclusive_lbr)) 3169 3133 return -EBUSY; ··· 3632 3596 .enable_all = core_pmu_enable_all, 3633 3597 .enable = core_pmu_enable_event, 3634 3598 .disable = x86_pmu_disable_event, 3635 - .hw_config = x86_pmu_hw_config, 3599 + .hw_config = core_pmu_hw_config, 3636 3600 .schedule_events = x86_schedule_events, 3637 3601 .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, 3638 3602 .perfctr = MSR_ARCH_PERFMON_PERFCTR0,
+9 -4
arch/x86/events/perf_event.h
··· 859 859 860 860 static inline bool intel_pmu_has_bts(struct perf_event *event) 861 861 { 862 - if (event->attr.config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS && 863 - !event->attr.freq && event->hw.sample_period == 1) 864 - return true; 862 + struct hw_perf_event *hwc = &event->hw; 863 + unsigned int hw_event, bts_event; 865 864 866 - return false; 865 + if (event->attr.freq) 866 + return false; 867 + 868 + hw_event = hwc->config & INTEL_ARCH_EVENT_MASK; 869 + bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS); 870 + 871 + return hw_event == bts_event && hwc->sample_period == 1; 867 872 } 868 873 869 874 int intel_pmu_save_and_restart(struct perf_event *event);
+10 -2
kernel/events/uprobes.c
··· 829 829 BUG_ON((uprobe->offset & ~PAGE_MASK) + 830 830 UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); 831 831 832 - smp_wmb(); /* pairs with rmb() in find_active_uprobe() */ 832 + smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */ 833 833 set_bit(UPROBE_COPY_INSN, &uprobe->flags); 834 834 835 835 out: ··· 2178 2178 * After we hit the bp, _unregister + _register can install the 2179 2179 * new and not-yet-analyzed uprobe at the same address, restart. 2180 2180 */ 2181 - smp_rmb(); /* pairs with wmb() in install_breakpoint() */ 2182 2181 if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags))) 2183 2182 goto out; 2183 + 2184 + /* 2185 + * Pairs with the smp_wmb() in prepare_uprobe(). 2186 + * 2187 + * Guarantees that if we see the UPROBE_COPY_INSN bit set, then 2188 + * we must also see the stores to &uprobe->arch performed by the 2189 + * prepare_uprobe() call. 2190 + */ 2191 + smp_rmb(); 2184 2192 2185 2193 /* Tracing handlers use ->utask to communicate with fetch methods */ 2186 2194 if (!get_utask())
+2
tools/arch/x86/include/asm/cpufeatures.h
··· 331 331 #define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */ 332 332 #define X86_FEATURE_RDPID (16*32+22) /* RDPID instruction */ 333 333 #define X86_FEATURE_CLDEMOTE (16*32+25) /* CLDEMOTE instruction */ 334 + #define X86_FEATURE_MOVDIRI (16*32+27) /* MOVDIRI instruction */ 335 + #define X86_FEATURE_MOVDIR64B (16*32+28) /* MOVDIR64B instruction */ 334 336 335 337 /* AMD-defined CPU features, CPUID level 0x80000007 (EBX), word 17 */ 336 338 #define X86_FEATURE_OVERFLOW_RECOV (17*32+ 0) /* MCA overflow recovery support */
+1
tools/build/Makefile.feature
··· 33 33 dwarf_getlocations \ 34 34 fortify-source \ 35 35 sync-compare-and-swap \ 36 + get_current_dir_name \ 36 37 glibc \ 37 38 gtk2 \ 38 39 gtk2-infobar \
+4
tools/build/feature/Makefile
··· 7 7 test-dwarf_getlocations.bin \ 8 8 test-fortify-source.bin \ 9 9 test-sync-compare-and-swap.bin \ 10 + test-get_current_dir_name.bin \ 10 11 test-glibc.bin \ 11 12 test-gtk2.bin \ 12 13 test-gtk2-infobar.bin \ ··· 101 100 102 101 $(OUTPUT)test-libelf.bin: 103 102 $(BUILD) -lelf 103 + 104 + $(OUTPUT)test-get_current_dir_name.bin: 105 + $(BUILD) 104 106 105 107 $(OUTPUT)test-glibc.bin: 106 108 $(BUILD)
+5
tools/build/feature/test-all.c
··· 34 34 # include "test-libelf-mmap.c" 35 35 #undef main 36 36 37 + #define main main_test_get_current_dir_name 38 + # include "test-get_current_dir_name.c" 39 + #undef main 40 + 37 41 #define main main_test_glibc 38 42 # include "test-glibc.c" 39 43 #undef main ··· 178 174 main_test_hello(); 179 175 main_test_libelf(); 180 176 main_test_libelf_mmap(); 177 + main_test_get_current_dir_name(); 181 178 main_test_glibc(); 182 179 main_test_dwarf(); 183 180 main_test_dwarf_getlocations();
+10
tools/build/feature/test-get_current_dir_name.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #define _GNU_SOURCE 3 + #include <unistd.h> 4 + #include <stdlib.h> 5 + 6 + int main(void) 7 + { 8 + free(get_current_dir_name()); 9 + return 0; 10 + }
+2
tools/include/uapi/asm-generic/ioctls.h
··· 79 79 #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ 80 80 #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ 81 81 #define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */ 82 + #define TIOCGISO7816 _IOR('T', 0x42, struct serial_iso7816) 83 + #define TIOCSISO7816 _IOWR('T', 0x43, struct serial_iso7816) 82 84 83 85 #define FIONCLEX 0x5450 84 86 #define FIOCLEX 0x5451
+22
tools/include/uapi/drm/i915_drm.h
··· 529 529 */ 530 530 #define I915_PARAM_CS_TIMESTAMP_FREQUENCY 51 531 531 532 + /* 533 + * Once upon a time we supposed that writes through the GGTT would be 534 + * immediately in physical memory (once flushed out of the CPU path). However, 535 + * on a few different processors and chipsets, this is not necessarily the case 536 + * as the writes appear to be buffered internally. Thus a read of the backing 537 + * storage (physical memory) via a different path (with different physical tags 538 + * to the indirect write via the GGTT) will see stale values from before 539 + * the GGTT write. Inside the kernel, we can for the most part keep track of 540 + * the different read/write domains in use (e.g. set-domain), but the assumption 541 + * of coherency is baked into the ABI, hence reporting its true state in this 542 + * parameter. 543 + * 544 + * Reports true when writes via mmap_gtt are immediately visible following an 545 + * lfence to flush the WCB. 546 + * 547 + * Reports false when writes via mmap_gtt are indeterminately delayed in an in 548 + * internal buffer and are _not_ immediately visible to third parties accessing 549 + * directly via mmap_cpu/mmap_wc. Use of mmap_gtt as part of an IPC 550 + * communications channel when reporting false is strongly disadvised. 551 + */ 552 + #define I915_PARAM_MMAP_GTT_COHERENT 52 553 + 532 554 typedef struct drm_i915_getparam { 533 555 __s32 param; 534 556 /*
+5
tools/perf/Makefile.config
··· 299 299 endif 300 300 endif 301 301 302 + ifeq ($(feature-get_current_dir_name), 1) 303 + CFLAGS += -DHAVE_GET_CURRENT_DIR_NAME 304 + endif 305 + 306 + 302 307 ifdef NO_LIBELF 303 308 NO_DWARF := 1 304 309 NO_DEMANGLE := 1
+1 -1
tools/perf/tests/attr/base-record
··· 9 9 config=0 10 10 sample_period=* 11 11 sample_type=263 12 - read_format=0 12 + read_format=0|4 13 13 disabled=1 14 14 inherit=1 15 15 pinned=0
+1
tools/perf/trace/beauty/ioctl.c
··· 31 31 "TCSETSW2", "TCSETSF2", "TIOCGRS48", "TIOCSRS485", "TIOCGPTN", "TIOCSPTLCK", 32 32 "TIOCGDEV", "TCSETX", "TCSETXF", "TCSETXW", "TIOCSIG", "TIOCVHANGUP", "TIOCGPKT", 33 33 "TIOCGPTLCK", [_IOC_NR(TIOCGEXCL)] = "TIOCGEXCL", "TIOCGPTPEER", 34 + "TIOCGISO7816", "TIOCSISO7816", 34 35 [_IOC_NR(FIONCLEX)] = "FIONCLEX", "FIOCLEX", "FIOASYNC", "TIOCSERCONFIG", 35 36 "TIOCSERGWILD", "TIOCSERSWILD", "TIOCGLCKTRMIOS", "TIOCSLCKTRMIOS", 36 37 "TIOCSERGSTRUCT", "TIOCSERGETLSR", "TIOCSERGETMULTI", "TIOCSERSETMULTI",
+1
tools/perf/util/Build
··· 10 10 libperf-y += evsel.o 11 11 libperf-y += evsel_fprintf.o 12 12 libperf-y += find_bit.o 13 + libperf-y += get_current_dir_name.o 13 14 libperf-y += kallsyms.o 14 15 libperf-y += levenshtein.o 15 16 libperf-y += llvm-utils.o
+1 -1
tools/perf/util/evsel.c
··· 1092 1092 attr->exclude_user = 1; 1093 1093 } 1094 1094 1095 - if (evsel->own_cpus) 1095 + if (evsel->own_cpus || evsel->unit) 1096 1096 evsel->attr.read_format |= PERF_FORMAT_ID; 1097 1097 1098 1098 /*
+18
tools/perf/util/get_current_dir_name.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 3 + // 4 + #ifndef HAVE_GET_CURRENT_DIR_NAME 5 + #include "util.h" 6 + #include <unistd.h> 7 + #include <stdlib.h> 8 + #include <stdlib.h> 9 + 10 + /* Android's 'bionic' library, for one, doesn't have this */ 11 + 12 + char *get_current_dir_name(void) 13 + { 14 + char pwd[PATH_MAX]; 15 + 16 + return getcwd(pwd, sizeof(pwd)) == NULL ? NULL : strdup(pwd); 17 + } 18 + #endif // HAVE_GET_CURRENT_DIR_NAME
+15 -2
tools/perf/util/namespaces.c
··· 18 18 #include <stdio.h> 19 19 #include <string.h> 20 20 #include <unistd.h> 21 + #include <asm/bug.h> 21 22 22 23 struct namespaces *namespaces__new(struct namespaces_event *event) 23 24 { ··· 187 186 char curpath[PATH_MAX]; 188 187 int oldns = -1; 189 188 int newns = -1; 189 + char *oldcwd = NULL; 190 190 191 191 if (nc == NULL) 192 192 return; ··· 201 199 if (snprintf(curpath, PATH_MAX, "/proc/self/ns/mnt") >= PATH_MAX) 202 200 return; 203 201 202 + oldcwd = get_current_dir_name(); 203 + if (!oldcwd) 204 + return; 205 + 204 206 oldns = open(curpath, O_RDONLY); 205 207 if (oldns < 0) 206 - return; 208 + goto errout; 207 209 208 210 newns = open(nsi->mntns_path, O_RDONLY); 209 211 if (newns < 0) ··· 216 210 if (setns(newns, CLONE_NEWNS) < 0) 217 211 goto errout; 218 212 213 + nc->oldcwd = oldcwd; 219 214 nc->oldns = oldns; 220 215 nc->newns = newns; 221 216 return; 222 217 223 218 errout: 219 + free(oldcwd); 224 220 if (oldns > -1) 225 221 close(oldns); 226 222 if (newns > -1) ··· 231 223 232 224 void nsinfo__mountns_exit(struct nscookie *nc) 233 225 { 234 - if (nc == NULL || nc->oldns == -1 || nc->newns == -1) 226 + if (nc == NULL || nc->oldns == -1 || nc->newns == -1 || !nc->oldcwd) 235 227 return; 236 228 237 229 setns(nc->oldns, CLONE_NEWNS); 230 + 231 + if (nc->oldcwd) { 232 + WARN_ON_ONCE(chdir(nc->oldcwd)); 233 + zfree(&nc->oldcwd); 234 + } 238 235 239 236 if (nc->oldns > -1) { 240 237 close(nc->oldns);
+1
tools/perf/util/namespaces.h
··· 38 38 struct nscookie { 39 39 int oldns; 40 40 int newns; 41 + char *oldcwd; 41 42 }; 42 43 43 44 int nsinfo__init(struct nsinfo *nsi);
+4
tools/perf/util/util.h
··· 59 59 60 60 const char *perf_tip(const char *dirpath); 61 61 62 + #ifndef HAVE_GET_CURRENT_DIR_NAME 63 + char *get_current_dir_name(void); 64 + #endif 65 + 62 66 #ifndef HAVE_SCHED_GETCPU_SUPPORT 63 67 int sched_getcpu(void); 64 68 #endif