Commit 144c79ef authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'perf-tools-fixes-for-v5.12-2020-03-07' of...

Merge tag 'perf-tools-fixes-for-v5.12-2020-03-07' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

Pull perf tools fixes from Arnaldo Carvalho de Melo:
 "Perf tool fixes:

   - Fix wrong skipping for per-die aggregation in 'perf stat'.

   - Fix race in signal handling on large core count machines, setting
     up signal handlers earlier.

   - Fix -F for branch & mem modes in 'perf report'.

   - Fix the condition checks for max number of NUMA nodes in 'perf
     bench numa'.

   - Fix crash in 'perf diff' error path.

   - Fix filtering of empty build-ids in 'perf archive'.

   - Ensure read cmdlines from libtraceevent are null terminated.

  Recent regressions:

   - Fix control fifo permissions in 'perf daemon'.

   - Fix 'perf daemon' compile error with ASAN.

   - Fix running 'perf daemon' test for non root user.

   - Fix PERF_SAMPLE_WEIGHT_STRUCT 'perf test' failure on non-x86
     arches.

   - Fix event's PMU name parsing related to new drm/i915/gt
     software-gt-awake-time event.

  Fixes from compiler instrumentation:

   - Fix leaks in 'perf test' entries, found using ASAN.

   - Fix use-after-free when 'perf stat -r' option is used.

  Arch specific:

   - Fix bitmap for option om ARM's CS-ETM.

  Documentation:

   - Fix documentation of verbose options.

  Build:

   - Clean 'generated' directory used for creating the syscall table on
     x86.

   - Fix ccache usage in $(CC) when generating arch errno table.

   - Cast (struct timeval).tv_sec when printing, fixing the build with
     MUSL libc.

   - Tighten snprintf() string precision to pass gcc check on some
     32-bit arches.

   - Update UAPI copies from the kernel sources.

   - Fix regression on feature detection 'make clean' target"

* tag 'perf-tools-fixes-for-v5.12-2020-03-07' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux: (44 commits)
  perf cs-etm: Fix bitmap for option
  perf trace: Fix race in signal handling
  perf map: Tighten snprintf() string precision to pass gcc check on some 32-bit arches
  perf report: Fix -F for branch & mem modes
  perf tests x86: Move insn.h include to make sure it finds stddef.h
  perf test: Support the ins_lat check in the X86 specific test
  perf test: Fix sample-parsing failure on non-x86 platforms
  perf archive: Fix filtering of empty build-ids
  perf daemon: Fix compile error with Asan
  perf stat: Fix use-after-free when -r option is used
  libperf: Add perf_evlist__reset_id_hash()
  perf stat: Fix wrong skipping for per-die aggregation
  tools headers UAPI: Sync KVM's kvm.h and vmx.h headers with the kernel sources
  tools headers cpufeatures: Sync with the kernel sources
  tools headers UAPI: Update tools' copy of linux/coresight-pmu.h
  tools headers: Update syscall.tbl files to support mount_setattr
  perf test: Fix cpu and thread map leaks in perf_time_to_tsc test
  perf test: Fix cpu map leaks in cpu_map_print test
  perf test: Fix a memory leak in thread_map_remove test
  perf test: Fix a thread map leak in thread_map_synthesize test
  ...
