*/
/*
- * hw_event.type
+ * attr.type
*/
enum perf_event_types {
PERF_TYPE_HARDWARE = 0,
};
/*
- * Generalized performance counter event types, used by the hw_event.event_id
+ * Generalized performance counter event types, used by the attr.event_id
* parameter of the sys_perf_counter_open() syscall:
*/
-enum hw_event_ids {
+enum attr_ids {
/*
* Common hardware events, generalized by the kernel:
*/
#define PERF_COUNTER_EVENT_MASK __PERF_COUNTER_MASK(EVENT)
/*
- * Bits that can be set in hw_event.record_type to request information
+ * Bits that can be set in attr.sample_type to request information
* in the overflow packets.
*/
-enum perf_counter_record_format {
- PERF_RECORD_IP = 1U << 0,
- PERF_RECORD_TID = 1U << 1,
- PERF_RECORD_TIME = 1U << 2,
- PERF_RECORD_ADDR = 1U << 3,
- PERF_RECORD_GROUP = 1U << 4,
- PERF_RECORD_CALLCHAIN = 1U << 5,
- PERF_RECORD_CONFIG = 1U << 6,
- PERF_RECORD_CPU = 1U << 7,
+enum perf_counter_sample_format {
+ PERF_SAMPLE_IP = 1U << 0,
+ PERF_SAMPLE_TID = 1U << 1,
+ PERF_SAMPLE_TIME = 1U << 2,
+ PERF_SAMPLE_ADDR = 1U << 3,
+ PERF_SAMPLE_GROUP = 1U << 4,
+ PERF_SAMPLE_CALLCHAIN = 1U << 5,
+ PERF_SAMPLE_CONFIG = 1U << 6,
+ PERF_SAMPLE_CPU = 1U << 7,
};
/*
- * Bits that can be set in hw_event.read_format to request that
+ * Bits that can be set in attr.read_format to request that
* reads on the counter should return the indicated quantities,
* in increasing order of bit value, after the counter value.
*/
enum perf_counter_read_format {
- PERF_FORMAT_TOTAL_TIME_ENABLED = 1,
- PERF_FORMAT_TOTAL_TIME_RUNNING = 2,
+ PERF_FORMAT_TOTAL_TIME_ENABLED = 1U << 0,
+ PERF_FORMAT_TOTAL_TIME_RUNNING = 1U << 1,
+ PERF_FORMAT_ID = 1U << 2,
};
/*
* Hardware event to monitor via a performance monitoring counter:
*/
-struct perf_counter_hw_event {
+struct perf_counter_attr {
/*
* The MSB of the config word signifies if the rest contains cpu
* specific (raw) counter configuration data, if unset, the next
__u64 config;
union {
- __u64 irq_period;
- __u64 irq_freq;
+ __u64 sample_period;
+ __u64 sample_freq;
};
- __u32 record_type;
- __u32 read_format;
+ __u64 sample_type;
+ __u64 read_format;
__u64 disabled : 1, /* off by default */
- nmi : 1, /* NMI sampling */
inherit : 1, /* children inherit it */
pinned : 1, /* must always be on PMU */
exclusive : 1, /* only group on PMU */
comm : 1, /* include comm data */
freq : 1, /* use freq, not period */
- __reserved_1 : 51;
+ __reserved_1 : 52;
__u32 wakeup_events; /* wakeup every n events */
__u32 __reserved_2;
/*
* Ioctls that can be done on a perf counter fd:
*/
-#define PERF_COUNTER_IOC_ENABLE _IOW('$', 0, u32)
-#define PERF_COUNTER_IOC_DISABLE _IOW('$', 1, u32)
-#define PERF_COUNTER_IOC_REFRESH _IOW('$', 2, u32)
-#define PERF_COUNTER_IOC_RESET _IOW('$', 3, u32)
+#define PERF_COUNTER_IOC_ENABLE _IO ('$', 0)
+#define PERF_COUNTER_IOC_DISABLE _IO ('$', 1)
+#define PERF_COUNTER_IOC_REFRESH _IO ('$', 2)
+#define PERF_COUNTER_IOC_RESET _IO ('$', 3)
+#define PERF_COUNTER_IOC_PERIOD _IOW('$', 4, u64)
enum perf_counter_ioc_flags {
PERF_IOC_FLAG_GROUP = 1U << 0,
* User-space reading this value should issue an rmb(), on SMP capable
* platforms, after reading this value -- see perf_counter_wakeup().
*/
- __u32 data_head; /* head in the data section */
+ __u64 data_head; /* head in the data section */
};
#define PERF_EVENT_MISC_CPUMODE_MASK (3 << 0)
* struct {
* struct perf_event_header header;
* u64 time;
- * u64 irq_period;
+ * u64 sample_period;
* };
*/
PERF_EVENT_PERIOD = 4,
PERF_EVENT_UNTHROTTLE = 6,
/*
+ * struct {
+ * struct perf_event_header header;
+ * u32 pid, ppid;
+ * };
+ */
+ PERF_EVENT_FORK = 7,
+
+ /*
* When header.misc & PERF_EVENT_MISC_OVERFLOW the event_type field
* will be PERF_RECORD_*
*
* { u32 cpu, res; } && PERF_RECORD_CPU
*
* { u64 nr;
- * { u64 event, val; } cnt[nr]; } && PERF_RECORD_GROUP
+ * { u64 id, val; } cnt[nr]; } && PERF_RECORD_GROUP
*
* { u16 nr,
* hv,
#include <linux/spinlock.h>
#include <linux/hrtimer.h>
#include <linux/fs.h>
+#include <linux/pid_namespace.h>
#include <asm/atomic.h>
struct task_struct;
-static inline u64 perf_event_raw(struct perf_counter_hw_event *hw_event)
+static inline u64 perf_event_raw(struct perf_counter_attr *attr)
{
- return hw_event->config & PERF_COUNTER_RAW_MASK;
+ return attr->config & PERF_COUNTER_RAW_MASK;
}
-static inline u64 perf_event_config(struct perf_counter_hw_event *hw_event)
+static inline u64 perf_event_config(struct perf_counter_attr *attr)
{
- return hw_event->config & PERF_COUNTER_CONFIG_MASK;
+ return attr->config & PERF_COUNTER_CONFIG_MASK;
}
-static inline u64 perf_event_type(struct perf_counter_hw_event *hw_event)
+static inline u64 perf_event_type(struct perf_counter_attr *attr)
{
- return (hw_event->config & PERF_COUNTER_TYPE_MASK) >>
+ return (attr->config & PERF_COUNTER_TYPE_MASK) >>
PERF_COUNTER_TYPE_SHIFT;
}
-static inline u64 perf_event_id(struct perf_counter_hw_event *hw_event)
+static inline u64 perf_event_id(struct perf_counter_attr *attr)
{
- return hw_event->config & PERF_COUNTER_EVENT_MASK;
+ return attr->config & PERF_COUNTER_EVENT_MASK;
}
/**
u64 config;
unsigned long config_base;
unsigned long counter_base;
- int nmi;
int idx;
};
union { /* software */
};
};
atomic64_t prev_count;
- u64 irq_period;
+ u64 sample_period;
atomic64_t period_left;
u64 interrupts;
#endif
int nr_locked; /* nr pages mlocked */
atomic_t poll; /* POLL_ for wakeups */
- atomic_t head; /* write position */
atomic_t events; /* event limit */
- atomic_t done_head; /* completed head */
+ atomic_long_t head; /* write position */
+ atomic_long_t done_head; /* completed head */
+
atomic_t lock; /* concurrent writes */
atomic_t wakeup; /* needs a wakeup */
const struct pmu *pmu;
enum perf_counter_active_state state;
- enum perf_counter_active_state prev_state;
atomic64_t count;
/*
u64 tstamp_running;
u64 tstamp_stopped;
- struct perf_counter_hw_event hw_event;
+ struct perf_counter_attr attr;
struct hw_perf_counter hw;
struct perf_counter_context *ctx;
void (*destroy)(struct perf_counter *);
struct rcu_head rcu_head;
+
+ struct pid_namespace *ns;
+ u64 id;
#endif
};
struct perf_counter_context *parent_ctx;
u64 parent_gen;
u64 generation;
+ int pin_count;
struct rcu_head rcu_head;
};
*
* task, softirq, irq, nmi context
*/
- int recursion[4];
+ int recursion[4];
};
#ifdef CONFIG_PERF_COUNTERS
extern void perf_counter_task_tick(struct task_struct *task, int cpu);
extern int perf_counter_init_task(struct task_struct *child);
extern void perf_counter_exit_task(struct task_struct *child);
+extern void perf_counter_free_task(struct task_struct *task);
extern void perf_counter_do_pending(void);
extern void perf_counter_print_debug(void);
extern void __perf_disable(void);
*/
static inline int is_software_counter(struct perf_counter *counter)
{
- return !perf_event_raw(&counter->hw_event) &&
- perf_event_type(&counter->hw_event) != PERF_TYPE_HARDWARE;
+ return !perf_event_raw(&counter->attr) &&
+ perf_event_type(&counter->attr) != PERF_TYPE_HARDWARE;
}
extern void perf_swcounter_event(u32, u64, int, struct pt_regs *, u64);
unsigned long pgoff, struct file *file);
extern void perf_counter_comm(struct task_struct *tsk);
+extern void perf_counter_fork(struct task_struct *tsk);
+
+extern void perf_counter_task_migration(struct task_struct *task, int cpu);
#define MAX_STACK_DEPTH 255
perf_counter_task_tick(struct task_struct *task, int cpu) { }
static inline int perf_counter_init_task(struct task_struct *child) { return 0; }
static inline void perf_counter_exit_task(struct task_struct *child) { }
+static inline void perf_counter_free_task(struct task_struct *task) { }
static inline void perf_counter_do_pending(void) { }
static inline void perf_counter_print_debug(void) { }
static inline void perf_disable(void) { }
unsigned long pgoff, struct file *file) { }
static inline void perf_counter_comm(struct task_struct *tsk) { }
+static inline void perf_counter_fork(struct task_struct *tsk) { }
static inline void perf_counter_init(void) { }
+static inline void perf_counter_task_migration(struct task_struct *task,
+ int cpu) { }
#endif
#endif /* __KERNEL__ */