Commit b381e63b authored by Ingo Molnar's avatar Ingo Molnar

Merge branch 'perf/core' into perf/timer, before applying new changes

Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 4e6d7c2a ccd41c86
...@@ -648,7 +648,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) ...@@ -648,7 +648,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
* Per-cpu breakpoints are not supported by our stepping * Per-cpu breakpoints are not supported by our stepping
* mechanism. * mechanism.
*/ */
if (!bp->hw.bp_target) if (!bp->hw.target)
return -EINVAL; return -EINVAL;
/* /*
......
...@@ -527,7 +527,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) ...@@ -527,7 +527,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
* Disallow per-task kernel breakpoints since these would * Disallow per-task kernel breakpoints since these would
* complicate the stepping code. * complicate the stepping code.
*/ */
if (info->ctrl.privilege == AARCH64_BREAKPOINT_EL1 && bp->hw.bp_target) if (info->ctrl.privilege == AARCH64_BREAKPOINT_EL1 && bp->hw.target)
return -EINVAL; return -EINVAL;
return 0; return 0;
......
...@@ -124,7 +124,7 @@ static unsigned long ebb_switch_in(bool ebb, struct cpu_hw_events *cpuhw) ...@@ -124,7 +124,7 @@ static unsigned long ebb_switch_in(bool ebb, struct cpu_hw_events *cpuhw)
static inline void power_pmu_bhrb_enable(struct perf_event *event) {} static inline void power_pmu_bhrb_enable(struct perf_event *event) {}
static inline void power_pmu_bhrb_disable(struct perf_event *event) {} static inline void power_pmu_bhrb_disable(struct perf_event *event) {}
static void power_pmu_flush_branch_stack(void) {} static void power_pmu_sched_task(struct perf_event_context *ctx, bool sched_in) {}
static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {} static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {}
static void pmao_restore_workaround(bool ebb) { } static void pmao_restore_workaround(bool ebb) { }
#endif /* CONFIG_PPC32 */ #endif /* CONFIG_PPC32 */
...@@ -350,6 +350,7 @@ static void power_pmu_bhrb_enable(struct perf_event *event) ...@@ -350,6 +350,7 @@ static void power_pmu_bhrb_enable(struct perf_event *event)
cpuhw->bhrb_context = event->ctx; cpuhw->bhrb_context = event->ctx;
} }
cpuhw->bhrb_users++; cpuhw->bhrb_users++;
perf_sched_cb_inc(event->ctx->pmu);
} }
static void power_pmu_bhrb_disable(struct perf_event *event) static void power_pmu_bhrb_disable(struct perf_event *event)
...@@ -361,6 +362,7 @@ static void power_pmu_bhrb_disable(struct perf_event *event) ...@@ -361,6 +362,7 @@ static void power_pmu_bhrb_disable(struct perf_event *event)
cpuhw->bhrb_users--; cpuhw->bhrb_users--;
WARN_ON_ONCE(cpuhw->bhrb_users < 0); WARN_ON_ONCE(cpuhw->bhrb_users < 0);
perf_sched_cb_dec(event->ctx->pmu);
if (!cpuhw->disabled && !cpuhw->bhrb_users) { if (!cpuhw->disabled && !cpuhw->bhrb_users) {
/* BHRB cannot be turned off when other /* BHRB cannot be turned off when other
...@@ -375,9 +377,12 @@ static void power_pmu_bhrb_disable(struct perf_event *event) ...@@ -375,9 +377,12 @@ static void power_pmu_bhrb_disable(struct perf_event *event)
/* Called from ctxsw to prevent one process's branch entries to /* Called from ctxsw to prevent one process's branch entries to
* mingle with the other process's entries during context switch. * mingle with the other process's entries during context switch.
*/ */
static void power_pmu_flush_branch_stack(void) static void power_pmu_sched_task(struct perf_event_context *ctx, bool sched_in)
{ {
if (ppmu->bhrb_nr) if (!ppmu->bhrb_nr)
return;
if (sched_in)
power_pmu_bhrb_reset(); power_pmu_bhrb_reset();
} }
/* Calculate the to address for a branch */ /* Calculate the to address for a branch */
...@@ -1901,7 +1906,7 @@ static struct pmu power_pmu = { ...@@ -1901,7 +1906,7 @@ static struct pmu power_pmu = {
.cancel_txn = power_pmu_cancel_txn, .cancel_txn = power_pmu_cancel_txn,
.commit_txn = power_pmu_commit_txn, .commit_txn = power_pmu_commit_txn,
.event_idx = power_pmu_event_idx, .event_idx = power_pmu_event_idx,
.flush_branch_stack = power_pmu_flush_branch_stack, .sched_task = power_pmu_sched_task,
}; };
/* /*
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include <asm/disabled-features.h> #include <asm/disabled-features.h>
#endif #endif
#define NCAPINTS 11 /* N 32-bit words worth of info */ #define NCAPINTS 13 /* N 32-bit words worth of info */
#define NBUGINTS 1 /* N 32-bit bug flags */ #define NBUGINTS 1 /* N 32-bit bug flags */
/* /*
...@@ -226,6 +226,7 @@ ...@@ -226,6 +226,7 @@
#define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */ #define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */
#define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */ #define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */
#define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */ #define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */
#define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */
#define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */ #define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */
#define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */ #define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */
#define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */ #define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */
...@@ -242,6 +243,12 @@ ...@@ -242,6 +243,12 @@
#define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 */ #define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 */
#define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS */ #define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS */
/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */
#define X86_FEATURE_CQM_LLC (11*32+ 1) /* LLC QoS if 1 */
/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */
#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */
/* /*
* BUG word(s) * BUG word(s)
*/ */
......
...@@ -109,6 +109,9 @@ struct cpuinfo_x86 { ...@@ -109,6 +109,9 @@ struct cpuinfo_x86 {
/* in KB - valid for CPUS which support this call: */ /* in KB - valid for CPUS which support this call: */
int x86_cache_size; int x86_cache_size;
int x86_cache_alignment; /* In bytes */ int x86_cache_alignment; /* In bytes */
/* Cache QoS architectural values: */
int x86_cache_max_rmid; /* max index */
int x86_cache_occ_scale; /* scale to bytes */
int x86_power; int x86_power;
unsigned long loops_per_jiffy; unsigned long loops_per_jiffy;
/* cpuid returned max cores value: */ /* cpuid returned max cores value: */
......
...@@ -39,7 +39,7 @@ obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd_iommu.o ...@@ -39,7 +39,7 @@ obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd_iommu.o
endif endif
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_rapl.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_rapl.o perf_event_intel_cqm.o
obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += perf_event_intel_uncore.o \ obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += perf_event_intel_uncore.o \
perf_event_intel_uncore_snb.o \ perf_event_intel_uncore_snb.o \
......
...@@ -646,6 +646,30 @@ void get_cpu_cap(struct cpuinfo_x86 *c) ...@@ -646,6 +646,30 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
c->x86_capability[10] = eax; c->x86_capability[10] = eax;
} }
/* Additional Intel-defined flags: level 0x0000000F */
if (c->cpuid_level >= 0x0000000F) {
u32 eax, ebx, ecx, edx;
/* QoS sub-leaf, EAX=0Fh, ECX=0 */
cpuid_count(0x0000000F, 0, &eax, &ebx, &ecx, &edx);
c->x86_capability[11] = edx;
if (cpu_has(c, X86_FEATURE_CQM_LLC)) {
/* will be overridden if occupancy monitoring exists */
c->x86_cache_max_rmid = ebx;
/* QoS sub-leaf, EAX=0Fh, ECX=1 */
cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx);
c->x86_capability[12] = edx;
if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) {
c->x86_cache_max_rmid = ecx;
c->x86_cache_occ_scale = ebx;
}
} else {
c->x86_cache_max_rmid = -1;
c->x86_cache_occ_scale = -1;
}
}
/* AMD-defined flags: level 0x80000001 */ /* AMD-defined flags: level 0x80000001 */
xlvl = cpuid_eax(0x80000000); xlvl = cpuid_eax(0x80000000);
c->extended_cpuid_level = xlvl; c->extended_cpuid_level = xlvl;
...@@ -834,6 +858,20 @@ static void generic_identify(struct cpuinfo_x86 *c) ...@@ -834,6 +858,20 @@ static void generic_identify(struct cpuinfo_x86 *c)
detect_nopl(c); detect_nopl(c);
} }
static void x86_init_cache_qos(struct cpuinfo_x86 *c)
{
/*
* The heavy lifting of max_rmid and cache_occ_scale are handled
* in get_cpu_cap(). Here we just set the max_rmid for the boot_cpu
* in case CQM bits really aren't there in this CPU.
*/
if (c != &boot_cpu_data) {
boot_cpu_data.x86_cache_max_rmid =
min(boot_cpu_data.x86_cache_max_rmid,
c->x86_cache_max_rmid);
}
}
/* /*
* This does the hard work of actually picking apart the CPU stuff... * This does the hard work of actually picking apart the CPU stuff...
*/ */
...@@ -923,6 +961,7 @@ static void identify_cpu(struct cpuinfo_x86 *c) ...@@ -923,6 +961,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)
init_hypervisor(c); init_hypervisor(c);
x86_init_rdrand(c); x86_init_rdrand(c);
x86_init_cache_qos(c);
/* /*
* Clear/Set all flags overriden by options, need do it * Clear/Set all flags overriden by options, need do it
......
...@@ -399,12 +399,12 @@ int x86_pmu_hw_config(struct perf_event *event) ...@@ -399,12 +399,12 @@ int x86_pmu_hw_config(struct perf_event *event)
if (event->attr.precise_ip > precise) if (event->attr.precise_ip > precise)
return -EOPNOTSUPP; return -EOPNOTSUPP;
}
/* /*
* check that PEBS LBR correction does not conflict with * check that PEBS LBR correction does not conflict with
* whatever the user is asking with attr->branch_sample_type * whatever the user is asking with attr->branch_sample_type
*/ */
if (event->attr.precise_ip > 1 && if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format < 2) {
x86_pmu.intel_cap.pebs_format < 2) {
u64 *br_type = &event->attr.branch_sample_type; u64 *br_type = &event->attr.branch_sample_type;
if (has_branch_stack(event)) { if (has_branch_stack(event)) {
...@@ -430,7 +430,9 @@ int x86_pmu_hw_config(struct perf_event *event) ...@@ -430,7 +430,9 @@ int x86_pmu_hw_config(struct perf_event *event)
*br_type |= PERF_SAMPLE_BRANCH_KERNEL; *br_type |= PERF_SAMPLE_BRANCH_KERNEL;
} }
} }
}
if (event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK)
event->attach_state |= PERF_ATTACH_TASK_DATA;
/* /*
* Generate PMC IRQs: * Generate PMC IRQs:
...@@ -449,6 +451,12 @@ int x86_pmu_hw_config(struct perf_event *event) ...@@ -449,6 +451,12 @@ int x86_pmu_hw_config(struct perf_event *event)
if (event->attr.type == PERF_TYPE_RAW) if (event->attr.type == PERF_TYPE_RAW)
event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK; event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK;
if (event->attr.sample_period && x86_pmu.limit_period) {
if (x86_pmu.limit_period(event, event->attr.sample_period) >
event->attr.sample_period)
return -EINVAL;
}
return x86_setup_perfctr(event); return x86_setup_perfctr(event);
} }
...@@ -986,6 +994,9 @@ int x86_perf_event_set_period(struct perf_event *event) ...@@ -986,6 +994,9 @@ int x86_perf_event_set_period(struct perf_event *event)
if (left > x86_pmu.max_period) if (left > x86_pmu.max_period)
left = x86_pmu.max_period; left = x86_pmu.max_period;
if (x86_pmu.limit_period)
left = x86_pmu.limit_period(event, left);
per_cpu(pmc_prev_left[idx], smp_processor_id()) = left; per_cpu(pmc_prev_left[idx], smp_processor_id()) = left;
/* /*
...@@ -1033,7 +1044,6 @@ static int x86_pmu_add(struct perf_event *event, int flags) ...@@ -1033,7 +1044,6 @@ static int x86_pmu_add(struct perf_event *event, int flags)
hwc = &event->hw; hwc = &event->hw;
perf_pmu_disable(event->pmu);
n0 = cpuc->n_events; n0 = cpuc->n_events;
ret = n = collect_events(cpuc, event, false); ret = n = collect_events(cpuc, event, false);
if (ret < 0) if (ret < 0)
...@@ -1071,7 +1081,6 @@ static int x86_pmu_add(struct perf_event *event, int flags) ...@@ -1071,7 +1081,6 @@ static int x86_pmu_add(struct perf_event *event, int flags)
ret = 0; ret = 0;
out: out:
perf_pmu_enable(event->pmu);
return ret; return ret;
} }
...@@ -1914,10 +1923,10 @@ static const struct attribute_group *x86_pmu_attr_groups[] = { ...@@ -1914,10 +1923,10 @@ static const struct attribute_group *x86_pmu_attr_groups[] = {
NULL, NULL,
}; };
static void x86_pmu_flush_branch_stack(void) static void x86_pmu_sched_task(struct perf_event_context *ctx, bool sched_in)
{ {
if (x86_pmu.flush_branch_stack) if (x86_pmu.sched_task)
x86_pmu.flush_branch_stack(); x86_pmu.sched_task(ctx, sched_in);
} }
void perf_check_microcode(void) void perf_check_microcode(void)
...@@ -1949,7 +1958,8 @@ static struct pmu pmu = { ...@@ -1949,7 +1958,8 @@ static struct pmu pmu = {
.commit_txn = x86_pmu_commit_txn, .commit_txn = x86_pmu_commit_txn,
.event_idx = x86_pmu_event_idx, .event_idx = x86_pmu_event_idx,
.flush_branch_stack = x86_pmu_flush_branch_stack, .sched_task = x86_pmu_sched_task,
.task_ctx_size = sizeof(struct x86_perf_task_context),
}; };
void arch_perf_update_userpage(struct perf_event *event, void arch_perf_update_userpage(struct perf_event *event,
......
...@@ -451,6 +451,7 @@ struct x86_pmu { ...@@ -451,6 +451,7 @@ struct x86_pmu {
struct x86_pmu_quirk *quirks; struct x86_pmu_quirk *quirks;
int perfctr_second_write; int perfctr_second_write;
bool late_ack; bool late_ack;
unsigned (*limit_period)(struct perf_event *event, unsigned l);
/* /*
* sysfs attrs * sysfs attrs
...@@ -472,7 +473,8 @@ struct x86_pmu { ...@@ -472,7 +473,8 @@ struct x86_pmu {
void (*cpu_dead)(int cpu); void (*cpu_dead)(int cpu);
void (*check_microcode)(void); void (*check_microcode)(void);
void (*flush_branch_stack)(void); void (*sched_task)(struct perf_event_context *ctx,
bool sched_in);
/* /*
* Intel Arch Perfmon v2+ * Intel Arch Perfmon v2+
...@@ -515,6 +517,13 @@ struct x86_pmu { ...@@ -515,6 +517,13 @@ struct x86_pmu {
struct perf_guest_switch_msr *(*guest_get_msrs)(int *nr); struct perf_guest_switch_msr *(*guest_get_msrs)(int *nr);
}; };
struct x86_perf_task_context {
u64 lbr_from[MAX_LBR_ENTRIES];
u64 lbr_to[MAX_LBR_ENTRIES];
int lbr_callstack_users;
int lbr_stack_state;
};
#define x86_add_quirk(func_) \ #define x86_add_quirk(func_) \
do { \ do { \
static struct x86_pmu_quirk __quirk __initdata = { \ static struct x86_pmu_quirk __quirk __initdata = { \
...@@ -546,6 +555,12 @@ static struct perf_pmu_events_attr event_attr_##v = { \ ...@@ -546,6 +555,12 @@ static struct perf_pmu_events_attr event_attr_##v = { \
extern struct x86_pmu x86_pmu __read_mostly; extern struct x86_pmu x86_pmu __read_mostly;
static inline bool x86_pmu_has_lbr_callstack(void)
{
return x86_pmu.lbr_sel_map &&
x86_pmu.lbr_sel_map[PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT] > 0;
}
DECLARE_PER_CPU(struct cpu_hw_events, cpu_hw_events); DECLARE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
int x86_perf_event_set_period(struct perf_event *event); int x86_perf_event_set_period(struct perf_event *event);
...@@ -727,6 +742,8 @@ void intel_pmu_pebs_disable_all(void); ...@@ -727,6 +742,8 @@ void intel_pmu_pebs_disable_all(void);
void intel_ds_init(void); void intel_ds_init(void);
void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in);
void intel_pmu_lbr_reset(void); void intel_pmu_lbr_reset(void);
void intel_pmu_lbr_enable(struct perf_event *event); void intel_pmu_lbr_enable(struct perf_event *event);
...@@ -747,6 +764,8 @@ void intel_pmu_lbr_init_atom(void); ...@@ -747,6 +764,8 @@ void intel_pmu_lbr_init_atom(void);
void intel_pmu_lbr_init_snb(void); void intel_pmu_lbr_init_snb(void);
void intel_pmu_lbr_init_hsw(void);
int intel_pmu_setup_lbr_filter(struct perf_event *event); int intel_pmu_setup_lbr_filter(struct perf_event *event);
int p4_pmu_init(void); int p4_pmu_init(void);
......
...@@ -796,7 +796,7 @@ static int setup_ibs_ctl(int ibs_eilvt_off) ...@@ -796,7 +796,7 @@ static int setup_ibs_ctl(int ibs_eilvt_off)
* the IBS interrupt vector is handled by perf_ibs_cpu_notifier that * the IBS interrupt vector is handled by perf_ibs_cpu_notifier that
* is using the new offset. * is using the new offset.
*/ */
static int force_ibs_eilvt_setup(void) static void force_ibs_eilvt_setup(void)
{ {
int offset; int offset;
int ret; int ret;
...@@ -811,26 +811,24 @@ static int force_ibs_eilvt_setup(void) ...@@ -811,26 +811,24 @@ static int force_ibs_eilvt_setup(void)
if (offset == APIC_EILVT_NR_MAX) { if (offset == APIC_EILVT_NR_MAX) {
printk(KERN_DEBUG "No EILVT entry available\n"); printk(KERN_DEBUG "No EILVT entry available\n");
return -EBUSY; return;
} }
ret = setup_ibs_ctl(offset); ret = setup_ibs_ctl(offset);
if (ret) if (ret)
goto out; goto out;
if (!ibs_eilvt_valid()) { if (!ibs_eilvt_valid())
ret = -EFAULT;
goto out; goto out;
}
pr_info("IBS: LVT offset %d assigned\n", offset); pr_info("IBS: LVT offset %d assigned\n", offset);
return 0; return;
out: out:
preempt_disable(); preempt_disable();
put_eilvt(offset); put_eilvt(offset);
preempt_enable(); preempt_enable();
return ret; return;
} }
static void ibs_eilvt_setup(void) static void ibs_eilvt_setup(void)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -1132,7 +1132,6 @@ static int snbep_pci2phy_map_init(int devid) ...@@ -1132,7 +1132,6 @@ static int snbep_pci2phy_map_init(int devid)
} }
} }
if (ubox_dev)
pci_dev_put(ubox_dev); pci_dev_put(ubox_dev);
return err ? pcibios_err_to_errno(err) : 0; return err ? pcibios_err_to_errno(err) : 0;
......
...@@ -354,6 +354,7 @@ int __copy_instruction(u8 *dest, u8 *src) ...@@ -354,6 +354,7 @@ int __copy_instruction(u8 *dest, u8 *src)
{ {
struct insn insn; struct insn insn;
kprobe_opcode_t buf[MAX_INSN_SIZE]; kprobe_opcode_t buf[MAX_INSN_SIZE];
int length;
unsigned long recovered_insn = unsigned long recovered_insn =
recover_probed_instruction(buf, (unsigned long)src); recover_probed_instruction(buf, (unsigned long)src);
...@@ -361,16 +362,18 @@ int __copy_instruction(u8 *dest, u8 *src) ...@@ -361,16 +362,18 @@ int __copy_instruction(u8 *dest, u8 *src)
return 0; return 0;
kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE); kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE);
insn_get_length(&insn); insn_get_length(&insn);
length = insn.length;
/* Another subsystem puts a breakpoint, failed to recover */ /* Another subsystem puts a breakpoint, failed to recover */
if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION) if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION)
return 0; return 0;
memcpy(dest, insn.kaddr, insn.length); memcpy(dest, insn.kaddr, length);
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
if (insn_rip_relative(&insn)) { if (insn_rip_relative(&insn)) {
s64 newdisp; s64 newdisp;
u8 *disp; u8 *disp;
kernel_insn_init(&insn, dest, insn.length); kernel_insn_init(&insn, dest, length);
insn_get_displacement(&insn); insn_get_displacement(&insn);
/* /*
* The copied instruction uses the %rip-relative addressing * The copied instruction uses the %rip-relative addressing
...@@ -394,7 +397,7 @@ int __copy_instruction(u8 *dest, u8 *src) ...@@ -394,7 +397,7 @@ int __copy_instruction(u8 *dest, u8 *src)
*(s32 *) disp = (s32) newdisp; *(s32 *) disp = (s32) newdisp;
} }
#endif #endif
return insn.length; return length;
} }
static int arch_copy_kprobe(struct kprobe *p) static int arch_copy_kprobe(struct kprobe *p)
......
...@@ -53,6 +53,7 @@ struct perf_guest_info_callbacks { ...@@ -53,6 +53,7 @@ struct perf_guest_info_callbacks {
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/perf_regs.h> #include <linux/perf_regs.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/cgroup.h>
#include <asm/local.h> #include <asm/local.h>
struct perf_callchain_entry { struct perf_callchain_entry {
...@@ -118,10 +119,16 @@ struct hw_perf_event { ...@@ -118,10 +119,16 @@ struct hw_perf_event {
struct hrtimer hrtimer; struct hrtimer hrtimer;
}; };
struct { /* tracepoint */ struct { /* tracepoint */
struct task_struct *tp_target;
/* for tp_event->class */ /* for tp_event->class */
struct list_head tp_list; struct list_head tp_list;
}; };
struct { /* intel_cqm */
int cqm_state;
int cqm_rmid;
struct list_head cqm_events_entry;
struct list_head cqm_groups_entry;
struct list_head cqm_group_entry;
};
#ifdef CONFIG_HAVE_HW_BREAKPOINT #ifdef CONFIG_HAVE_HW_BREAKPOINT
struct { /* breakpoint */ struct { /* breakpoint */
/* /*
...@@ -129,12 +136,12 @@ struct hw_perf_event { ...@@ -129,12 +136,12 @@ struct hw_perf_event {
* problem hw_breakpoint has with context * problem hw_breakpoint has with context
* creation and event initalization. * creation and event initalization.
*/ */
struct task_struct *bp_target;
struct arch_hw_breakpoint info; struct arch_hw_breakpoint info;
struct list_head bp_list; struct list_head bp_list;
}; };
#endif #endif
}; };
struct task_struct *target;
int state; int state;
local64_t prev_count; local64_t prev_count;
u64 sample_period; u64 sample_period;
...@@ -262,9 +269,20 @@ struct pmu { ...@@ -262,9 +269,20 @@ struct pmu {
int (*event_idx) (struct perf_event *event); /*optional */ int (*event_idx) (struct perf_event *event); /*optional */
/* /*
* flush branch stack on context-switches (needed in cpu-wide mode) * context-switches callback
*/
void (*sched_task) (struct perf_event_context *ctx,
bool sched_in);
/*
* PMU specific data size
*/
size_t task_ctx_size;
/*
* Return the count value for a counter.
*/ */
void (*flush_branch_stack) (void); u64 (*count) (struct perf_event *event); /*optional*/
}; };
/** /**
...@@ -300,6 +318,7 @@ struct swevent_hlist { ...@@ -300,6 +318,7 @@ struct swevent_hlist {
#define PERF_ATTACH_CONTEXT 0x01 #define PERF_ATTACH_CONTEXT 0x01
#define PERF_ATTACH_GROUP 0x02 #define PERF_ATTACH_GROUP 0x02
#define PERF_ATTACH_TASK 0x04 #define PERF_ATTACH_TASK 0x04
#define PERF_ATTACH_TASK_DATA 0x08
struct perf_cgroup; struct perf_cgroup;
struct ring_buffer; struct ring_buffer;
...@@ -504,7 +523,7 @@ struct perf_event_context { ...@@ -504,7 +523,7 @@ struct perf_event_context {
u64 generation; u64 generation;
int pin_count; int pin_count;
int nr_cgroups; /* cgroup evts */ int nr_cgroups; /* cgroup evts */
int nr_branch_stack; /* branch_stack evt */ void *task_ctx_data; /* pmu specific data */
struct rcu_head rcu_head; struct rcu_head rcu_head;
struct delayed_work orphans_remove; struct delayed_work orphans_remove;
...@@ -540,6 +559,35 @@ struct perf_output_handle { ...@@ -540,6 +559,35 @@ struct perf_output_handle {
int page; int page;
}; };
#ifdef CONFIG_CGROUP_PERF
/*
* perf_cgroup_info keeps track of time_enabled for a cgroup.
* This is a per-cpu dynamically allocated data structure.
*/
struct perf_cgroup_info {
u64 time;
u64 timestamp;
};
struct perf_cgroup {
struct cgroup_subsys_state css;
struct perf_cgroup_info __percpu *info;
};
/*
* Must ensure cgroup is pinned (css_get) before calling
* this function. In other words, we cannot call this function
* if there is no cgroup event for the current CPU context.
*/
static inline struct perf_cgroup *
perf_cgroup_from_task(struct task_struct *task)
{
return container_of(task_css(task, perf_event_cgrp_id),
struct perf_cgroup, css);
}
#endif /* CONFIG_CGROUP_PERF */
#ifdef CONFIG_PERF_EVENTS #ifdef CONFIG_PERF_EVENTS
extern int perf_pmu_register(struct pmu *pmu, const char *name, int type); extern int perf_pmu_register(struct pmu *pmu, const char *name, int type);
...@@ -558,6 +606,8 @@ extern void perf_event_delayed_put(struct task_struct *task); ...@@ -558,6 +606,8 @@ extern void perf_event_delayed_put(struct task_struct *task);
extern void perf_event_print_debug(void); extern void perf_event_print_debug(void);
extern void perf_pmu_disable(struct pmu *pmu); extern void perf_pmu_disable(struct pmu *pmu);
extern void perf_pmu_enable(struct pmu *pmu); extern void perf_pmu_enable(struct pmu *pmu);
extern void perf_sched_cb_dec(struct pmu *pmu);
extern void perf_sched_cb_inc(struct pmu *pmu);
extern int perf_event_task_disable(void); extern int perf_event_task_disable(void);
extern int perf_event_task_enable(void); extern int perf_event_task_enable(void);
extern int perf_event_refresh(struct perf_event *event, int refresh); extern int perf_event_refresh(struct perf_event *event, int refresh);
...@@ -731,6 +781,11 @@ static inline void perf_event_task_sched_out(struct task_struct *prev, ...@@ -731,6 +781,11 @@ static inline void perf_event_task_sched_out(struct task_struct *prev,
__perf_event_task_sched_out(prev, next); __perf_event_task_sched_out(prev, next);
} }
static inline u64 __perf_event_count(struct perf_event *event)
{
return local64_read(&event->count) + atomic64_read(&event->child_count);
}
extern void perf_event_mmap(struct vm_area_struct *vma); extern void perf_event_mmap(struct vm_area_struct *vma);
extern struct perf_guest_info_callbacks *perf_guest_cbs; extern struct perf_guest_info_callbacks *perf_guest_cbs;
extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks); extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
...@@ -800,6 +855,11 @@ static inline bool has_branch_stack(struct perf_event *event) ...@@ -800,6 +855,11 @@ static inline bool has_branch_stack(struct perf_event *event)
return event->attr.sample_type & PERF_SAMPLE_BRANCH_STACK; return event->attr.sample_type & PERF_SAMPLE_BRANCH_STACK;
} }
static inline bool needs_branch_stack(struct perf_event *event)
{
return event->attr.branch_sample_type != 0;
}
extern int perf_output_begin(struct perf_output_handle *handle, extern int perf_output_begin(struct perf_output_handle *handle,
struct perf_event *event, unsigned int size); struct perf_event *event, unsigned int size);
extern void perf_output_end(struct perf_output_handle *handle); extern void perf_output_end(struct perf_output_handle *handle);
......
...@@ -152,21 +152,42 @@ enum perf_event_sample_format { ...@@ -152,21 +152,42 @@ enum perf_event_sample_format {
* The branch types can be combined, however BRANCH_ANY covers all types * The branch types can be combined, however BRANCH_ANY covers all types
* of branches and therefore it supersedes all the other types. * of branches and therefore it supersedes all the other types.
*/ */
enum perf_branch_sample_type_shift {
PERF_SAMPLE_BRANCH_USER_SHIFT = 0, /* user branches */
PERF_SAMPLE_BRANCH_KERNEL_SHIFT = 1, /* kernel branches */
PERF_SAMPLE_BRANCH_HV_SHIFT = 2, /* hypervisor branches */
PERF_SAMPLE_BRANCH_ANY_SHIFT = 3, /* any branch types */
PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT = 4, /* any call branch */
PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT = 5, /* any return branch */
PERF_SAMPLE_BRANCH_IND_CALL_SHIFT = 6, /* indirect calls */
PERF_SAMPLE_BRANCH_ABORT_TX_SHIFT = 7, /* transaction aborts */
PERF_SAMPLE_BRANCH_IN_TX_SHIFT = 8, /* in transaction */
PERF_SAMPLE_BRANCH_NO_TX_SHIFT = 9, /* not in transaction */
PERF_SAMPLE_BRANCH_COND_SHIFT = 10, /* conditional branches */
PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT = 11, /* call/ret stack */
PERF_SAMPLE_BRANCH_MAX_SHIFT /* non-ABI */
};
enum perf_branch_sample_type { enum perf_branch_sample_type {
PERF_SAMPLE_BRANCH_USER = 1U << 0, /* user branches */ PERF_SAMPLE_BRANCH_USER = 1U << PERF_SAMPLE_BRANCH_USER_SHIFT,
PERF_SAMPLE_BRANCH_KERNEL = 1U << 1, /* kernel branches */ PERF_SAMPLE_BRANCH_KERNEL = 1U << PERF_SAMPLE_BRANCH_KERNEL_SHIFT,
PERF_SAMPLE_BRANCH_HV = 1U << 2, /* hypervisor branches */ PERF_SAMPLE_BRANCH_HV = 1U << PERF_SAMPLE_BRANCH_HV_SHIFT,
PERF_SAMPLE_BRANCH_ANY = 1U << 3, /* any branch types */ PERF_SAMPLE_BRANCH_ANY = 1U << PERF_SAMPLE_BRANCH_ANY_SHIFT,
PERF_SAMPLE_BRANCH_ANY_CALL = 1U << 4, /* any call branch */ PERF_SAMPLE_BRANCH_ANY_CALL = 1U << PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT,
PERF_SAMPLE_BRANCH_ANY_RETURN = 1U << 5, /* any return branch */ PERF_SAMPLE_BRANCH_ANY_RETURN = 1U << PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT,
PERF_SAMPLE_BRANCH_IND_CALL = 1U << 6, /* indirect calls */ PERF_SAMPLE_BRANCH_IND_CALL = 1U << PERF_SAMPLE_BRANCH_IND_CALL_SHIFT,
PERF_SAMPLE_BRANCH_ABORT_TX = 1U << 7, /* transaction aborts */ PERF_SAMPLE_BRANCH_ABORT_TX = 1U << PERF_SAMPLE_BRANCH_ABORT_TX_SHIFT,
PERF_SAMPLE_BRANCH_IN_TX = 1U << 8, /* in transaction */ PERF_SAMPLE_BRANCH_IN_TX = 1U << PERF_SAMPLE_BRANCH_IN_TX_SHIFT,
PERF_SAMPLE_BRANCH_NO_TX = 1U << 9, /* not in transaction */ PERF_SAMPLE_BRANCH_NO_TX = 1U << PERF_SAMPLE_BRANCH_NO_TX_SHIFT,
PERF_SAMPLE_BRANCH_COND = 1U << 10, /* conditional branches */ PERF_SAMPLE_BRANCH_COND = 1U << PERF_SAMPLE_BRANCH_COND_SHIFT,
PERF_SAMPLE_BRANCH_MAX = 1U << 11, /* non-ABI */ PERF_SAMPLE_BRANCH_CALL_STACK = 1U << PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT,
PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
}; };
#define PERF_SAMPLE_BRANCH_PLM_ALL \ #define PERF_SAMPLE_BRANCH_PLM_ALL \
......
This diff is collapsed.
...@@ -116,12 +116,12 @@ static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type) ...@@ -116,12 +116,12 @@ static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type)
*/ */
static int task_bp_pinned(int cpu, struct perf_event *bp, enum bp_type_idx type) static int task_bp_pinned(int cpu, struct perf_event *bp, enum bp_type_idx type)
{ {
struct task_struct *tsk = bp->hw.bp_target; struct task_struct *tsk = bp->hw.target;
struct perf_event *iter; struct perf_event *iter;
int count = 0; int count = 0;
list_for_each_entry(iter, &bp_task_head, hw.bp_list) { list_for_each_entry(iter, &bp_task_head, hw.bp_list) {
if (iter->hw.bp_target == tsk && if (iter->hw.target == tsk &&
find_slot_idx(iter) == type && find_slot_idx(iter) == type &&
(iter->cpu < 0 || cpu == iter->cpu)) (iter->cpu < 0 || cpu == iter->cpu))
count += hw_breakpoint_weight(iter); count += hw_breakpoint_weight(iter);
...@@ -153,7 +153,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp, ...@@ -153,7 +153,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp,
int nr; int nr;
nr = info->cpu_pinned; nr = info->cpu_pinned;
if (!bp->hw.bp_target) if (!bp->hw.target)
nr += max_task_bp_pinned(cpu, type); nr += max_task_bp_pinned(cpu, type);
else else
nr += task_bp_pinned(cpu, bp, type); nr += task_bp_pinned(cpu, bp, type);
...@@ -210,7 +210,7 @@ toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type, ...@@ -210,7 +210,7 @@ toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type,
weight = -weight; weight = -weight;
/* Pinned counter cpu profiling */ /* Pinned counter cpu profiling */
if (!bp->hw.bp_target) { if (!bp->hw.target) {
get_bp_info(bp->cpu, type)->cpu_pinned += weight; get_bp_info(bp->cpu, type)->cpu_pinned += weight;
return; return;
} }
......
...@@ -1005,7 +1005,7 @@ __uprobe_perf_filter(struct trace_uprobe_filter *filter, struct mm_struct *mm) ...@@ -1005,7 +1005,7 @@ __uprobe_perf_filter(struct trace_uprobe_filter *filter, struct mm_struct *mm)
return true; return true;
list_for_each_entry(event, &filter->perf_events, hw.tp_list) { list_for_each_entry(event, &filter->perf_events, hw.tp_list) {
if (event->hw.tp_target->mm == mm) if (event->hw.target->mm == mm)
return true; return true;
} }
...@@ -1015,7 +1015,7 @@ __uprobe_perf_filter(struct trace_uprobe_filter *filter, struct mm_struct *mm) ...@@ -1015,7 +1015,7 @@ __uprobe_perf_filter(struct trace_uprobe_filter *filter, struct mm_struct *mm)
static inline bool static inline bool
uprobe_filter_event(struct trace_uprobe *tu, struct perf_event *event) uprobe_filter_event(struct trace_uprobe *tu, struct perf_event *event)
{ {
return __uprobe_perf_filter(&tu->filter, event->hw.tp_target->mm); return __uprobe_perf_filter(&tu->filter, event->hw.target->mm);
} }
static int uprobe_perf_close(struct trace_uprobe *tu, struct perf_event *event) static int uprobe_perf_close(struct trace_uprobe *tu, struct perf_event *event)
...@@ -1023,10 +1023,10 @@ static int uprobe_perf_close(struct trace_uprobe *tu, struct perf_event *event) ...@@ -1023,10 +1023,10 @@ static int uprobe_perf_close(struct trace_uprobe *tu, struct perf_event *event)
bool done; bool done;
write_lock(&tu->filter.rwlock); write_lock(&tu->filter.rwlock);
if (event->hw.tp_target) { if (event->hw.target) {
list_del(&event->hw.tp_list); list_del(&event->hw.tp_list);
done = tu->filter.nr_systemwide || done = tu->filter.nr_systemwide ||
(event->hw.tp_target->flags & PF_EXITING) || (event->hw.target->flags & PF_EXITING) ||
uprobe_filter_event(tu, event); uprobe_filter_event(tu, event);
} else { } else {
tu->filter.nr_systemwide--; tu->filter.nr_systemwide--;
...@@ -1046,7 +1046,7 @@ static int uprobe_perf_open(struct trace_uprobe *tu, struct perf_event *event) ...@@ -1046,7 +1046,7 @@ static int uprobe_perf_open(struct trace_uprobe *tu, struct perf_event *event)
int err; int err;
write_lock(&tu->filter.rwlock); write_lock(&tu->filter.rwlock);
if (event->hw.tp_target) { if (event->hw.target) {
/* /*
* event->parent != NULL means copy_process(), we can avoid * event->parent != NULL means copy_process(), we can avoid
* uprobe_apply(). current->mm must be probed and we can rely * uprobe_apply(). current->mm must be probed and we can rely
......
###
# build: Generic definitions
#
# Lots of this code have been borrowed or heavily inspired from parts
# of kbuild code, which is not credited, but mostly developed by:
#
# Copyright (C) Sam Ravnborg <sam@mars.ravnborg.org>, 2015
# Copyright (C) Linus Torvalds <torvalds@linux-foundation.org>, 2015
#
###
# Convenient variables
comma := ,
squote := '
###
# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o
dot-target = $(dir $@).$(notdir $@)
###
# filename of target with directory and extension stripped
basetarget = $(basename $(notdir $@))
###
# The temporary file to save gcc -MD generated dependencies must not
# contain a comma
depfile = $(subst $(comma),_,$(dot-target).d)
###
# Check if both arguments has same arguments. Result is empty string if equal.
arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
$(filter-out $(cmd_$@), $(cmd_$(1))) )
###
# Escape single quote for use in echo statements
escsq = $(subst $(squote),'\$(squote)',$1)
# Echo command
# Short version is used, if $(quiet) equals `quiet_', otherwise full one.
echo-cmd = $(if $($(quiet)cmd_$(1)),\
echo ' $(call escsq,$($(quiet)cmd_$(1)))';)
###
# Replace >$< with >$$< to preserve $ when reloading the .cmd file
# (needed for make)
# Replace >#< with >\#< to avoid starting a comment in the .cmd file
# (needed for make)
# Replace >'< with >'\''< to be able to enclose the whole string in '...'
# (needed for the shell)
make-cmd = $(call escsq,$(subst \#,\\\#,$(subst $$,$$$$,$(cmd_$(1)))))
###
# Find any prerequisites that is newer than target or that does not exist.
# PHONY targets skipped in both cases.
any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^)
###
# if_changed_dep - execute command if any prerequisite is newer than
# target, or command line has changed and update
# dependencies in the cmd file
if_changed_dep = $(if $(strip $(any-prereq) $(arg-check)), \
@set -e; \
$(echo-cmd) $(cmd_$(1)); \
cat $(depfile) > $(dot-target).cmd; \
printf '%s\n' 'cmd_$@ := $(make-cmd)' >> $(dot-target).cmd)
# if_changed - execute command if any prerequisite is newer than
# target, or command line has changed
if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
@set -e; \
$(echo-cmd) $(cmd_$(1)); \
printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)
###
# C flags to be used in rule definitions, includes:
# - depfile generation
# - global $(CFLAGS)
# - per target C flags
# - per object C flags
# - BUILD_STR macro to allow '-D"$(variable)"' constructs
c_flags = -Wp,-MD,$(depfile),-MT,$@ $(CFLAGS) -D"BUILD_STR(s)=\#s" $(CFLAGS_$(basetarget).o) $(CFLAGS_$(obj))
Build Framework
===============
The perf build framework was adopted from the kernel build system, hence the
idea and the way how objects are built is the same.
Basically the user provides set of 'Build' files that list objects and
directories to nest for specific target to be build.
Unlike the kernel we don't have a single build object 'obj-y' list that where
we setup source objects, but we support more. This allows one 'Build' file to
carry a sources list for multiple build objects.
a) Build framework makefiles
----------------------------
The build framework consists of 2 Makefiles:
Build.include
Makefile.build
While the 'Build.include' file contains just some generic definitions, the
'Makefile.build' file is the makefile used from the outside. It's
interface/usage is following:
$ make -f tools/build/Makefile srctree=$(KSRC) dir=$(DIR) obj=$(OBJECT)
where:
KSRC - is the path to kernel sources
DIR - is the path to the project to be built
OBJECT - is the name of the build object
When succefully finished the $(DIR) directory contains the final object file
called $(OBJECT)-in.o:
$ ls $(DIR)/$(OBJECT)-in.o
which includes all compiled sources described in 'Build' makefiles.
a) Build makefiles
------------------
The user supplies 'Build' makefiles that contains a objects list, and connects
the build to nested directories.
Assume we have the following project structure:
ex/a.c
/b.c
/c.c
/d.c
/arch/e.c
/arch/f.c
Out of which you build the 'ex' binary ' and the 'libex.a' library:
'ex' - consists of 'a.o', 'b.o' and libex.a
'libex.a' - consists of 'c.o', 'd.o', 'e.o' and 'f.o'
The build framework does not create the 'ex' and 'libex.a' binaries for you, it
only prepares proper objects to be compiled and grouped together.
To follow the above example, the user provides following 'Build' files:
ex/Build:
ex-y += a.o
ex-y += b.o
libex-y += c.o
libex-y += d.o
libex-y += arch/
ex/arch/Build:
libex-y += e.o
libex-y += f.o
and runs:
$ make -f tools/build/Makefile.build dir=. obj=ex
$ make -f tools/build/Makefile.build dir=. obj=libex
which creates the following objects:
ex/ex-in.o
ex/libex-in.o
that contain request objects names in Build files.
It's only a matter of 2 single commands to create the final binaries:
$ ar rcs libex.a libex-in.o
$ gcc -o ex ex-in.o libex.a
You can check the 'ex' example in 'tools/build/tests/ex' for more details.
b) Rules
--------
The build framework provides standard compilation rules to handle .S and .c
compilation.
It's possible to include special rule if needed (like we do for flex or bison
code generation).
c) CFLAGS
---------
It's possible to alter the standard object C flags in the following way:
CFLAGS_perf.o += '...' - alters CFLAGS for perf.o object
CFLAGS_gtk += '...' - alters CFLAGS for gtk build object
This C flags changes has the scope of the Build makefile they are defined in.
d) Dependencies
---------------
For each built object file 'a.o' the '.a.cmd' is created and holds:
- Command line used to built that object
(for each object)
- Dependency rules generated by 'gcc -Wp,-MD,...'
(for compiled object)
All existing '.cmd' files are included in the Build process to follow properly
the dependencies and trigger a rebuild when necessary.
e) Single rules
---------------
It's possible to build single object file by choice, like:
$ make util/map.o # objects
$ make util/map.i # preprocessor
$ make util/map.s # assembly
###
# Main build makefile.
#
# Lots of this code have been borrowed or heavily inspired from parts
# of kbuild code, which is not credited, but mostly developed by:
#
# Copyright (C) Sam Ravnborg <sam@mars.ravnborg.org>, 2015
# Copyright (C) Linus Torvalds <torvalds@linux-foundation.org>, 2015
#
PHONY := __build
__build:
ifeq ($(V),1)
quiet =
Q =
else
quiet=quiet_
Q=@
endif
build-dir := $(srctree)/tools/build
# Generic definitions
include $(build-dir)/Build.include
# do not force detected configuration
-include .config-detected
# Init all relevant variables used in build files so
# 1) they have correct type
# 2) they do not inherit any value from the environment
subdir-y :=
obj-y :=
subdir-y :=
subdir-obj-y :=
# Build definitions
build-file := $(dir)/Build
include $(build-file)
quiet_cmd_flex = FLEX $@
quiet_cmd_bison = BISON $@
# Create directory unless it exists
quiet_cmd_mkdir = MKDIR $(dir $@)
cmd_mkdir = mkdir -p $(dir $@)
rule_mkdir = $(if $(wildcard $(dir $@)),,@$(call echo-cmd,mkdir) $(cmd_mkdir))
# Compile command
quiet_cmd_cc_o_c = CC $@
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
quiet_cmd_cc_i_c = CPP $@
cmd_cc_i_c = $(CC) $(c_flags) -E -o $@ $<
quiet_cmd_cc_s_c = AS $@
cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $<
# Link agregate command
# If there's nothing to link, create empty $@ object.
quiet_cmd_ld_multi = LD $@
cmd_ld_multi = $(if $(strip $(obj-y)),\
$(LD) -r -o $@ $(obj-y),rm -f $@; $(AR) rcs $@)
# Build rules
$(OUTPUT)%.o: %.c FORCE
$(call rule_mkdir)
$(call if_changed_dep,cc_o_c)
$(OUTPUT)%.o: %.S FORCE
$(call rule_mkdir)
$(call if_changed_dep,cc_o_c)
$(OUTPUT)%.i: %.c FORCE
$(call rule_mkdir)
$(call if_changed_dep,cc_i_c)
$(OUTPUT)%.i: %.S FORCE
$(call rule_mkdir)
$(call if_changed_dep,cc_i_c)
$(OUTPUT)%.s: %.c FORCE
$(call rule_mkdir)
$(call if_changed_dep,cc_s_c)
# Gather build data:
# obj-y - list of build objects
# subdir-y - list of directories to nest
# subdir-obj-y - list of directories objects 'dir/$(obj)-in.o'
obj-y := $($(obj)-y)
subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
obj-y := $(patsubst %/, %/$(obj)-in.o, $(obj-y))
subdir-obj-y := $(filter %/$(obj)-in.o, $(obj-y))
# '$(OUTPUT)/dir' prefix to all objects
prefix := $(subst ./,,$(OUTPUT)$(dir)/)
obj-y := $(addprefix $(prefix),$(obj-y))
subdir-obj-y := $(addprefix $(prefix),$(subdir-obj-y))
# Final '$(obj)-in.o' object
in-target := $(prefix)$(obj)-in.o
PHONY += $(subdir-y)
$(subdir-y):
$(Q)$(MAKE) -f $(build-dir)/Makefile.build dir=$(dir)/$@ obj=$(obj)
$(sort $(subdir-obj-y)): $(subdir-y) ;
$(in-target): $(obj-y) FORCE
$(call rule_mkdir)
$(call if_changed,ld_multi)
__build: $(in-target)
@:
PHONY += FORCE
FORCE:
# Include all cmd files to get all the dependency rules
# for all objects included
targets := $(wildcard $(sort $(obj-y) $(in-target) $(MAKECMDGOALS)))
cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
ifneq ($(cmd_files),)
include $(cmd_files)
endif
.PHONY: $(PHONY)
feature_dir := $(srctree)/tools/build/feature
ifneq ($(OUTPUT),)
OUTPUT_FEATURES = $(OUTPUT)feature/
$(shell mkdir -p $(OUTPUT_FEATURES))
endif
feature_check = $(eval $(feature_check_code))
define feature_check_code
feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C $(feature_dir) test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0)
endef
feature_set = $(eval $(feature_set_code))
define feature_set_code
feature-$(1) := 1
endef
#
# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output:
#
#
# Note that this is not a complete list of all feature tests, just
# those that are typically built on a fully configured system.
#
# [ Feature tests not mentioned here have to be built explicitly in
# the rule that uses them - an example for that is the 'bionic'
# feature check. ]
#
FEATURE_TESTS = \
backtrace \
dwarf \
fortify-source \
sync-compare-and-swap \
glibc \
gtk2 \
gtk2-infobar \
libaudit \
libbfd \
libelf \
libelf-getphdrnum \
libelf-mmap \
libnuma \
libperl \
libpython \
libpython-version \
libslang \
libunwind \
pthread-attr-setaffinity-np \
stackprotector-all \
timerfd \
libdw-dwarf-unwind \
zlib \
lzma
FEATURE_DISPLAY = \
dwarf \
glibc \
gtk2 \
libaudit \
libbfd \
libelf \
libnuma \
libperl \
libpython \
libslang \
libunwind \
libdw-dwarf-unwind \
zlib \
lzma
# Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
# If in the future we need per-feature checks/flags for features not
# mentioned in this list we need to refactor this ;-).
set_test_all_flags = $(eval $(set_test_all_flags_code))
define set_test_all_flags_code
FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1))
FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1))
endef
$(foreach feat,$(FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
#
# Special fast-path for the 'all features are available' case:
#
$(call feature_check,all,$(MSG))
#
# Just in case the build freshly failed, make sure we print the
# feature matrix:
#
ifeq ($(feature-all), 1)
#
# test-all.c passed - just set all the core feature flags to 1:
#
$(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
else
$(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C $(feature_dir) $(addsuffix .bin,$(FEATURE_TESTS)) >/dev/null 2>&1)
$(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
endif
#
# Print the result of the feature test:
#
feature_print_status = $(eval $(feature_print_status_code)) $(info $(MSG))
define feature_print_status_code
ifeq ($(feature-$(1)), 1)
MSG = $(shell printf '...%30s: [ \033[32mon\033[m ]' $(1))
else
MSG = $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(1))
endif
endef
feature_print_text = $(eval $(feature_print_text_code)) $(info $(MSG))
define feature_print_text_code
MSG = $(shell printf '...%30s: %s' $(1) $(2))
endef
FEATURE_DUMP := $(foreach feat,$(FEATURE_DISPLAY),feature-$(feat)($(feature-$(feat))))
FEATURE_DUMP_FILE := $(shell touch $(OUTPUT)FEATURE-DUMP; cat $(OUTPUT)FEATURE-DUMP)
ifeq ($(dwarf-post-unwind),1)
FEATURE_DUMP += dwarf-post-unwind($(dwarf-post-unwind-text))
endif
# The $(feature_display) controls the default detection message
# output. It's set if:
# - detected features differes from stored features from
# last build (in FEATURE-DUMP file)
# - one of the $(FEATURE_DISPLAY) is not detected
# - VF is enabled
ifneq ("$(FEATURE_DUMP)","$(FEATURE_DUMP_FILE)")
$(shell echo "$(FEATURE_DUMP)" > $(OUTPUT)FEATURE-DUMP)
feature_display := 1
endif
feature_display_check = $(eval $(feature_check_code))
define feature_display_check_code
ifneq ($(feature-$(1)), 1)
feature_display := 1
endif
endef
$(foreach feat,$(FEATURE_DISPLAY),$(call feature_display_check,$(feat)))
ifeq ($(VF),1)
feature_display := 1
feature_verbose := 1
endif
ifeq ($(feature_display),1)
$(info )
$(info Auto-detecting system features:)
$(foreach feat,$(FEATURE_DISPLAY),$(call feature_print_status,$(feat),))
ifeq ($(dwarf-post-unwind),1)
$(call feature_print_text,"DWARF post unwind library", $(dwarf-post-unwind-text))
endif
ifneq ($(feature_verbose),1)
$(info )
endif
endif
ifeq ($(feature_verbose),1)
TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS))
$(foreach feat,$(TMP),$(call feature_print_status,$(feat),))
$(info )
endif
...@@ -29,33 +29,36 @@ FILES= \ ...@@ -29,33 +29,36 @@ FILES= \
test-stackprotector-all.bin \ test-stackprotector-all.bin \
test-timerfd.bin \ test-timerfd.bin \
test-libdw-dwarf-unwind.bin \ test-libdw-dwarf-unwind.bin \
test-libbabeltrace.bin \
test-compile-32.bin \ test-compile-32.bin \
test-compile-x32.bin \ test-compile-x32.bin \
test-zlib.bin test-zlib.bin \
test-lzma.bin
CC := $(CROSS_COMPILE)gcc -MD CC := $(CROSS_COMPILE)gcc -MD
PKG_CONFIG := $(CROSS_COMPILE)pkg-config PKG_CONFIG := $(CROSS_COMPILE)pkg-config
all: $(FILES) all: $(FILES)
BUILD = $(CC) $(CFLAGS) -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@) $(LDFLAGS) __BUILD = $(CC) $(CFLAGS) -Wall -Werror -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@) $(LDFLAGS)
BUILD = $(__BUILD) > $(OUTPUT)$(@:.bin=.make.output) 2>&1
############################### ###############################
test-all.bin: test-all.bin:
$(BUILD) -Werror -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl -lz $(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl -lz -llzma
test-hello.bin: test-hello.bin:
$(BUILD) $(BUILD)
test-pthread-attr-setaffinity-np.bin: test-pthread-attr-setaffinity-np.bin:
$(BUILD) -D_GNU_SOURCE -Werror -lpthread $(BUILD) -D_GNU_SOURCE -lpthread
test-stackprotector-all.bin: test-stackprotector-all.bin:
$(BUILD) -Werror -fstack-protector-all $(BUILD) -fstack-protector-all
test-fortify-source.bin: test-fortify-source.bin:
$(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2 $(BUILD) -O2 -D_FORTIFY_SOURCE=2
test-bionic.bin: test-bionic.bin:
$(BUILD) $(BUILD)
...@@ -118,10 +121,10 @@ test-libbfd.bin: ...@@ -118,10 +121,10 @@ test-libbfd.bin:
$(BUILD) -DPACKAGE='"perf"' -lbfd -lz -liberty -ldl $(BUILD) -DPACKAGE='"perf"' -lbfd -lz -liberty -ldl
test-liberty.bin: test-liberty.bin:
$(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty $(CC) -Wall -Werror -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty
test-liberty-z.bin: test-liberty-z.bin:
$(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty -lz $(CC) -Wall -Werror -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty -lz
test-cplus-demangle.bin: test-cplus-demangle.bin:
$(BUILD) -liberty $(BUILD) -liberty
...@@ -133,10 +136,13 @@ test-timerfd.bin: ...@@ -133,10 +136,13 @@ test-timerfd.bin:
$(BUILD) $(BUILD)
test-libdw-dwarf-unwind.bin: test-libdw-dwarf-unwind.bin:
$(BUILD) $(BUILD) # -ldw provided by $(FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind)
test-libbabeltrace.bin:
$(BUILD) # -lbabeltrace provided by $(FEATURE_CHECK_LDFLAGS-libbabeltrace)
test-sync-compare-and-swap.bin: test-sync-compare-and-swap.bin:
$(BUILD) -Werror $(BUILD)
test-compile-32.bin: test-compile-32.bin:
$(CC) -m32 -o $(OUTPUT)$@ test-compile.c $(CC) -m32 -o $(OUTPUT)$@ test-compile.c
...@@ -147,9 +153,12 @@ test-compile-x32.bin: ...@@ -147,9 +153,12 @@ test-compile-x32.bin:
test-zlib.bin: test-zlib.bin:
$(BUILD) -lz $(BUILD) -lz
test-lzma.bin:
$(BUILD) -llzma
-include *.d -include *.d
############################### ###############################
clean: clean:
rm -f $(FILES) *.d rm -f $(FILES) *.d $(FILES:.bin=.make.output)
...@@ -98,7 +98,23 @@ ...@@ -98,7 +98,23 @@
#undef main #undef main
#define main main_test_pthread_attr_setaffinity_np #define main main_test_pthread_attr_setaffinity_np
# include "test-pthread_attr_setaffinity_np.c" # include "test-pthread-attr-setaffinity-np.c"
#undef main
# if 0
/*
* Disable libbabeltrace check for test-all, because the requested
* library version is not released yet in most distributions. Will
* reenable later.
*/
#define main main_test_libbabeltrace
# include "test-libbabeltrace.c"
#undef main
#endif
#define main main_test_lzma
# include "test-lzma.c"
#undef main #undef main
int main(int argc, char *argv[]) int main(int argc, char *argv[])
...@@ -126,6 +142,7 @@ int main(int argc, char *argv[]) ...@@ -126,6 +142,7 @@ int main(int argc, char *argv[])
main_test_sync_compare_and_swap(argc, argv); main_test_sync_compare_and_swap(argc, argv);
main_test_zlib(); main_test_zlib();
main_test_pthread_attr_setaffinity_np(); main_test_pthread_attr_setaffinity_np();
main_test_lzma();
return 0; return 0;
} }
#include <babeltrace/ctf-writer/writer.h>
#include <babeltrace/ctf-ir/stream-class.h>
int main(void)
{
bt_ctf_stream_class_get_packet_context_type((void *) 0);
return 0;
}
#include <lzma.h>
int main(void)
{
lzma_stream strm = LZMA_STREAM_INIT;
int ret;
ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
return ret ? -1 : 0;
}
#include <stdint.h> #include <stdint.h>
#include <pthread.h> #include <pthread.h>
#include <sched.h>
int main(void) int main(void)
{ {
...@@ -8,7 +9,8 @@ int main(void) ...@@ -8,7 +9,8 @@ int main(void)
cpu_set_t cs; cpu_set_t cs;
pthread_attr_init(&thread_attr); pthread_attr_init(&thread_attr);
/* don't care abt exact args, just the API itself in libpthread */ CPU_ZERO(&cs);
ret = pthread_attr_setaffinity_np(&thread_attr, sizeof(cs), &cs); ret = pthread_attr_setaffinity_np(&thread_attr, sizeof(cs), &cs);
return ret; return ret;
......
ex-y += ex.o
ex-y += a.o
ex-y += b.o
ex-y += empty/
libex-y += c.o
libex-y += d.o
libex-y += arch/
export srctree := ../../../..
export CC := gcc
export LD := ld
export AR := ar
build := -f $(srctree)/tools/build/Makefile.build dir=. obj
ex: ex-in.o libex-in.o
gcc -o $@ $^
ex.%: FORCE
make -f $(srctree)/tools/build/Makefile.build dir=. $@
ex-in.o: FORCE
make $(build)=ex
libex-in.o: FORCE
make $(build)=libex
clean:
find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
rm -f ex ex.i ex.s
.PHONY: FORCE
int a(void)
{
return 0;
}
libex-y += e.o
libex-y += f.o
int e(void)
{
return 0;
}
int f(void)
{
return 0;
}
int b(void)
{
return 0;
}
int c(void)
{
return 0;
}
int d(void)
{
return 0;
}
int a(void);
int b(void);
int c(void);
int d(void);
int e(void);
int f(void);
int main(void)
{
a();
b();
c();
d();
e();
f();
return 0;
}
#!/bin/sh
function test_ex {
make -C ex V=1 clean > ex.out 2>&1
make -C ex V=1 >> ex.out 2>&1
if [ ! -x ./ex/ex ]; then
echo FAILED
exit -1
fi
make -C ex V=1 clean > /dev/null 2>&1
rm -f ex.out
}
function test_ex_suffix {
make -C ex V=1 clean > ex.out 2>&1
# use -rR to disable make's builtin rules
make -rR -C ex V=1 ex.o >> ex.out 2>&1
make -rR -C ex V=1 ex.i >> ex.out 2>&1
make -rR -C ex V=1 ex.s >> ex.out 2>&1
if [ -x ./ex/ex ]; then
echo FAILED
exit -1
fi
if [ ! -f ./ex/ex.o -o ! -f ./ex/ex.i -o ! -f ./ex/ex.s ]; then
echo FAILED
exit -1
fi
make -C ex V=1 clean > /dev/null 2>&1
rm -f ex.out
}
echo -n Testing..
test_ex
test_ex_suffix
echo OK
libapi-y += fd/
libapi-y += fs/
include ../../scripts/Makefile.include include ../../scripts/Makefile.include
include ../../perf/config/utilities.mak # QUIET_CLEAN include ../../perf/config/utilities.mak # QUIET_CLEAN
ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
#$(info Determined 'srctree' to be $(srctree))
endif
CC = $(CROSS_COMPILE)gcc CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar AR = $(CROSS_COMPILE)ar
# guard against environment variables MAKEFLAGS += --no-print-directory
LIB_H=
LIB_OBJS=
LIB_H += fs/debugfs.h
LIB_H += fs/fs.h
# See comment below about piggybacking...
LIB_H += fd/array.h
LIB_OBJS += $(OUTPUT)fs/debugfs.o
LIB_OBJS += $(OUTPUT)fs/fs.o
# XXX piggybacking here, need to introduce libapikfd, or rename this
# to plain libapik.a and make it have it all api goodies
LIB_OBJS += $(OUTPUT)fd/array.o
LIBFILE = libapikfs.a LIBFILE = $(OUTPUT)libapi.a
CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -fPIC CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
EXTLIBS = -lelf -lpthread -lrt -lm CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 -fPIC
ALL_CFLAGS = $(CFLAGS) $(BASIC_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
ALL_LDFLAGS = $(LDFLAGS)
RM = rm -f RM = rm -f
$(LIBFILE): $(LIB_OBJS) build := -f $(srctree)/tools/build/Makefile.build dir=. obj
$(QUIET_AR)$(RM) $@ && $(AR) rcs $(OUTPUT)$@ $(LIB_OBJS) API_IN := $(OUTPUT)libapi-in.o
$(LIB_OBJS): $(LIB_H) export srctree OUTPUT CC LD CFLAGS V
libapi_dirs: all: $(LIBFILE)
$(QUIET_MKDIR)mkdir -p $(OUTPUT)fd $(OUTPUT)fs
$(OUTPUT)%.o: %.c libapi_dirs $(API_IN): FORCE
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< @$(MAKE) $(build)=libapi
$(OUTPUT)%.s: %.c libapi_dirs
$(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $< $(LIBFILE): $(API_IN)
$(OUTPUT)%.o: %.S libapi_dirs $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(API_IN)
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
clean: clean:
$(call QUIET_CLEAN, libapi) $(RM) $(LIB_OBJS) $(LIBFILE) $(call QUIET_CLEAN, libapi) $(RM) $(LIBFILE); \
find $(if $(OUTPUT),$(OUTPUT),.) -name \*.o | xargs $(RM)
FORCE:
.PHONY: clean .PHONY: clean FORCE
libapi-y += array.o
libapi-y += fs.o
libapi-y += debugfs.o
libapi-y += findfs.o
libapi-y += tracefs.o
...@@ -3,75 +3,50 @@ ...@@ -3,75 +3,50 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <stdbool.h> #include <stdbool.h>
#include <sys/vfs.h> #include <sys/vfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include "debugfs.h" #include "debugfs.h"
char debugfs_mountpoint[PATH_MAX + 1] = "/sys/kernel/debug"; #ifndef DEBUGFS_DEFAULT_PATH
#define DEBUGFS_DEFAULT_PATH "/sys/kernel/debug"
#endif
char debugfs_mountpoint[PATH_MAX + 1] = DEBUGFS_DEFAULT_PATH;
static const char * const debugfs_known_mountpoints[] = { static const char * const debugfs_known_mountpoints[] = {
"/sys/kernel/debug", DEBUGFS_DEFAULT_PATH,
"/debug", "/debug",
0, 0,
}; };
static bool debugfs_found; static bool debugfs_found;
bool debugfs_configured(void)
{
return debugfs_find_mountpoint() != NULL;
}
/* find the path to the mounted debugfs */ /* find the path to the mounted debugfs */
const char *debugfs_find_mountpoint(void) const char *debugfs_find_mountpoint(void)
{ {
const char * const *ptr; const char *ret;
char type[100];
FILE *fp;
if (debugfs_found) if (debugfs_found)
return (const char *)debugfs_mountpoint; return (const char *)debugfs_mountpoint;
ptr = debugfs_known_mountpoints; ret = find_mountpoint("debugfs", (long) DEBUGFS_MAGIC,
while (*ptr) { debugfs_mountpoint, PATH_MAX + 1,
if (debugfs_valid_mountpoint(*ptr) == 0) { debugfs_known_mountpoints);
debugfs_found = true; if (ret)
strcpy(debugfs_mountpoint, *ptr);
return debugfs_mountpoint;
}
ptr++;
}
/* give up and parse /proc/mounts */
fp = fopen("/proc/mounts", "r");
if (fp == NULL)
return NULL;
while (fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
debugfs_mountpoint, type) == 2) {
if (strcmp(type, "debugfs") == 0)
break;
}
fclose(fp);
if (strcmp(type, "debugfs") != 0)
return NULL;
debugfs_found = true; debugfs_found = true;
return debugfs_mountpoint; return ret;
}
/* verify that a mountpoint is actually a debugfs instance */
int debugfs_valid_mountpoint(const char *debugfs)
{
struct statfs st_fs;
if (statfs(debugfs, &st_fs) < 0)
return -ENOENT;
else if ((long)st_fs.f_type != (long)DEBUGFS_MAGIC)
return -ENOENT;
return 0;
} }
/* mount the debugfs somewhere if it's not mounted */ /* mount the debugfs somewhere if it's not mounted */
...@@ -87,7 +62,7 @@ char *debugfs_mount(const char *mountpoint) ...@@ -87,7 +62,7 @@ char *debugfs_mount(const char *mountpoint)
mountpoint = getenv(PERF_DEBUGFS_ENVIRONMENT); mountpoint = getenv(PERF_DEBUGFS_ENVIRONMENT);
/* if no environment variable, use default */ /* if no environment variable, use default */
if (mountpoint == NULL) if (mountpoint == NULL)
mountpoint = "/sys/kernel/debug"; mountpoint = DEBUGFS_DEFAULT_PATH;
} }
if (mount(NULL, mountpoint, "debugfs", 0, NULL) < 0) if (mount(NULL, mountpoint, "debugfs", 0, NULL) < 0)
......
#ifndef __API_DEBUGFS_H__ #ifndef __API_DEBUGFS_H__
#define __API_DEBUGFS_H__ #define __API_DEBUGFS_H__
#define _STR(x) #x #include "findfs.h"
#define STR(x) _STR(x)
/*
* On most systems <limits.h> would have given us this, but not on some systems
* (e.g. GNU/Hurd).
*/
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#ifndef DEBUGFS_MAGIC #ifndef DEBUGFS_MAGIC
#define DEBUGFS_MAGIC 0x64626720 #define DEBUGFS_MAGIC 0x64626720
...@@ -20,8 +11,8 @@ ...@@ -20,8 +11,8 @@
#define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR" #define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"
#endif #endif
bool debugfs_configured(void);
const char *debugfs_find_mountpoint(void); const char *debugfs_find_mountpoint(void);
int debugfs_valid_mountpoint(const char *debugfs);
char *debugfs_mount(const char *mountpoint); char *debugfs_mount(const char *mountpoint);
extern char debugfs_mountpoint[]; extern char debugfs_mountpoint[];
......
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sys/vfs.h>
#include "findfs.h"
/* verify that a mountpoint is actually the type we want */
int valid_mountpoint(const char *mount, long magic)
{
struct statfs st_fs;
if (statfs(mount, &st_fs) < 0)
return -ENOENT;
else if ((long)st_fs.f_type != magic)
return -ENOENT;
return 0;
}
/* find the path to a mounted file system */
const char *find_mountpoint(const char *fstype, long magic,
char *mountpoint, int len,
const char * const *known_mountpoints)
{
const char * const *ptr;
char format[128];
char type[100];
FILE *fp;
if (known_mountpoints) {
ptr = known_mountpoints;
while (*ptr) {
if (valid_mountpoint(*ptr, magic) == 0) {
strncpy(mountpoint, *ptr, len - 1);
mountpoint[len-1] = 0;
return mountpoint;
}
ptr++;
}
}
/* give up and parse /proc/mounts */
fp = fopen("/proc/mounts", "r");
if (fp == NULL)
return NULL;
snprintf(format, 128, "%%*s %%%ds %%99s %%*s %%*d %%*d\n", len);
while (fscanf(fp, format, mountpoint, type) == 2) {
if (strcmp(type, fstype) == 0)
break;
}
fclose(fp);
if (strcmp(type, fstype) != 0)
return NULL;
return mountpoint;
}
#ifndef __API_FINDFS_H__
#define __API_FINDFS_H__
#include <stdbool.h>
#define _STR(x) #x
#define STR(x) _STR(x)
/*
* On most systems <limits.h> would have given us this, but not on some systems
* (e.g. GNU/Hurd).
*/
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
const char *find_mountpoint(const char *fstype, long magic,
char *mountpoint, int len,
const char * const *known_mountpoints);
int valid_mountpoint(const char *mount, long magic);
#endif /* __API_FINDFS_H__ */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include <sys/vfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <linux/kernel.h>
#include "tracefs.h"
#ifndef TRACEFS_DEFAULT_PATH
#define TRACEFS_DEFAULT_PATH "/sys/kernel/tracing"
#endif
char tracefs_mountpoint[PATH_MAX + 1] = TRACEFS_DEFAULT_PATH;
static const char * const tracefs_known_mountpoints[] = {
TRACEFS_DEFAULT_PATH,
"/sys/kernel/debug/tracing",
"/tracing",
"/trace",
0,
};
static bool tracefs_found;
bool tracefs_configured(void)
{
return tracefs_find_mountpoint() != NULL;
}
/* find the path to the mounted tracefs */
const char *tracefs_find_mountpoint(void)
{
const char *ret;
if (tracefs_found)
return (const char *)tracefs_mountpoint;
ret = find_mountpoint("tracefs", (long) TRACEFS_MAGIC,
tracefs_mountpoint, PATH_MAX + 1,
tracefs_known_mountpoints);
if (ret)
tracefs_found = true;
return ret;
}
/* mount the tracefs somewhere if it's not mounted */
char *tracefs_mount(const char *mountpoint)
{
/* see if it's already mounted */
if (tracefs_find_mountpoint())
goto out;
/* if not mounted and no argument */
if (mountpoint == NULL) {
/* see if environment variable set */
mountpoint = getenv(PERF_TRACEFS_ENVIRONMENT);
/* if no environment variable, use default */
if (mountpoint == NULL)
mountpoint = TRACEFS_DEFAULT_PATH;
}
if (mount(NULL, mountpoint, "tracefs", 0, NULL) < 0)
return NULL;
/* save the mountpoint */
tracefs_found = true;
strncpy(tracefs_mountpoint, mountpoint, sizeof(tracefs_mountpoint));
out:
return tracefs_mountpoint;
}
#ifndef __API_TRACEFS_H__
#define __API_TRACEFS_H__
#include "findfs.h"
#ifndef TRACEFS_MAGIC
#define TRACEFS_MAGIC 0x74726163
#endif
#ifndef PERF_TRACEFS_ENVIRONMENT
#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"
#endif
bool tracefs_configured(void);
const char *tracefs_find_mountpoint(void);
int tracefs_valid_mountpoint(const char *debugfs);
char *tracefs_mount(const char *mountpoint);
extern char tracefs_mountpoint[];
#endif /* __API_DEBUGFS_H__ */
liblockdep-y += common.o lockdep.o preload.o rbtree.o
...@@ -35,6 +35,10 @@ bindir = $(prefix)/$(bindir_relative) ...@@ -35,6 +35,10 @@ bindir = $(prefix)/$(bindir_relative)
export DESTDIR DESTDIR_SQ INSTALL export DESTDIR DESTDIR_SQ INSTALL
MAKEFLAGS += --no-print-directory
include ../../scripts/Makefile.include
# copy a bit from Linux kbuild # copy a bit from Linux kbuild
ifeq ("$(origin V)", "command line") ifeq ("$(origin V)", "command line")
...@@ -44,56 +48,21 @@ ifndef VERBOSE ...@@ -44,56 +48,21 @@ ifndef VERBOSE
VERBOSE = 0 VERBOSE = 0
endif endif
ifeq ("$(origin O)", "command line") ifeq ($(srctree),)
BUILD_OUTPUT := $(O) srctree := $(patsubst %/,%,$(dir $(shell pwd)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
#$(info Determined 'srctree' to be $(srctree))
endif endif
ifeq ($(BUILD_SRC),)
ifneq ($(BUILD_OUTPUT),)
define build_output
$(if $(VERBOSE:1=),@)$(MAKE) -C $(BUILD_OUTPUT) \
BUILD_SRC=$(CURDIR) -f $(CURDIR)/Makefile $1
endef
saved-output := $(BUILD_OUTPUT)
BUILD_OUTPUT := $(shell cd $(BUILD_OUTPUT) && /bin/pwd)
$(if $(BUILD_OUTPUT),, \
$(error output directory "$(saved-output)" does not exist))
all: sub-make
gui: force
$(call build_output, all_cmd)
$(filter-out gui,$(MAKECMDGOALS)): sub-make
sub-make: force
$(call build_output, $(MAKECMDGOALS))
# Leave processing to above invocation of make
skip-makefile := 1
endif # BUILD_OUTPUT
endif # BUILD_SRC
# We process the rest of the Makefile if this is the final invocation of make
ifeq ($(skip-makefile),)
srctree := $(realpath $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR)))
objtree := $(realpath $(CURDIR))
src := $(srctree)
obj := $(objtree)
export prefix libdir bindir src obj
# Shell quotes # Shell quotes
libdir_SQ = $(subst ','\'',$(libdir)) libdir_SQ = $(subst ','\'',$(libdir))
bindir_SQ = $(subst ','\'',$(bindir)) bindir_SQ = $(subst ','\'',$(bindir))
LIB_FILE = liblockdep.a liblockdep.so.$(LIBLOCKDEP_VERSION) LIB_IN := $(OUTPUT)liblockdep-in.o
BIN_FILE = lockdep BIN_FILE = lockdep
LIB_FILE = $(OUTPUT)liblockdep.a $(OUTPUT)liblockdep.so.$(LIBLOCKDEP_VERSION)
CONFIG_INCLUDES = CONFIG_INCLUDES =
CONFIG_LIBS = CONFIG_LIBS =
...@@ -108,33 +77,23 @@ INCLUDES = -I. -I./uinclude -I./include -I../../include $(CONFIG_INCLUDES) ...@@ -108,33 +77,23 @@ INCLUDES = -I. -I./uinclude -I./include -I../../include $(CONFIG_INCLUDES)
# Set compile option CFLAGS if not set elsewhere # Set compile option CFLAGS if not set elsewhere
CFLAGS ?= -g -DCONFIG_LOCKDEP -DCONFIG_STACKTRACE -DCONFIG_PROVE_LOCKING -DBITS_PER_LONG=__WORDSIZE -DLIBLOCKDEP_VERSION='"$(LIBLOCKDEP_VERSION)"' -rdynamic -O0 -g CFLAGS ?= -g -DCONFIG_LOCKDEP -DCONFIG_STACKTRACE -DCONFIG_PROVE_LOCKING -DBITS_PER_LONG=__WORDSIZE -DLIBLOCKDEP_VERSION='"$(LIBLOCKDEP_VERSION)"' -rdynamic -O0 -g
CFLAGS += -fPIC
override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ) override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ)
ifeq ($(VERBOSE),1) ifeq ($(VERBOSE),1)
Q = Q =
print_compile =
print_app_build =
print_fpic_compile =
print_shared_lib_compile = print_shared_lib_compile =
print_install = print_install =
else else
Q = @ Q = @
print_compile = echo ' CC '$(OBJ); print_shared_lib_compile = echo ' LD '$(OBJ);
print_app_build = echo ' BUILD '$(OBJ); print_static_lib_build = echo ' LD '$(OBJ);
print_fpic_compile = echo ' CC FPIC '$(OBJ);
print_shared_lib_compile = echo ' BUILD SHARED LIB '$(OBJ);
print_static_lib_build = echo ' BUILD STATIC LIB '$(OBJ);
print_install = echo ' INSTALL '$1' to $(DESTDIR_SQ)$2'; print_install = echo ' INSTALL '$1' to $(DESTDIR_SQ)$2';
endif endif
do_fpic_compile = \ export srctree OUTPUT CC LD CFLAGS V
($(print_fpic_compile) \ build := -f $(srctree)/tools/build/Makefile.build dir=. obj
$(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@)
do_app_build = \
($(print_app_build) \
$(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS))
do_compile_shared_library = \ do_compile_shared_library = \
($(print_shared_lib_compile) \ ($(print_shared_lib_compile) \
...@@ -144,22 +103,6 @@ do_build_static_lib = \ ...@@ -144,22 +103,6 @@ do_build_static_lib = \
($(print_static_lib_build) \ ($(print_static_lib_build) \
$(RM) $@; $(AR) rcs $@ $^) $(RM) $@; $(AR) rcs $@ $^)
define do_compile
$(print_compile) \
$(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@;
endef
$(obj)/%.o: $(src)/%.c
$(Q)$(call do_compile)
%.o: $(src)/%.c
$(Q)$(call do_compile)
PEVENT_LIB_OBJS = common.o lockdep.o preload.o rbtree.o
ALL_OBJS = $(PEVENT_LIB_OBJS)
CMD_TARGETS = $(LIB_FILE) CMD_TARGETS = $(LIB_FILE)
TARGETS = $(CMD_TARGETS) TARGETS = $(CMD_TARGETS)
...@@ -169,42 +112,15 @@ all: all_cmd ...@@ -169,42 +112,15 @@ all: all_cmd
all_cmd: $(CMD_TARGETS) all_cmd: $(CMD_TARGETS)
liblockdep.so.$(LIBLOCKDEP_VERSION): $(PEVENT_LIB_OBJS) $(LIB_IN): force
$(Q)$(MAKE) $(build)=liblockdep
liblockdep.so.$(LIBLOCKDEP_VERSION): $(LIB_IN)
$(Q)$(do_compile_shared_library) $(Q)$(do_compile_shared_library)
liblockdep.a: $(PEVENT_LIB_OBJS) liblockdep.a: $(LIB_IN)
$(Q)$(do_build_static_lib) $(Q)$(do_build_static_lib)
$(PEVENT_LIB_OBJS): %.o: $(src)/%.c
$(Q)$(do_fpic_compile)
## make deps
all_objs := $(sort $(ALL_OBJS))
all_deps := $(all_objs:%.o=.%.d)
# let .d file also depends on the source and header files
define check_deps
@set -e; $(RM) $@; \
$(CC) -MM $(CFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
$(RM) $@.$$$$
endef
$(all_deps): .%.d: $(src)/%.c
$(Q)$(call check_deps)
$(all_objs) : %.o : .%.d
dep_includes := $(wildcard $(all_deps))
ifneq ($(dep_includes),)
include $(dep_includes)
endif
### Detect environment changes
TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE)
tags: force tags: force
$(RM) tags $(RM) tags
find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \ find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
...@@ -233,8 +149,6 @@ clean: ...@@ -233,8 +149,6 @@ clean:
$(RM) *.o *~ $(TARGETS) *.a *liblockdep*.so* $(VERSION_FILES) .*.d $(RM) *.o *~ $(TARGETS) *.a *liblockdep*.so* $(VERSION_FILES) .*.d
$(RM) tags TAGS $(RM) tags TAGS
endif # skip-makefile
PHONY += force PHONY += force
force: force:
......
libtraceevent-y += event-parse.o
libtraceevent-y += event-plugin.o
libtraceevent-y += trace-seq.o
libtraceevent-y += parse-filter.o
libtraceevent-y += parse-utils.o
libtraceevent-y += kbuffer-parse.o
plugin_jbd2-y += plugin_jbd2.o
plugin_hrtimer-y += plugin_hrtimer.o
plugin_kmem-y += plugin_kmem.o
plugin_kvm-y += plugin_kvm.o
plugin_mac80211-y += plugin_mac80211.o
plugin_sched_switch-y += plugin_sched_switch.o
plugin_function-y += plugin_function.o
plugin_xen-y += plugin_xen.o
plugin_scsi-y += plugin_scsi.o
plugin_cfg80211-y += plugin_cfg80211.o
...@@ -67,7 +67,7 @@ PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)" ...@@ -67,7 +67,7 @@ PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)"
PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))' PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))'
endif endif
include $(if $(BUILD_SRC),$(BUILD_SRC)/)../../scripts/Makefile.include include ../../scripts/Makefile.include
# copy a bit from Linux kbuild # copy a bit from Linux kbuild
...@@ -78,40 +78,13 @@ ifndef VERBOSE ...@@ -78,40 +78,13 @@ ifndef VERBOSE
VERBOSE = 0 VERBOSE = 0
endif endif
ifeq ("$(origin O)", "command line") ifeq ($(srctree),)
BUILD_OUTPUT := $(O) srctree := $(patsubst %/,%,$(dir $(shell pwd)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
#$(info Determined 'srctree' to be $(srctree))
endif endif
ifeq ($(BUILD_SRC),)
ifneq ($(OUTPUT),)
define build_output
$(if $(VERBOSE:1=),@)+$(MAKE) -C $(OUTPUT) \
BUILD_SRC=$(CURDIR)/ -f $(CURDIR)/Makefile $1
endef
all: sub-make
$(MAKECMDGOALS): sub-make
sub-make: force
$(call build_output, $(MAKECMDGOALS))
# Leave processing to above invocation of make
skip-makefile := 1
endif # OUTPUT
endif # BUILD_SRC
# We process the rest of the Makefile if this is the final invocation of make
ifeq ($(skip-makefile),)
srctree := $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR))
objtree := $(CURDIR)
src := $(srctree)
obj := $(objtree)
export prefix bindir src obj export prefix bindir src obj
# Shell quotes # Shell quotes
...@@ -132,16 +105,19 @@ EXTRAVERSION = $(EP_EXTRAVERSION) ...@@ -132,16 +105,19 @@ EXTRAVERSION = $(EP_EXTRAVERSION)
OBJ = $@ OBJ = $@
N = N =
export Q VERBOSE
EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION) EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION)
INCLUDES = -I. -I $(srctree)/../../include $(CONFIG_INCLUDES) INCLUDES = -I. -I $(srctree)/tools/include $(CONFIG_INCLUDES)
# Set compile option CFLAGS if not set elsewhere # Set compile option CFLAGS
CFLAGS ?= -g -Wall ifdef EXTRA_CFLAGS
CFLAGS := $(EXTRA_CFLAGS)
else
CFLAGS := -g -Wall
endif
# Append required CFLAGS # Append required CFLAGS
override CFLAGS += -fPIC
override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ) override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ)
override CFLAGS += $(udis86-flags) -D_GNU_SOURCE override CFLAGS += $(udis86-flags) -D_GNU_SOURCE
...@@ -151,74 +127,58 @@ else ...@@ -151,74 +127,58 @@ else
Q = @ Q = @
endif endif
do_compile_shared_library = \ # Disable command line variables (CFLAGS) overide from top
($(print_shared_lib_compile) \ # level Makefile (perf), otherwise build Makefile will get
$(CC) --shared $^ -o $@) # the same command line setup.
MAKEOVERRIDES=
do_plugin_build = \
($(print_plugin_build) \
$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $<)
do_build_static_lib = \
($(print_static_lib_build) \
$(RM) $@; $(AR) rcs $@ $^)
do_compile = $(QUIET_CC)$(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@;
$(obj)/%.o: $(src)/%.c export srctree OUTPUT CC LD CFLAGS V
$(call do_compile) build := -f $(srctree)/tools/build/Makefile.build dir=. obj
%.o: $(src)/%.c PLUGINS = plugin_jbd2.so
$(call do_compile) PLUGINS += plugin_hrtimer.so
PLUGINS += plugin_kmem.so
PLUGINS += plugin_kvm.so
PLUGINS += plugin_mac80211.so
PLUGINS += plugin_sched_switch.so
PLUGINS += plugin_function.so
PLUGINS += plugin_xen.so
PLUGINS += plugin_scsi.so
PLUGINS += plugin_cfg80211.so
PEVENT_LIB_OBJS = event-parse.o PLUGINS := $(addprefix $(OUTPUT),$(PLUGINS))
PEVENT_LIB_OBJS += event-plugin.o PLUGINS_IN := $(PLUGINS:.so=-in.o)
PEVENT_LIB_OBJS += trace-seq.o
PEVENT_LIB_OBJS += parse-filter.o
PEVENT_LIB_OBJS += parse-utils.o
PEVENT_LIB_OBJS += kbuffer-parse.o
PLUGIN_OBJS = plugin_jbd2.o TE_IN := $(OUTPUT)libtraceevent-in.o
PLUGIN_OBJS += plugin_hrtimer.o LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE))
PLUGIN_OBJS += plugin_kmem.o
PLUGIN_OBJS += plugin_kvm.o
PLUGIN_OBJS += plugin_mac80211.o
PLUGIN_OBJS += plugin_sched_switch.o
PLUGIN_OBJS += plugin_function.o
PLUGIN_OBJS += plugin_xen.o
PLUGIN_OBJS += plugin_scsi.o
PLUGIN_OBJS += plugin_cfg80211.o
PLUGINS := $(PLUGIN_OBJS:.o=.so)
ALL_OBJS = $(PEVENT_LIB_OBJS) $(PLUGIN_OBJS)
CMD_TARGETS = $(LIB_FILE) $(PLUGINS) CMD_TARGETS = $(LIB_FILE) $(PLUGINS)
TARGETS = $(CMD_TARGETS) TARGETS = $(CMD_TARGETS)
all: all_cmd all: all_cmd
all_cmd: $(CMD_TARGETS) all_cmd: $(CMD_TARGETS)
libtraceevent.so: $(PEVENT_LIB_OBJS) $(TE_IN): force
$(Q)$(MAKE) $(build)=libtraceevent
$(OUTPUT)libtraceevent.so: $(TE_IN)
$(QUIET_LINK)$(CC) --shared $^ -o $@ $(QUIET_LINK)$(CC) --shared $^ -o $@
libtraceevent.a: $(PEVENT_LIB_OBJS) $(OUTPUT)libtraceevent.a: $(TE_IN)
$(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
plugins: $(PLUGINS) plugins: $(PLUGINS)
$(PEVENT_LIB_OBJS): %.o: $(src)/%.c TRACEEVENT-CFLAGS __plugin_obj = $(notdir $@)
$(QUIET_CC_FPIC)$(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@ plugin_obj = $(__plugin_obj:-in.o=)
$(PLUGIN_OBJS): %.o : $(src)/%.c $(PLUGINS_IN): force
$(QUIET_CC_FPIC)$(CC) -c $(CFLAGS) -fPIC -o $@ $< $(Q)$(MAKE) $(build)=$(plugin_obj)
$(PLUGINS): %.so: %.o $(OUTPUT)%.so: $(OUTPUT)%-in.o
$(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $< $(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $^
define make_version.h define make_version.h
(echo '/* This file is automatically generated. Do not modify. */'; \ (echo '/* This file is automatically generated. Do not modify. */'; \
...@@ -255,40 +215,6 @@ define update_dir ...@@ -255,40 +215,6 @@ define update_dir
fi); fi);
endef endef
## make deps
all_objs := $(sort $(ALL_OBJS))
all_deps := $(all_objs:%.o=.%.d)
# let .d file also depends on the source and header files
define check_deps
@set -e; $(RM) $@; \
$(CC) -MM $(CFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
$(RM) $@.$$$$
endef
$(all_deps): .%.d: $(src)/%.c
$(Q)$(call check_deps)
$(all_objs) : %.o : .%.d
dep_includes := $(wildcard $(all_deps))
ifneq ($(dep_includes),)
include $(dep_includes)
endif
### Detect environment changes
TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE)
TRACEEVENT-CFLAGS: force
@FLAGS='$(TRACK_CFLAGS)'; \
if test x"$$FLAGS" != x"`cat TRACEEVENT-CFLAGS 2>/dev/null`" ; then \
echo 1>&2 " FLAGS: * new build flags or cross compiler"; \
echo "$$FLAGS" >TRACEEVENT-CFLAGS; \
fi
tags: force tags: force
$(RM) tags $(RM) tags
find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \ find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
...@@ -327,14 +253,9 @@ clean: ...@@ -327,14 +253,9 @@ clean:
$(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d \ $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d \
$(RM) TRACEEVENT-CFLAGS tags TAGS $(RM) TRACEEVENT-CFLAGS tags TAGS
endif # skip-makefile
PHONY += force plugins PHONY += force plugins
force: force:
plugins:
@echo > /dev/null
# Declare the contents of the .PHONY variable as phony. We keep that # Declare the contents of the .PHONY variable as phony. We keep that
# information in a variable so we can use it in if_changed and friends. # information in a variable so we can use it in if_changed and friends.
.PHONY: $(PHONY) .PHONY: $(PHONY)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -372,7 +372,6 @@ translate_data(struct kbuffer *kbuf, void *data, void **rptr, ...@@ -372,7 +372,6 @@ translate_data(struct kbuffer *kbuf, void *data, void **rptr,
switch (type_len) { switch (type_len) {
case KBUFFER_TYPE_PADDING: case KBUFFER_TYPE_PADDING:
*length = read_4(kbuf, data); *length = read_4(kbuf, data);
data += *length;
break; break;
case KBUFFER_TYPE_TIME_EXTEND: case KBUFFER_TYPE_TIME_EXTEND:
...@@ -730,3 +729,14 @@ void kbuffer_set_old_format(struct kbuffer *kbuf) ...@@ -730,3 +729,14 @@ void kbuffer_set_old_format(struct kbuffer *kbuf)
kbuf->next_event = __old_next_event; kbuf->next_event = __old_next_event;
} }
/**
* kbuffer_start_of_data - return offset of where data starts on subbuffer
* @kbuf: The kbuffer
*
* Returns the location on the subbuffer where the data starts.
*/
int kbuffer_start_of_data(struct kbuffer *kbuf)
{
return kbuf->start;
}
...@@ -63,5 +63,6 @@ int kbuffer_missed_events(struct kbuffer *kbuf); ...@@ -63,5 +63,6 @@ int kbuffer_missed_events(struct kbuffer *kbuf);
int kbuffer_subbuffer_size(struct kbuffer *kbuf); int kbuffer_subbuffer_size(struct kbuffer *kbuf);
void kbuffer_set_old_format(struct kbuffer *kbuf); void kbuffer_set_old_format(struct kbuffer *kbuf);
int kbuffer_start_of_data(struct kbuffer *kbuf);
#endif /* _K_BUFFER_H */ #endif /* _K_BUFFER_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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