parents 3bb48a85 6fc5baf5
......@@ -179,8 +179,9 @@
#define ACR_SIZE 4
#define PTRACE_OLDSETOPTIONS 21
#define PTRACE_OLDSETOPTIONS 21
#define PTRACE_SYSEMU 31
#define PTRACE_SYSEMU_SINGLESTEP 32
#ifndef __ASSEMBLY__
#include <linux/stddef.h>
#include <linux/types.h>
......
......@@ -13,7 +13,7 @@
/*
* Defines x86 CPU feature bits
*/
#define NCAPINTS 19 /* N 32-bit words worth of info */
#define NCAPINTS 20 /* N 32-bit words worth of info */
#define NBUGINTS 1 /* N 32-bit bug flags */
/*
......@@ -96,7 +96,7 @@
#define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in IA32 userspace */
#define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in IA32 userspace */
#define X86_FEATURE_REP_GOOD ( 3*32+16) /* REP microcode works well */
#define X86_FEATURE_SME_COHERENT ( 3*32+17) /* "" AMD hardware-enforced cache coherency */
/* FREE! ( 3*32+17) */
#define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" LFENCE synchronizes RDTSC */
#define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */
#define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */
......@@ -201,7 +201,7 @@
#define X86_FEATURE_INVPCID_SINGLE ( 7*32+ 7) /* Effectively INVPCID && CR4.PCIDE=1 */
#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
#define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */
/* FREE! ( 7*32+10) */
#define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation enabled */
#define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */
......@@ -211,7 +211,7 @@
#define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */
#define X86_FEATURE_MBA ( 7*32+18) /* Memory Bandwidth Allocation */
#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */
#define X86_FEATURE_SEV ( 7*32+20) /* AMD Secure Encrypted Virtualization */
/* FREE! ( 7*32+20) */
#define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */
#define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */
#define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */
......@@ -236,8 +236,6 @@
#define X86_FEATURE_EPT_AD ( 8*32+17) /* Intel Extended Page Table access-dirty bit */
#define X86_FEATURE_VMCALL ( 8*32+18) /* "" Hypervisor supports the VMCALL instruction */
#define X86_FEATURE_VMW_VMMCALL ( 8*32+19) /* "" VMware prefers VMMCALL hypercall instruction */
#define X86_FEATURE_SEV_ES ( 8*32+20) /* AMD Secure Encrypted Virtualization - Encrypted State */
#define X86_FEATURE_VM_PAGE_FLUSH ( 8*32+21) /* "" VM Page Flush MSR is supported */
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */
#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/
......@@ -294,6 +292,7 @@
#define X86_FEATURE_PER_THREAD_MBA (11*32+ 7) /* "" Per-thread Memory Bandwidth Allocation */
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */
/* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */
......@@ -337,6 +336,7 @@
#define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */
#define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* Virtual VMSAVE VMLOAD */
#define X86_FEATURE_VGIF (15*32+16) /* Virtual GIF */
#define X86_FEATURE_SVME_ADDR_CHK (15*32+28) /* "" SVME addr check */
/* Intel-defined CPU features, CPUID level 0x00000007:0 (ECX), word 16 */
#define X86_FEATURE_AVX512VBMI (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/
......@@ -385,6 +385,13 @@
#define X86_FEATURE_CORE_CAPABILITIES (18*32+30) /* "" IA32_CORE_CAPABILITIES MSR */
#define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */
/* AMD-defined memory encryption features, CPUID level 0x8000001f (EAX), word 19 */
#define X86_FEATURE_SME (19*32+ 0) /* AMD Secure Memory Encryption */
#define X86_FEATURE_SEV (19*32+ 1) /* AMD Secure Encrypted Virtualization */
#define X86_FEATURE_VM_PAGE_FLUSH (19*32+ 2) /* "" VM Page Flush MSR is supported */
#define X86_FEATURE_SEV_ES (19*32+ 3) /* AMD Secure Encrypted Virtualization - Encrypted State */
#define X86_FEATURE_SME_COHERENT (19*32+10) /* "" AMD hardware-enforced cache coherency */
/*
* BUG word(s)
*/
......
......@@ -112,6 +112,7 @@ struct kvm_ioapic_state {
#define KVM_NR_IRQCHIPS 3
#define KVM_RUN_X86_SMM (1 << 0)
#define KVM_RUN_X86_BUS_LOCK (1 << 1)
/* for KVM_GET_REGS and KVM_SET_REGS */
struct kvm_regs {
......
......@@ -89,6 +89,7 @@
#define EXIT_REASON_XRSTORS 64
#define EXIT_REASON_UMWAIT 67
#define EXIT_REASON_TPAUSE 68
#define EXIT_REASON_BUS_LOCK 74
#define VMX_EXIT_REASONS \
{ EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \
......@@ -150,7 +151,8 @@
{ EXIT_REASON_XSAVES, "XSAVES" }, \
{ EXIT_REASON_XRSTORS, "XRSTORS" }, \
{ EXIT_REASON_UMWAIT, "UMWAIT" }, \
{ EXIT_REASON_TPAUSE, "TPAUSE" }
{ EXIT_REASON_TPAUSE, "TPAUSE" }, \
{ EXIT_REASON_BUS_LOCK, "BUS_LOCK" }
#define VMX_EXIT_REASON_FLAGS \
{ VMX_EXIT_REASONS_FAILED_VMENTRY, "FAILED_VMENTRY" }
......
......@@ -30,12 +30,18 @@ build := -f $(srctree)/tools/build/Makefile.build dir=. obj
all: $(OUTPUT)fixdep
# Make sure there's anything to clean,
# feature contains check for existing OUTPUT
TMP_O := $(if $(OUTPUT),$(OUTPUT)/feature,./)
clean:
$(call QUIET_CLEAN, fixdep)
$(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
$(Q)rm -f $(OUTPUT)fixdep
$(call QUIET_CLEAN, feature-detect)
$(Q)$(MAKE) -C feature/ clean >/dev/null
ifneq ($(wildcard $(TMP_O)),)
$(Q)$(MAKE) -C feature OUTPUT=$(TMP_O) clean >/dev/null
endif
$(OUTPUT)fixdep-in.o: FORCE
$(Q)$(MAKE) $(build)=fixdep
......
......@@ -10,17 +10,27 @@
#define CORESIGHT_ETM_PMU_NAME "cs_etm"
#define CORESIGHT_ETM_PMU_SEED 0x10
/* ETMv3.5/PTM's ETMCR config bit */
#define ETM_OPT_CYCACC 12
#define ETM_OPT_CTXTID 14
#define ETM_OPT_TS 28
#define ETM_OPT_RETSTK 29
/*
* Below are the definition of bit offsets for perf option, and works as
* arbitrary values for all ETM versions.
*
* Most of them are orignally from ETMv3.5/PTM's ETMCR config, therefore,
* ETMv3.5/PTM doesn't define ETMCR config bits with prefix "ETM3_" and
* directly use below macros as config bits.
*/
#define ETM_OPT_CYCACC 12
#define ETM_OPT_CTXTID 14
#define ETM_OPT_CTXTID2 15
#define ETM_OPT_TS 28
#define ETM_OPT_RETSTK 29
/* ETMv4 CONFIGR programming bits for the ETM OPTs */
#define ETM4_CFG_BIT_CYCACC 4
#define ETM4_CFG_BIT_CTXTID 6
#define ETM4_CFG_BIT_VMID 7
#define ETM4_CFG_BIT_TS 11
#define ETM4_CFG_BIT_RETSTK 12
#define ETM4_CFG_BIT_VMID_OPT 15
static inline int coresight_get_trace_id(int cpu)
{
......
/**
* \file drm.h
/*
* Header for the Direct Rendering Manager
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* Author: Rickard E. (Rik) Faith <faith@valinux.com>
*
* \par Acknowledgments:
* Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic \c cmpxchg.
* Acknowledgments:
* Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg.
*/
/*
......@@ -85,7 +84,7 @@ typedef unsigned int drm_context_t;
typedef unsigned int drm_drawable_t;
typedef unsigned int drm_magic_t;
/**
/*
* Cliprect.
*
* \warning: If you change this structure, make sure you change
......@@ -101,7 +100,7 @@ struct drm_clip_rect {
unsigned short y2;
};
/**
/*
* Drawable information.
*/
struct drm_drawable_info {
......@@ -109,7 +108,7 @@ struct drm_drawable_info {
struct drm_clip_rect *rects;
};
/**
/*
* Texture region,
*/
struct drm_tex_region {
......@@ -120,7 +119,7 @@ struct drm_tex_region {
unsigned int age;
};
/**
/*
* Hardware lock.
*
* The lock structure is a simple cache-line aligned integer. To avoid
......@@ -132,7 +131,7 @@ struct drm_hw_lock {
char padding[60]; /**< Pad to cache line */
};
/**
/*
* DRM_IOCTL_VERSION ioctl argument type.
*
* \sa drmGetVersion().
......@@ -149,7 +148,7 @@ struct drm_version {
char __user *desc; /**< User-space buffer to hold desc */
};
/**
/*
* DRM_IOCTL_GET_UNIQUE ioctl argument type.
*
* \sa drmGetBusid() and drmSetBusId().
......@@ -168,7 +167,7 @@ struct drm_block {
int unused;
};
/**
/*
* DRM_IOCTL_CONTROL ioctl argument type.
*
* \sa drmCtlInstHandler() and drmCtlUninstHandler().
......@@ -183,7 +182,7 @@ struct drm_control {
int irq;
};
/**
/*
* Type of memory to map.
*/
enum drm_map_type {
......@@ -195,7 +194,7 @@ enum drm_map_type {
_DRM_CONSISTENT = 5 /**< Consistent memory for PCI DMA */
};
/**
/*
* Memory mapping flags.
*/
enum drm_map_flags {
......@@ -214,7 +213,7 @@ struct drm_ctx_priv_map {
void *handle; /**< Handle of map */
};
/**
/*
* DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls
* argument type.
*
......@@ -231,7 +230,7 @@ struct drm_map {
/* Private data */
};
/**
/*
* DRM_IOCTL_GET_CLIENT ioctl argument type.
*/
struct drm_client {
......@@ -263,7 +262,7 @@ enum drm_stat_type {
/* Add to the *END* of the list */
};
/**
/*
* DRM_IOCTL_GET_STATS ioctl argument type.
*/
struct drm_stats {
......@@ -274,7 +273,7 @@ struct drm_stats {
} data[15];
};
/**
/*
* Hardware locking flags.
*/
enum drm_lock_flags {
......@@ -289,7 +288,7 @@ enum drm_lock_flags {
_DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */
};
/**
/*
* DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type.
*
* \sa drmGetLock() and drmUnlock().
......@@ -299,7 +298,7 @@ struct drm_lock {
enum drm_lock_flags flags;
};
/**
/*
* DMA flags
*
* \warning
......@@ -328,7 +327,7 @@ enum drm_dma_flags {
_DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */
};
/**
/*
* DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type.
*
* \sa drmAddBufs().
......@@ -351,7 +350,7 @@ struct drm_buf_desc {
*/
};
/**
/*
* DRM_IOCTL_INFO_BUFS ioctl argument type.
*/
struct drm_buf_info {
......@@ -359,7 +358,7 @@ struct drm_buf_info {
struct drm_buf_desc __user *list;
};
/**
/*
* DRM_IOCTL_FREE_BUFS ioctl argument type.
*/
struct drm_buf_free {
......@@ -367,7 +366,7 @@ struct drm_buf_free {
int __user *list;
};
/**
/*
* Buffer information
*
* \sa drm_buf_map.
......@@ -379,7 +378,7 @@ struct drm_buf_pub {
void __user *address; /**< Address of buffer */
};
/**
/*
* DRM_IOCTL_MAP_BUFS ioctl argument type.
*/
struct drm_buf_map {
......@@ -392,7 +391,7 @@ struct drm_buf_map {
struct drm_buf_pub __user *list; /**< Buffer information */
};
/**
/*
* DRM_IOCTL_DMA ioctl argument type.
*
* Indices here refer to the offset into the buffer list in drm_buf_get.
......@@ -417,7 +416,7 @@ enum drm_ctx_flags {
_DRM_CONTEXT_2DONLY = 0x02
};
/**
/*
* DRM_IOCTL_ADD_CTX ioctl argument type.
*
* \sa drmCreateContext() and drmDestroyContext().
......@@ -427,7 +426,7 @@ struct drm_ctx {
enum drm_ctx_flags flags;
};
/**
/*
* DRM_IOCTL_RES_CTX ioctl argument type.
*/
struct drm_ctx_res {
......@@ -435,14 +434,14 @@ struct drm_ctx_res {
struct drm_ctx __user *contexts;
};
/**
/*
* DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type.
*/
struct drm_draw {
drm_drawable_t handle;
};
/**
/*
* DRM_IOCTL_UPDATE_DRAW ioctl argument type.
*/
typedef enum {
......@@ -456,14 +455,14 @@ struct drm_update_draw {
unsigned long long data;
};
/**
/*
* DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type.
*/
struct drm_auth {
drm_magic_t magic;
};
/**
/*
* DRM_IOCTL_IRQ_BUSID ioctl argument type.
*
* \sa drmGetInterruptFromBusID().
......@@ -505,7 +504,7 @@ struct drm_wait_vblank_reply {
long tval_usec;
};
/**
/*
* DRM_IOCTL_WAIT_VBLANK ioctl argument type.
*
* \sa drmWaitVBlank().
......@@ -518,7 +517,7 @@ union drm_wait_vblank {
#define _DRM_PRE_MODESET 1
#define _DRM_POST_MODESET 2
/**
/*
* DRM_IOCTL_MODESET_CTL ioctl argument type
*
* \sa drmModesetCtl().
......@@ -528,7 +527,7 @@ struct drm_modeset_ctl {
__u32 cmd;
};
/**
/*
* DRM_IOCTL_AGP_ENABLE ioctl argument type.
*
* \sa drmAgpEnable().
......@@ -537,7 +536,7 @@ struct drm_agp_mode {
unsigned long mode; /**< AGP mode */
};
/**
/*
* DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type.
*
* \sa drmAgpAlloc() and drmAgpFree().
......@@ -549,7 +548,7 @@ struct drm_agp_buffer {
unsigned long physical; /**< Physical used by i810 */
};
/**
/*
* DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type.
*
* \sa drmAgpBind() and drmAgpUnbind().
......@@ -559,7 +558,7 @@ struct drm_agp_binding {
unsigned long offset; /**< In bytes -- will round to page boundary */
};
/**
/*
* DRM_IOCTL_AGP_INFO ioctl argument type.
*
* \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(),
......@@ -580,7 +579,7 @@ struct drm_agp_info {
unsigned short id_device;
};
/**
/*
* DRM_IOCTL_SG_ALLOC ioctl argument type.
*/
struct drm_scatter_gather {
......@@ -588,7 +587,7 @@ struct drm_scatter_gather {
unsigned long handle; /**< Used for mapping / unmapping */
};
/**
/*
* DRM_IOCTL_SET_VERSION ioctl argument type.
*/
struct drm_set_version {
......@@ -598,14 +597,14 @@ struct drm_set_version {
int drm_dd_minor;
};
/** DRM_IOCTL_GEM_CLOSE ioctl argument type */
/* DRM_IOCTL_GEM_CLOSE ioctl argument type */
struct drm_gem_close {
/** Handle of the object to be closed. */
__u32 handle;
__u32 pad;
};
/** DRM_IOCTL_GEM_FLINK ioctl argument type */
/* DRM_IOCTL_GEM_FLINK ioctl argument type */
struct drm_gem_flink {
/** Handle for the object being named */
__u32 handle;
......@@ -614,7 +613,7 @@ struct drm_gem_flink {
__u32 name;
};
/** DRM_IOCTL_GEM_OPEN ioctl argument type */
/* DRM_IOCTL_GEM_OPEN ioctl argument type */
struct drm_gem_open {
/** Name of object being opened */
__u32 name;
......@@ -652,7 +651,7 @@ struct drm_gem_open {
#define DRM_CAP_SYNCOBJ 0x13
#define DRM_CAP_SYNCOBJ_TIMELINE 0x14
/** DRM_IOCTL_GET_CAP ioctl argument type */
/* DRM_IOCTL_GET_CAP ioctl argument type */
struct drm_get_cap {
__u64 capability;
__u64 value;
......@@ -678,7 +677,9 @@ struct drm_get_cap {
/**
* DRM_CLIENT_CAP_ATOMIC
*
* If set to 1, the DRM core will expose atomic properties to userspace
* If set to 1, the DRM core will expose atomic properties to userspace. This
* implicitly enables &DRM_CLIENT_CAP_UNIVERSAL_PLANES and
* &DRM_CLIENT_CAP_ASPECT_RATIO.
*/
#define DRM_CLIENT_CAP_ATOMIC 3
......@@ -698,7 +699,7 @@ struct drm_get_cap {
*/
#define DRM_CLIENT_CAP_WRITEBACK_CONNECTORS 5
/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
/* DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
struct drm_set_client_cap {
__u64 capability;
__u64 value;
......@@ -950,7 +951,7 @@ extern "C" {
#define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2)
/**
/*
* Device specific ioctls should only be in their respective headers
* The device specific ioctl range is from 0x40 to 0x9f.
* Generic IOCTLS restart at 0xA0.
......@@ -961,7 +962,7 @@ extern "C" {
#define DRM_COMMAND_BASE 0x40
#define DRM_COMMAND_END 0xA0
/**
/*
* Header for events written back to userspace on the drm fd. The
* type defines the type of event, the length specifies the total
* length of the event (including the header), and user_data is
......
......@@ -177,8 +177,9 @@ enum drm_i915_pmu_engine_sample {
#define I915_PMU_REQUESTED_FREQUENCY __I915_PMU_OTHER(1)
#define I915_PMU_INTERRUPTS __I915_PMU_OTHER(2)
#define I915_PMU_RC6_RESIDENCY __I915_PMU_OTHER(3)
#define I915_PMU_SOFTWARE_GT_AWAKE_TIME __I915_PMU_OTHER(4)
#define I915_PMU_LAST I915_PMU_RC6_RESIDENCY
#define I915_PMU_LAST /* Deprecated - do not use */ I915_PMU_RC6_RESIDENCY
/* Each region is a minimum of 16k, and there are at most 255 of them.
*/
......
......@@ -216,6 +216,20 @@ struct kvm_hyperv_exit {
} u;
};
struct kvm_xen_exit {
#define KVM_EXIT_XEN_HCALL 1
__u32 type;
union {
struct {
__u32 longmode;
__u32 cpl;
__u64 input;
__u64 result;
__u64 params[6];
} hcall;
} u;
};
#define KVM_S390_GET_SKEYS_NONE 1
#define KVM_S390_SKEYS_MAX 1048576
......@@ -252,6 +266,8 @@ struct kvm_hyperv_exit {
#define KVM_EXIT_X86_WRMSR 30
#define KVM_EXIT_DIRTY_RING_FULL 31
#define KVM_EXIT_AP_RESET_HOLD 32
#define KVM_EXIT_X86_BUS_LOCK 33
#define KVM_EXIT_XEN 34
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
......@@ -428,6 +444,8 @@ struct kvm_run {
__u32 index; /* kernel -> user */
__u64 data; /* kernel <-> user */
} msr;
/* KVM_EXIT_XEN */
struct kvm_xen_exit xen;
/* Fix the size of the union. */
char padding[256];
};
......@@ -1058,6 +1076,7 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_ENFORCE_PV_FEATURE_CPUID 190
#define KVM_CAP_SYS_HYPERV_CPUID 191
#define KVM_CAP_DIRTY_LOG_RING 192
#define KVM_CAP_X86_BUS_LOCK_EXIT 193
#define KVM_CAP_PPC_DAWR1 194
#ifdef KVM_CAP_IRQ_ROUTING
......@@ -1132,6 +1151,10 @@ struct kvm_x86_mce {
#endif
#ifdef KVM_CAP_XEN_HVM
#define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR (1 << 0)
#define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1)
#define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2)
struct kvm_xen_hvm_config {
__u32 flags;
__u32 msr;
......@@ -1566,6 +1589,45 @@ struct kvm_pv_cmd {
/* Available with KVM_CAP_DIRTY_LOG_RING */
#define KVM_RESET_DIRTY_RINGS _IO(KVMIO, 0xc7)
/* Per-VM Xen attributes */
#define KVM_XEN_HVM_GET_ATTR _IOWR(KVMIO, 0xc8, struct kvm_xen_hvm_attr)
#define KVM_XEN_HVM_SET_ATTR _IOW(KVMIO, 0xc9, struct kvm_xen_hvm_attr)
struct kvm_xen_hvm_attr {
__u16 type;
__u16 pad[3];
union {
__u8 long_mode;
__u8 vector;
struct {
__u64 gfn;
} shared_info;
__u64 pad[8];
} u;
};
/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */
#define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0
#define KVM_XEN_ATTR_TYPE_SHARED_INFO 0x1
#define KVM_XEN_ATTR_TYPE_UPCALL_VECTOR 0x2
/* Per-vCPU Xen attributes */
#define KVM_XEN_VCPU_GET_ATTR _IOWR(KVMIO, 0xca, struct kvm_xen_vcpu_attr)
#define KVM_XEN_VCPU_SET_ATTR _IOW(KVMIO, 0xcb, struct kvm_xen_vcpu_attr)
struct kvm_xen_vcpu_attr {
__u16 type;
__u16 pad[3];
union {
__u64 gpa;
__u64 pad[8];
} u;
};
/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */
#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO 0x0
#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO 0x1
/* Secure Encrypted Virtualization command */
enum sev_cmd_id {
/* Guest initialization commands */
......@@ -1594,6 +1656,8 @@ enum sev_cmd_id {
KVM_SEV_DBG_ENCRYPT,
/* Guest certificates commands */
KVM_SEV_CERT_EXPORT,
/* Attestation report */
KVM_SEV_GET_ATTESTATION_REPORT,
KVM_SEV_NR_MAX,
};
......@@ -1646,6 +1710,12 @@ struct kvm_sev_dbg {
__u32 len;
};
struct kvm_sev_attestation_report {
__u8 mnonce[16];
__u64 uaddr;
__u32 len;
};
#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
#define KVM_DEV_ASSIGN_MASK_INTX (1 << 2)
......@@ -1767,4 +1837,7 @@ struct kvm_dirty_gfn {
__u64 offset;
};
#define KVM_BUS_LOCK_DETECTION_OFF (1 << 0)
#define KVM_BUS_LOCK_DETECTION_EXIT (1 << 1)
#endif /* __LINUX_KVM_H */
#ifndef _UAPI_LINUX_MOUNT_H
#define _UAPI_LINUX_MOUNT_H
#include <linux/types.h>
/*
* These are the fs-independent mount-flags: up to 32 flags are supported
*
......@@ -117,5 +119,19 @@ enum fsconfig_command {
#define MOUNT_ATTR_NOATIME 0x00000010 /* - Do not update access times. */
#define MOUNT_ATTR_STRICTATIME 0x00000020 /* - Always perform atime updates */
#define MOUNT_ATTR_NODIRATIME 0x00000080 /* Do not update directory access times */
#define MOUNT_ATTR_IDMAP 0x00100000 /* Idmap mount to @userns_fd in struct mount_attr. */
/*
* mount_setattr()
*/
struct mount_attr {
__u64 attr_set;
__u64 attr_clr;
__u64 propagation;
__u64 userns_fd;
};
/* List of all mount_attr versions. */
#define MOUNT_ATTR_SIZE_VER0 32 /* sizeof first published struct */
#endif /* _UAPI_LINUX_MOUNT_H */
......@@ -35,5 +35,9 @@ struct open_how {
#define RESOLVE_IN_ROOT 0x10 /* Make all jumps to "/" and ".."
be scoped inside the dirfd
(similar to chroot(2)). */
#define RESOLVE_CACHED 0x20 /* Only complete if resolution can be
completed through cached lookup. May
return -EAGAIN if that's not
possible. */
#endif /* _UAPI_LINUX_OPENAT2_H */
......@@ -26,13 +26,10 @@
void perf_evlist__init(struct perf_evlist *evlist)
{
int i;
for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
INIT_HLIST_HEAD(&evlist->heads[i]);
INIT_LIST_HEAD(&evlist->entries);
evlist->nr_entries = 0;
fdarray__init(&evlist->pollfd, 64);
perf_evlist__reset_id_hash(evlist);
}
static void __perf_evlist__propagate_maps(struct perf_evlist *evlist,
......@@ -237,6 +234,14 @@ static void perf_evlist__id_hash(struct perf_evlist *evlist,
hlist_add_head(&sid->node, &evlist->heads[hash]);
}
void perf_evlist__reset_id_hash(struct perf_evlist *evlist)
{
int i;
for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
INIT_HLIST_HEAD(&evlist->heads[i]);
}
void perf_evlist__id_add(struct perf_evlist *evlist,
struct perf_evsel *evsel,
int cpu, int thread, u64 id)
......
......@@ -124,4 +124,6 @@ int perf_evlist__id_add_fd(struct perf_evlist *evlist,
struct perf_evsel *evsel,
int cpu, int thread, int fd);
void perf_evlist__reset_id_hash(struct perf_evlist *evlist);
#endif /* __LIBPERF_INTERNAL_EVLIST_H */
......@@ -29,7 +29,7 @@ OPTIONS
Show just the sample frequency used for each event.
-v::
--verbose=::
--verbose::
Show all fields.
-g::
......
......@@ -28,8 +28,8 @@ OPTIONS
specified: function_graph or function.
-v::
--verbose=::
Verbosity level.
--verbose::
Increase the verbosity level.
-F::
--funcs::
......
......@@ -20,5 +20,5 @@ modules).
OPTIONS
-------
-v::
--verbose=::
--verbose::
Increase verbosity level, showing details about symbol table loading, etc.
......@@ -97,8 +97,8 @@ filter out the startup phase of the program, which is often very different.
Filter out events for these pids and for 'trace' itself (comma separated list).
-v::
--verbose=::
Verbosity level.
--verbose::
Increase the verbosity level.
--no-inherit::
Child tasks do not inherit counters.
......
......@@ -607,7 +607,7 @@ arch_errno_hdr_dir := $(srctree)/tools
arch_errno_tbl := $(srctree)/tools/perf/trace/beauty/arch_errno_names.sh
$(arch_errno_name_array): $(arch_errno_tbl)
$(Q)$(SHELL) '$(arch_errno_tbl)' $(firstword $(CC)) $(arch_errno_hdr_dir) > $@
$(Q)$(SHELL) '$(arch_errno_tbl)' '$(patsubst -%,,$(CC))' $(arch_errno_hdr_dir) > $@
sync_file_range_arrays := $(beauty_outdir)/sync_file_range_arrays.c
sync_file_range_tbls := $(srctree)/tools/perf/trace/beauty/sync_file_range.sh
......@@ -1001,14 +1001,6 @@ $(INSTALL_DOC_TARGETS):
### Cleaning rules
#
# This is here, not in Makefile.config, because Makefile.config does
# not get included for the clean target:
#
config-clean:
$(call QUIET_CLEAN, config)
$(Q)$(MAKE) -C $(srctree)/tools/build/feature/ $(if $(OUTPUT),OUTPUT=$(OUTPUT)feature/,) clean >/dev/null
python-clean:
$(python-clean)
......@@ -1048,7 +1040,7 @@ endif # BUILD_BPF_SKEL
bpf-skel-clean:
$(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS)
clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean config-clean fixdep-clean python-clean bpf-skel-clean
clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean
$(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS)
$(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
$(Q)$(RM) $(OUTPUT).config-detected
......
......@@ -156,6 +156,10 @@ static int cs_etm_set_timestamp(struct auxtrace_record *itr,
return err;
}
#define ETM_SET_OPT_CTXTID (1 << 0)
#define ETM_SET_OPT_TS (1 << 1)
#define ETM_SET_OPT_MASK (ETM_SET_OPT_CTXTID | ETM_SET_OPT_TS)
static int cs_etm_set_option(struct auxtrace_record *itr,
struct evsel *evsel, u32 option)
{
......@@ -169,17 +173,17 @@ static int cs_etm_set_option(struct auxtrace_record *itr,
!cpu_map__has(online_cpus, i))
continue;
if (option & ETM_OPT_CTXTID) {
if (option & ETM_SET_OPT_CTXTID) {
err = cs_etm_set_context_id(itr, evsel, i);
if (err)
goto out;
}
if (option & ETM_OPT_TS) {
if (option & ETM_SET_OPT_TS) {
err = cs_etm_set_timestamp(itr, evsel, i);
if (err)
goto out;
}
if (option & ~(ETM_OPT_CTXTID | ETM_OPT_TS))
if (option & ~(ETM_SET_OPT_MASK))
/* Nothing else is currently supported */
goto out;
}
......@@ -406,7 +410,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
evsel__set_sample_bit(cs_etm_evsel, CPU);
err = cs_etm_set_option(itr, cs_etm_evsel,
ETM_OPT_CTXTID | ETM_OPT_TS);
ETM_SET_OPT_CTXTID | ETM_SET_OPT_TS);
if (err)
goto out;
}
......
......@@ -9,9 +9,7 @@
#
0 nospu restart_syscall sys_restart_syscall
1 nospu exit sys_exit
2 32 fork ppc_fork sys_fork
2 64 fork sys_fork
2 spu fork sys_ni_syscall
2 nospu fork sys_fork
3 common read sys_read
4 common write sys_write
5 common open sys_open compat_sys_open
......@@ -160,9 +158,7 @@
119 32 sigreturn sys_sigreturn compat_sys_sigreturn
119 64 sigreturn sys_ni_syscall
119 spu sigreturn sys_ni_syscall
120 32 clone ppc_clone sys_clone
120 64 clone sys_clone
120 spu clone sys_ni_syscall
120 nospu clone sys_clone
121 common setdomainname sys_setdomainname
122 common uname sys_newuname
123 common modify_ldt sys_ni_syscall
......@@ -244,9 +240,7 @@
186 spu sendfile sys_sendfile64
187 common getpmsg sys_ni_syscall
188 common putpmsg sys_ni_syscall
189 32 vfork ppc_vfork sys_vfork
189 64 vfork sys_vfork
189 spu vfork sys_ni_syscall
189 nospu vfork sys_vfork
190 common ugetrlimit sys_getrlimit compat_sys_getrlimit
191 common readahead sys_readahead compat_sys_readahead
192 32 mmap2 sys_mmap2 compat_sys_mmap2
......@@ -322,9 +316,7 @@
248 32 clock_nanosleep sys_clock_nanosleep_time32
248 64 clock_nanosleep sys_clock_nanosleep
248 spu clock_nanosleep sys_clock_nanosleep
249 32 swapcontext ppc_swapcontext compat_sys_swapcontext
249 64 swapcontext sys_swapcontext
249 spu swapcontext sys_ni_syscall
249 nospu swapcontext sys_swapcontext compat_sys_swapcontext
250 common tgkill sys_tgkill
251 32 utimes sys_utimes_time32
251 64 utimes sys_utimes
......@@ -522,12 +514,11 @@
432 common fsmount sys_fsmount
433 common fspick sys_fspick
434 common pidfd_open sys_pidfd_open
435 32 clone3 ppc_clone3 sys_clone3
435 64 clone3 sys_clone3
435 spu clone3 sys_ni_syscall
435 nospu clone3 sys_clone3
436 common close_range sys_close_range
437 common openat2 sys_openat2
438 common pidfd_getfd sys_pidfd_getfd
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
......@@ -444,3 +444,4 @@
439 common faccessat2 sys_faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr sys_mount_setattr
......@@ -10,10 +10,11 @@ PERF_HAVE_JITDUMP := 1
# Syscall table generation
#
out := $(OUTPUT)arch/x86/include/generated/asm
header := $(out)/syscalls_64.c
sys := $(srctree)/tools/perf/arch/x86/entry/syscalls
systbl := $(sys)/syscalltbl.sh
generated := $(OUTPUT)arch/x86/include/generated
out := $(generated)/asm
header := $(out)/syscalls_64.c
sys := $(srctree)/tools/perf/arch/x86/entry/syscalls
systbl := $(sys)/syscalltbl.sh
# Create output directory if not already present
_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
......@@ -22,6 +23,6 @@ $(header): $(sys)/syscall_64.tbl $(systbl)
$(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@
clean::
$(call QUIET_CLEAN, x86) $(RM) $(header)
$(call QUIET_CLEAN, x86) $(RM) -r $(header) $(generated)
archheaders: $(header)
......@@ -363,6 +363,7 @@
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
#
# Due to a historical design error, certain syscalls are numbered differently
......
......@@ -10,6 +10,7 @@ int test__rdpmc(struct test *test __maybe_unused, int subtest);
int test__insn_x86(struct test *test __maybe_unused, int subtest);
int test__intel_pt_pkt_decoder(struct test *test, int subtest);
int test__bp_modify(struct test *test, int subtest);
int test__x86_sample_parsing(struct test *test, int subtest);
#ifdef HAVE_DWARF_UNWIND_SUPPORT
struct thread;
......
......@@ -3,5 +3,6 @@ perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
perf-y += arch-tests.o
perf-y += rdpmc.o
perf-y += sample-parsing.o
perf-$(CONFIG_AUXTRACE) += insn-x86.o intel-pt-pkt-decoder-test.o
perf-$(CONFIG_X86_64) += bp-modify.o
......@@ -30,6 +30,10 @@ struct test arch_tests[] = {
.func = test__bp_modify,
},
#endif
{
.desc = "x86 Sample parsing",
.func = test__x86_sample_parsing,
},
{
.func = NULL,
},
......
// SPDX-License-Identifier: GPL-2.0
#include <linux/types.h>
#include "../../../../arch/x86/include/asm/insn.h"
#include <string.h>
#include "debug.h"
#include "tests/tests.h"
#include "arch-tests.h"
#include "../../../../arch/x86/include/asm/insn.h"
#include "intel-pt-decoder/intel-pt-insn-decoder.h"
......
// SPDX-License-Identifier: GPL-2.0-only
#include <stdbool.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include "event.h"
#include "evsel.h"
#include "debug.h"
#include "util/synthetic-events.h"
#include "tests/tests.h"
#include "arch-tests.h"
#define COMP(m) do { \
if (s1->m != s2->m) { \
pr_debug("Samples differ at '"#m"'\n"); \
return false; \
} \
} while (0)
static bool samples_same(const struct perf_sample *s1,
const struct perf_sample *s2,
u64 type)
{
if (type & PERF_SAMPLE_WEIGHT_STRUCT)
COMP(ins_lat);
return true;
}
static int do_test(u64 sample_type)
{
struct evsel evsel = {
.needs_swap = false,
.core = {
. attr = {
.sample_type = sample_type,
.read_format = 0,
},
},
};
union perf_event *event;
struct perf_sample sample = {
.weight = 101,
.ins_lat = 102,
};
struct perf_sample sample_out;
size_t i, sz, bufsz;
int err, ret = -1;
sz = perf_event__sample_event_size(&sample, sample_type, 0);
bufsz = sz + 4096; /* Add a bit for overrun checking */
event = malloc(bufsz);
if (!event) {
pr_debug("malloc failed\n");
return -1;
}
memset(event, 0xff, bufsz);
event->header.type = PERF_RECORD_SAMPLE;
event->header.misc = 0;
event->header.size = sz;
err = perf_event__synthesize_sample(event, sample_type, 0, &sample);
if (err) {
pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
"perf_event__synthesize_sample", sample_type, err);
goto out_free;
}
/* The data does not contain 0xff so we use that to check the size */
for (i = bufsz; i > 0; i--) {
if (*(i - 1 + (u8 *)event) != 0xff)
break;
}
if (i != sz) {
pr_debug("Event size mismatch: actual %zu vs expected %zu\n",
i, sz);
goto out_free;
}
evsel.sample_size = __evsel__sample_size(sample_type);
err = evsel__parse_sample(&evsel, event, &sample_out);
if (err) {
pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
"evsel__parse_sample", sample_type, err);
goto out_free;
}
if (!samples_same(&sample, &sample_out, sample_type)) {
pr_debug("parsing failed for sample_type %#"PRIx64"\n",
sample_type);
goto out_free;
}
ret = 0;
out_free:
free(event);
return ret;
}
/**
* test__x86_sample_parsing - test X86 specific sample parsing
*
* This function implements a test that synthesizes a sample event, parses it
* and then checks that the parsed sample matches the original sample. If the
* test passes %0 is returned, otherwise %-1 is returned.
*
* For now, the PERF_SAMPLE_WEIGHT_STRUCT is the only X86 specific sample type.
* The test only checks the PERF_SAMPLE_WEIGHT_STRUCT type.
*/
int test__x86_sample_parsing(struct test *test __maybe_unused, int subtest __maybe_unused)
{
return do_test(PERF_SAMPLE_WEIGHT_STRUCT);
}
// SPDX-License-Identifier: GPL-2.0
#include "../../../../arch/x86/include/asm/insn.h"
#include "archinsn.h"
#include "event.h"
#include "machine.h"
#include "thread.h"
#include "symbol.h"
#include "../../../../arch/x86/include/asm/insn.h"
void arch_fetch_insn(struct perf_sample *sample,
struct thread *thread,
......
......@@ -344,18 +344,22 @@ static void mempol_restore(void)
static void bind_to_memnode(int node)
{
unsigned long nodemask;
struct bitmask *node_mask;
int ret;
if (node == NUMA_NO_NODE)
return;
BUG_ON(g->p.nr_nodes > (int)sizeof(nodemask)*8);
nodemask = 1L << node;
node_mask = numa_allocate_nodemask();
BUG_ON(!node_mask);
ret = set_mempolicy(MPOL_BIND, &nodemask, sizeof(nodemask)*8);
dprintf("binding to node %d, mask: %016lx => %d\n", node, nodemask, ret);
numa_bitmask_clearall(node_mask);
numa_bitmask_setbit(node_mask, node);
ret = set_mempolicy(MPOL_BIND, node_mask->maskp, node_mask->size + 1);
dprintf("binding to node %d, mask: %016lx => %d\n", node, *node_mask->maskp, ret);
numa_bitmask_free(node_mask);
BUG_ON(ret);
}
......@@ -876,8 +880,6 @@ static void update_curr_cpu(int task_nr, unsigned long bytes_worked)
prctl(0, bytes_worked);
}
#define MAX_NR_NODES 64
/*
* Count the number of nodes a process's threads
* are spread out on.
......@@ -888,10 +890,15 @@ static void update_curr_cpu(int task_nr, unsigned long bytes_worked)
*/
static int count_process_nodes(int process_nr)
{
char node_present[MAX_NR_NODES] = { 0, };
char *node_present;
int nodes;
int n, t;
node_present = (char *)malloc(g->p.nr_nodes * sizeof(char));
BUG_ON(!node_present);
for (nodes = 0; nodes < g->p.nr_nodes; nodes++)
node_present[nodes] = 0;
for (t = 0; t < g->p.nr_threads; t++) {
struct thread_data *td;
int task_nr;
......@@ -901,17 +908,20 @@ static int count_process_nodes(int process_nr)
td = g->threads + task_nr;
node = numa_node_of_cpu(td->curr_cpu);
if (node < 0) /* curr_cpu was likely still -1 */
if (node < 0) /* curr_cpu was likely still -1 */ {
free(node_present);
return 0;
}
node_present[node] = 1;
}
nodes = 0;
for (n = 0; n < MAX_NR_NODES; n++)
for (n = 0; n < g->p.nr_nodes; n++)
nodes += node_present[n];
free(node_present);
return nodes;
}
......@@ -980,7 +990,7 @@ static void calc_convergence(double runtime_ns_max, double *convergence)
{
unsigned int loops_done_min, loops_done_max;
int process_groups;
int nodes[MAX_NR_NODES];
int *nodes;
int distance;
int nr_min;
int nr_max;
......@@ -994,6 +1004,8 @@ static void calc_convergence(double runtime_ns_max, double *convergence)
if (!g->p.show_convergence && !g->p.measure_convergence)
return;
nodes = (int *)malloc(g->p.nr_nodes * sizeof(int));
BUG_ON(!nodes);
for (node = 0; node < g->p.nr_nodes; node++)
nodes[node] = 0;
......@@ -1035,8 +1047,10 @@ static void calc_convergence(double runtime_ns_max, double *convergence)
BUG_ON(sum > g->p.nr_tasks);
if (0 && (sum < g->p.nr_tasks))
if (0 && (sum < g->p.nr_tasks)) {
free(nodes);
return;
}
/*
* Count the number of distinct process groups present
......@@ -1088,6 +1102,8 @@ static void calc_convergence(double runtime_ns_max, double *convergence)
}
tprintf("\n");
}
free(nodes);
}
static void show_summary(double runtime_ns_max, int l, double *convergence)
......@@ -1413,7 +1429,7 @@ static int init(void)
g->p.nr_nodes = numa_max_node() + 1;
/* char array in count_process_nodes(): */
BUG_ON(g->p.nr_nodes > MAX_NR_NODES || g->p.nr_nodes < 0);
BUG_ON(g->p.nr_nodes < 0);
if (g->p.show_quiet && !g->p.show_details)
g->p.show_details = -1;
......
......@@ -309,11 +309,11 @@ int bench_sched_messaging(int argc, const char **argv)
num_groups, num_groups * 2 * num_fds,
thread_mode ? "threads" : "processes");
printf(" %14s: %lu.%03lu [sec]\n", "Total time",
diff.tv_sec,
(unsigned long) diff.tv_sec,
(unsigned long) (diff.tv_usec / USEC_PER_MSEC));
break;
case BENCH_FORMAT_SIMPLE:
printf("%lu.%03lu\n", diff.tv_sec,
printf("%lu.%03lu\n", (unsigned long) diff.tv_sec,
(unsigned long) (diff.tv_usec / USEC_PER_MSEC));
break;
default:
......
......@@ -156,7 +156,7 @@ int bench_sched_pipe(int argc, const char **argv)
result_usec += diff.tv_usec;
printf(" %14s: %lu.%03lu [sec]\n\n", "Total time",
diff.tv_sec,
(unsigned long) diff.tv_sec,
(unsigned long) (diff.tv_usec / USEC_PER_MSEC));
printf(" %14lf usecs/op\n",
......@@ -168,7 +168,7 @@ int bench_sched_pipe(int argc, const char **argv)
case BENCH_FORMAT_SIMPLE:
printf("%lu.%03lu\n",
diff.tv_sec,
(unsigned long) diff.tv_sec,
(unsigned long) (diff.tv_usec / USEC_PER_MSEC));
break;
......
......@@ -54,7 +54,7 @@ int bench_syscall_basic(int argc, const char **argv)
result_usec += diff.tv_usec;
printf(" %14s: %lu.%03lu [sec]\n\n", "Total time",
diff.tv_sec,
(unsigned long) diff.tv_sec,
(unsigned long) (diff.tv_usec/1000));
printf(" %14lf usecs/op\n",
......@@ -66,7 +66,7 @@ int bench_syscall_basic(int argc, const char **argv)
case BENCH_FORMAT_SIMPLE:
printf("%lu.%03lu\n",
diff.tv_sec,
(unsigned long) diff.tv_sec,
(unsigned long) (diff.tv_usec / 1000));
break;
......
......@@ -161,7 +161,7 @@ static int session_config(struct daemon *daemon, const char *var, const char *va
struct daemon_session *session;
char name[100];
if (get_session_name(var, name, sizeof(name)))
if (get_session_name(var, name, sizeof(name) - 1))
return -EINVAL;
var = strchr(var, '.');
......@@ -373,12 +373,12 @@ static int daemon_session__run(struct daemon_session *session,
dup2(fd, 2);
close(fd);
if (mkfifo(SESSION_CONTROL, O_RDWR) && errno != EEXIST) {
if (mkfifo(SESSION_CONTROL, 0600) && errno != EEXIST) {
perror("failed: create control fifo");
return -1;
}
if (mkfifo(SESSION_ACK, O_RDWR) && errno != EEXIST) {
if (mkfifo(SESSION_ACK, 0600) && errno != EEXIST) {
perror("failed: create ack fifo");
return -1;
}
......
......@@ -1236,7 +1236,8 @@ static int __cmd_diff(void)
out_delete:
data__for_each_file(i, d) {
perf_session__delete(d->session);
if (!IS_ERR(d->session))
perf_session__delete(d->session);
data__free(d);
}
......
......@@ -3964,9 +3964,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
evlist__config(evlist, &trace->opts, &callchain_param);
signal(SIGCHLD, sig_handler);
signal(SIGINT, sig_handler);
if (forks) {
err = evlist__prepare_workload(evlist, &trace->opts.target, argv, false, NULL);
if (err < 0) {
......@@ -4827,6 +4824,8 @@ int cmd_trace(int argc, const char **argv)
signal(SIGSEGV, sighandler_dump_stack);
signal(SIGFPE, sighandler_dump_stack);
signal(SIGCHLD, sig_handler);
signal(SIGINT, sig_handler);
trace.evlist = evlist__new();
trace.sctbl = syscalltbl__new();
......
......@@ -20,9 +20,8 @@ else
fi
BUILDIDS=$(mktemp /tmp/perf-archive-buildids.XXXXXX)
NOBUILDID=0000000000000000000000000000000000000000
perf buildid-list -i $PERF_DATA --with-hits | grep -v "^$NOBUILDID " > $BUILDIDS
perf buildid-list -i $PERF_DATA --with-hits | grep -v "^ " > $BUILDIDS
if [ ! -s $BUILDIDS ] ; then
echo "perf archive: no build-ids found"
rm $BUILDIDS || true
......
......@@ -182,14 +182,20 @@ int test__attr(struct test *test __maybe_unused, int subtest __maybe_unused)
struct stat st;
char path_perf[PATH_MAX];
char path_dir[PATH_MAX];
char *exec_path;
/* First try development tree tests. */
if (!lstat("./tests", &st))
return run_dir("./tests", "./perf");
exec_path = get_argv_exec_path();
if (exec_path == NULL)
return -1;
/* Then installed path. */
snprintf(path_dir, PATH_MAX, "%s/tests", get_argv_exec_path());
snprintf(path_dir, PATH_MAX, "%s/tests", exec_path);
snprintf(path_perf, PATH_MAX, "%s/perf", BINDIR);
free(exec_path);
if (!lstat(path_dir, &st) &&
!lstat(path_perf, &st))
......
......@@ -706,13 +706,9 @@ static int do_test_code_reading(bool try_kcore)
out_put:
thread__put(thread);
out_err:
if (evlist) {
evlist__delete(evlist);
} else {
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
}
evlist__delete(evlist);
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
machine__delete_threads(machine);
machine__delete(machine);
......
......@@ -106,6 +106,8 @@ static int cpu_map_print(const char *str)
return -1;
cpu_map__snprint(map, buf, sizeof(buf));
perf_cpu_map__put(map);
return !strcmp(buf, str);
}
......
......@@ -154,10 +154,9 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un
if (evlist) {
evlist__disable(evlist);
evlist__delete(evlist);
} else {
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
}
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
return err;
}
......@@ -158,8 +158,6 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse
out_delete_evlist:
evlist__delete(evlist);
cpus = NULL;
threads = NULL;
out_free_cpus:
perf_cpu_map__put(cpus);
out_free_threads:
......
......@@ -167,6 +167,8 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe
out_err:
evlist__delete(evlist);
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
return err;
}
......
......@@ -129,9 +129,6 @@ static bool samples_same(const struct perf_sample *s1,
if (type & PERF_SAMPLE_WEIGHT)
COMP(weight);
if (type & PERF_SAMPLE_WEIGHT_STRUCT)
COMP(ins_lat);
if (type & PERF_SAMPLE_DATA_SRC)
COMP(data_src);
......@@ -245,7 +242,6 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
.cgroup = 114,
.data_page_size = 115,
.code_page_size = 116,
.ins_lat = 117,
.aux_sample = {
.size = sizeof(aux_data),
.data = (void *)aux_data,
......
......@@ -140,10 +140,10 @@ test_list()
base=BASE
[session-size]
run = -e cpu-clock
run = -e cpu-clock -m 1 sleep 10
[session-time]
run = -e task-clock
run = -e task-clock -m 1 sleep 10
EOF
sed -i -e "s|BASE|${base}|" ${config}
......@@ -159,14 +159,14 @@ EOF
# check 1st session
# pid:size:-e cpu-clock:base/size:base/size/output:base/size/control:base/size/ack:0
local line=`perf daemon --config ${config} -x: | head -2 | tail -1`
check_line_other "${line}" size "-e cpu-clock" ${base}/session-size \
check_line_other "${line}" size "-e cpu-clock -m 1 sleep 10" ${base}/session-size \
${base}/session-size/output ${base}/session-size/control \
${base}/session-size/ack "0"
# check 2nd session
# pid:time:-e task-clock:base/time:base/time/output:base/time/control:base/time/ack:0
local line=`perf daemon --config ${config} -x: | head -3 | tail -1`
check_line_other "${line}" time "-e task-clock" ${base}/session-time \
check_line_other "${line}" time "-e task-clock -m 1 sleep 10" ${base}/session-time \
${base}/session-time/output ${base}/session-time/control \
${base}/session-time/ack "0"
......@@ -190,10 +190,10 @@ test_reconfig()
base=BASE
[session-size]
run = -e cpu-clock
run = -e cpu-clock -m 1 sleep 10
[session-time]
run = -e task-clock
run = -e task-clock -m 1 sleep 10
EOF
sed -i -e "s|BASE|${base}|" ${config}
......@@ -204,7 +204,7 @@ EOF
# check 2nd session
# pid:time:-e task-clock:base/time:base/time/output:base/time/control:base/time/ack:0
local line=`perf daemon --config ${config} -x: | head -3 | tail -1`
check_line_other "${line}" time "-e task-clock" ${base}/session-time \
check_line_other "${line}" time "-e task-clock -m 1 sleep 10" ${base}/session-time \
${base}/session-time/output ${base}/session-time/control ${base}/session-time/ack "0"
local pid=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $1 }'`
......@@ -215,10 +215,10 @@ EOF
base=BASE
[session-size]
run = -e cpu-clock
run = -e cpu-clock -m 1 sleep 10
[session-time]
run = -e cpu-clock
run = -e cpu-clock -m 1 sleep 10
EOF
# TEST 1 - change config
......@@ -238,7 +238,7 @@ EOF
# check reconfigured 2nd session
# pid:time:-e task-clock:base/time:base/time/output:base/time/control:base/time/ack:0
local line=`perf daemon --config ${config} -x: | head -3 | tail -1`
check_line_other "${line}" time "-e cpu-clock" ${base}/session-time \
check_line_other "${line}" time "-e cpu-clock -m 1 sleep 10" ${base}/session-time \
${base}/session-time/output ${base}/session-time/control ${base}/session-time/ack "0"
# TEST 2 - empty config
......@@ -309,10 +309,10 @@ test_stop()
base=BASE
[session-size]
run = -e cpu-clock
run = -e cpu-clock -m 1 sleep 10
[session-time]
run = -e task-clock
run = -e task-clock -m 1 sleep 10
EOF
sed -i -e "s|BASE|${base}|" ${config}
......@@ -361,7 +361,7 @@ test_signal()
base=BASE
[session-test]
run = -e cpu-clock --switch-output
run = -e cpu-clock --switch-output -m 1 sleep 10
EOF
sed -i -e "s|BASE|${base}|" ${config}
......@@ -400,10 +400,10 @@ test_ping()
base=BASE
[session-size]
run = -e cpu-clock
run = -e cpu-clock -m 1 sleep 10
[session-time]
run = -e task-clock
run = -e task-clock -m 1 sleep 10
EOF
sed -i -e "s|BASE|${base}|" ${config}
......@@ -439,7 +439,7 @@ test_lock()
base=BASE
[session-size]
run = -e cpu-clock
run = -e cpu-clock -m 1 sleep 10
EOF
sed -i -e "s|BASE|${base}|" ${config}
......
......@@ -42,8 +42,8 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
.disabled = 1,
.freq = 1,
};
struct perf_cpu_map *cpus;
struct perf_thread_map *threads;
struct perf_cpu_map *cpus = NULL;
struct perf_thread_map *threads = NULL;
struct mmap *md;
attr.sample_freq = 500;
......@@ -66,14 +66,11 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
if (!cpus || !threads) {
err = -ENOMEM;
pr_debug("Not enough memory to create thread/cpu maps\n");
goto out_free_maps;
goto out_delete_evlist;
}
perf_evlist__set_maps(&evlist->core, cpus, threads);
cpus = NULL;
threads = NULL;
if (evlist__open(evlist)) {
const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate";
......@@ -129,10 +126,9 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
err = -1;
}
out_free_maps:
out_delete_evlist:
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
out_delete_evlist:
evlist__delete(evlist);
return err;
}
......
......@@ -574,10 +574,9 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_
if (evlist) {
evlist__disable(evlist);
evlist__delete(evlist);
} else {
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
}
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
return err;
......
......@@ -75,14 +75,11 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused
if (!cpus || !threads) {
err = -ENOMEM;
pr_debug("Not enough memory to create thread/cpu maps\n");
goto out_free_maps;
goto out_delete_evlist;
}
perf_evlist__set_maps(&evlist->core, cpus, threads);
cpus = NULL;
threads = NULL;
err = evlist__prepare_workload(evlist, &target, argv, false, workload_exec_failed_signal);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
......@@ -137,7 +134,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused
if (retry_count++ > 1000) {
pr_debug("Failed after retrying 1000 times\n");
err = -1;
goto out_free_maps;
goto out_delete_evlist;
}
goto retry;
......@@ -148,10 +145,9 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused
err = -1;
}
out_free_maps:
out_delete_evlist:
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
out_delete_evlist:
evlist__delete(evlist);
return err;
}
......@@ -102,6 +102,7 @@ int test__thread_map_synthesize(struct test *test __maybe_unused, int subtest __
TEST_ASSERT_VAL("failed to synthesize map",
!perf_event__synthesize_thread_map2(NULL, threads, process_event, NULL));
perf_thread_map__put(threads);
return 0;
}
......@@ -109,12 +110,12 @@ int test__thread_map_remove(struct test *test __maybe_unused, int subtest __mayb
{
struct perf_thread_map *threads;
char *str;
int i;
TEST_ASSERT_VAL("failed to allocate map string",
asprintf(&str, "%d,%d", getpid(), getppid()) >= 0);
threads = thread_map__new_str(str, NULL, 0, false);
free(str);
TEST_ASSERT_VAL("failed to allocate thread_map",
threads);
......@@ -141,9 +142,6 @@ int test__thread_map_remove(struct test *test __maybe_unused, int subtest __mayb
TEST_ASSERT_VAL("failed to not remove thread",
thread_map__remove(threads, 0));
for (i = 0; i < threads->nr; i++)
zfree(&threads->map[i].comm);
free(threads);
perf_thread_map__put(threads);
return 0;
}
......@@ -1306,6 +1306,7 @@ void evlist__close(struct evlist *evlist)
perf_evsel__free_fd(&evsel->core);
perf_evsel__free_id(&evsel->core);
}
perf_evlist__reset_id_hash(&evlist->core);
}
static int evlist__create_syswide_maps(struct evlist *evlist)
......
......@@ -46,6 +46,7 @@
#include "string2.h"
#include "memswap.h"
#include "util.h"
#include "hashmap.h"
#include "../perf-sys.h"
#include "util/parse-branch-options.h"
#include <internal/xyarray.h>
......@@ -1390,7 +1391,9 @@ void evsel__exit(struct evsel *evsel)
zfree(&evsel->group_name);
zfree(&evsel->name);
zfree(&evsel->pmu_name);
zfree(&evsel->per_pkg_mask);
evsel__zero_per_pkg(evsel);
hashmap__free(evsel->per_pkg_mask);
evsel->per_pkg_mask = NULL;
zfree(&evsel->metric_events);
perf_evsel__object.fini(evsel);
}
......@@ -2781,3 +2784,16 @@ int evsel__store_ids(struct evsel *evsel, struct evlist *evlist)
return store_evsel_ids(evsel, evlist);
}
void evsel__zero_per_pkg(struct evsel *evsel)
{
struct hashmap_entry *cur;
size_t bkt;
if (evsel->per_pkg_mask) {
hashmap__for_each_entry(evsel->per_pkg_mask, cur, bkt)
free((char *)cur->key);
hashmap__clear(evsel->per_pkg_mask);
}
}
......@@ -19,6 +19,7 @@ struct perf_stat_evsel;
union perf_event;
struct bpf_counter_ops;
struct target;
struct hashmap;
typedef int (evsel__sb_cb_t)(union perf_event *event, void *data);
......@@ -112,7 +113,7 @@ struct evsel {
bool merged_stat;
bool reset_group;
bool errored;
unsigned long *per_pkg_mask;
struct hashmap *per_pkg_mask;
struct evsel *leader;
struct list_head config_terms;
int err;
......@@ -433,4 +434,5 @@ struct perf_env *evsel__env(struct evsel *evsel);
int evsel__store_ids(struct evsel *evsel, struct evlist *evlist);
void evsel__zero_per_pkg(struct evsel *evsel);
#endif /* __PERF_EVSEL_H */
......@@ -1618,8 +1618,8 @@ static void print_clock_data(struct feat_fd *ff, FILE *fp)
fprintf(fp, "# clockid: %s (%u)\n", clockid_name(clockid), clockid);
fprintf(fp, "# reference time: %s = %ld.%06d (TOD) = %ld.%09ld (%s)\n",
tstr, tod_ns.tv_sec, (int) tod_ns.tv_usec,
clockid_ns.tv_sec, clockid_ns.tv_nsec,
tstr, (long) tod_ns.tv_sec, (int) tod_ns.tv_usec,
(long) clockid_ns.tv_sec, clockid_ns.tv_nsec,
clockid_name(clockid));
}
......
......@@ -77,8 +77,7 @@ static inline bool replace_android_lib(const char *filename, char *newfilename)
if (strstarts(filename, "/system/lib/")) {
char *ndk, *app;
const char *arch;
size_t ndk_length;
size_t app_length;
int ndk_length, app_length;
ndk = getenv("NDK_ROOT");
app = getenv("APP_PLATFORM");
......@@ -106,8 +105,8 @@ static inline bool replace_android_lib(const char *filename, char *newfilename)
if (new_length > PATH_MAX)
return false;
snprintf(newfilename, new_length,
"%s/platforms/%s/arch-%s/usr/lib/%s",
ndk, app, arch, libname);
"%.*s/platforms/%.*s/arch-%s/usr/lib/%s",
ndk_length, ndk, app_length, app, arch, libname);
return true;
}
......
......@@ -89,6 +89,7 @@ static void inc_group_count(struct list_head *list,
%type <str> PE_EVENT_NAME
%type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE
%type <str> PE_DRV_CFG_TERM
%type <str> event_pmu_name
%destructor { free ($$); } <str>
%type <term> event_term
%destructor { parse_events_term__delete ($$); } <term>
......@@ -272,8 +273,11 @@ event_def: event_pmu |
event_legacy_raw sep_dc |
event_bpf_file
event_pmu_name:
PE_NAME | PE_PMU_EVENT_PRE
event_pmu:
PE_NAME opt_pmu_config
event_pmu_name opt_pmu_config
{
struct parse_events_state *parse_state = _parse_state;
struct parse_events_error *error = parse_state->error;
......
......@@ -36,3 +36,4 @@ util/symbol_fprintf.c
util/units.c
util/affinity.c
util/rwsem.c
util/hashmap.c
......@@ -3140,7 +3140,7 @@ int output_field_add(struct perf_hpp_list *list, char *tok)
if (strncasecmp(tok, sd->name, strlen(tok)))
continue;
if (sort__mode != SORT_MODE__MEMORY)
if (sort__mode != SORT_MODE__BRANCH)
return -EINVAL;
return __sort_dimension__add_output(list, sd);
......@@ -3152,7 +3152,7 @@ int output_field_add(struct perf_hpp_list *list, char *tok)
if (strncasecmp(tok, sd->name, strlen(tok)))
continue;
if (sort__mode != SORT_MODE__BRANCH)
if (sort__mode != SORT_MODE__MEMORY)
return -EINVAL;
return __sort_dimension__add_output(list, sd);
......
......@@ -983,7 +983,7 @@ static void print_interval(struct perf_stat_config *config,
if (config->interval_clear)
puts(CONSOLE_CLEAR);
sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, config->csv_sep);
sprintf(prefix, "%6lu.%09lu%s", (unsigned long) ts->tv_sec, ts->tv_nsec, config->csv_sep);
if ((num_print_interval == 0 && !config->csv_output) || config->interval_clear) {
switch (config->aggr_mode) {
......
......@@ -13,6 +13,7 @@
#include "evlist.h"
#include "evsel.h"
#include "thread_map.h"
#include "hashmap.h"
#include <linux/zalloc.h>
void update_stats(struct stats *stats, u64 val)
......@@ -277,18 +278,29 @@ void evlist__save_aggr_prev_raw_counts(struct evlist *evlist)
}
}
static void zero_per_pkg(struct evsel *counter)
static size_t pkg_id_hash(const void *__key, void *ctx __maybe_unused)
{
if (counter->per_pkg_mask)
memset(counter->per_pkg_mask, 0, cpu__max_cpu());
uint64_t *key = (uint64_t *) __key;
return *key & 0xffffffff;
}
static bool pkg_id_equal(const void *__key1, const void *__key2,
void *ctx __maybe_unused)
{
uint64_t *key1 = (uint64_t *) __key1;
uint64_t *key2 = (uint64_t *) __key2;
return *key1 == *key2;
}
static int check_per_pkg(struct evsel *counter,
struct perf_counts_values *vals, int cpu, bool *skip)
{
unsigned long *mask = counter->per_pkg_mask;
struct hashmap *mask = counter->per_pkg_mask;
struct perf_cpu_map *cpus = evsel__cpus(counter);
int s;
int s, d, ret = 0;
uint64_t *key;
*skip = false;
......@@ -299,7 +311,7 @@ static int check_per_pkg(struct evsel *counter,
return 0;
if (!mask) {
mask = zalloc(cpu__max_cpu());
mask = hashmap__new(pkg_id_hash, pkg_id_equal, NULL);
if (!mask)
return -ENOMEM;
......@@ -321,8 +333,25 @@ static int check_per_pkg(struct evsel *counter,
if (s < 0)
return -1;
*skip = test_and_set_bit(s, mask) == 1;
return 0;
/*
* On multi-die system, die_id > 0. On no-die system, die_id = 0.
* We use hashmap(socket, die) to check the used socket+die pair.
*/
d = cpu_map__get_die(cpus, cpu, NULL).die;
if (d < 0)
return -1;
key = malloc(sizeof(*key));
if (!key)
return -ENOMEM;
*key = (uint64_t)d << 32 | s;
if (hashmap__find(mask, (void *)key, NULL))
*skip = true;
else
ret = hashmap__add(mask, (void *)key, (void *)1);
return ret;
}
static int
......@@ -422,7 +451,7 @@ int perf_stat_process_counter(struct perf_stat_config *config,
}
if (counter->per_pkg)
zero_per_pkg(counter);
evsel__zero_per_pkg(counter);
ret = process_counter_maps(config, counter);
if (ret)
......
......@@ -361,6 +361,7 @@ static int read_saved_cmdline(struct tep_handle *pevent)
pr_debug("error reading saved cmdlines\n");
goto out;
}
buf[ret] = '\0';
parse_saved_cmdline(pevent, buf, size);
ret = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment