Commit d93c4308 authored by Stéphane Eranian's avatar Stéphane Eranian Committed by David Mosberger

[PATCH] ia64: perfmon-2 fixes

 - remove PFM_FL_UNSECURE support because broken
 - remove instrumentation code for syswide ctx update (5% speedup)
 - integrated cleanups from John Levon
 - remove references to pmu_conf.ovfl_val from loops, use local variable
 - updated pfm_bad_permissions()
 - support reset values for non-counting pmds
 - serialization of PFM_RESTART
 - added support for restart_active in per-task mode
 - remove potential deadlock caused by calling pfm_overflow_handler()   from pfm_load_regs()
 - fix invalid check in perfmon_mckinley() for PMC13
parent 761552e7
This diff is collapsed.
...@@ -81,6 +81,8 @@ pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu ...@@ -81,6 +81,8 @@ pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu
*/ */
if (cnum == 13 && ((*val & 0x1) == 0UL) && ctx->ctx_fl_using_dbreg == 0) { if (cnum == 13 && ((*val & 0x1) == 0UL) && ctx->ctx_fl_using_dbreg == 0) {
DPRINT(("pmc[%d]=0x%lx has active pmc13.ta cleared, clearing ibr\n", cnum, *val));
/* don't mix debug with perfmon */ /* don't mix debug with perfmon */
if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL; if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
...@@ -98,6 +100,8 @@ pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu ...@@ -98,6 +100,8 @@ pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu
*/ */
if (cnum == 11 && ((*val >> 28)& 0x1) == 0 && ctx->ctx_fl_using_dbreg == 0) { if (cnum == 11 && ((*val >> 28)& 0x1) == 0 && ctx->ctx_fl_using_dbreg == 0) {
DPRINT(("pmc[%d]=0x%lx has active pmc11.pt cleared, clearing dbr\n", cnum, *val));
/* don't mix debug with perfmon */ /* don't mix debug with perfmon */
if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL; if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
......
...@@ -109,10 +109,20 @@ pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu ...@@ -109,10 +109,20 @@ pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu
if (ctx == NULL) return -EINVAL; if (ctx == NULL) return -EINVAL;
/* /*
* we must clear the debug registers if any pmc13.ena_dbrpX bit is enabled * we must clear the debug registers if pmc13 has a value which enable
* before they are written (fl_using_dbreg==0) to avoid picking up stale information. * memory pipeline event constraints. In this case we need to clear the
* the debug registers if they have not yet been accessed. This is required
* to avoid picking stale state.
* PMC13 is "active" if:
* one of the pmc13.cfg_dbrpXX field is different from 0x3
* AND
* at the corresponding pmc13.ena_dbrpXX is set.
*
* For now, we just check on cfg_dbrXX != 0x3.
*/ */
if (cnum == 13 && (*val & (0xfUL << 45)) && ctx->ctx_fl_using_dbreg == 0) { if (cnum == 13 && ((*val & 0x18181818UL) != 0x18181818UL) && ctx->ctx_fl_using_dbreg == 0) {
DPRINT(("pmc[%d]=0x%lx has active pmc13 settings, clearing dbr\n", cnum, *val));
/* don't mix debug with perfmon */ /* don't mix debug with perfmon */
if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL; if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
...@@ -128,7 +138,9 @@ pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu ...@@ -128,7 +138,9 @@ pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu
* we must clear the (instruction) debug registers if any pmc14.ibrpX bit is enabled * we must clear the (instruction) debug registers if any pmc14.ibrpX bit is enabled
* before they are (fl_using_dbreg==0) to avoid picking up stale information. * before they are (fl_using_dbreg==0) to avoid picking up stale information.
*/ */
if (cnum == 14 && ((*val & 0x2222) != 0x2222) && ctx->ctx_fl_using_dbreg == 0) { if (cnum == 14 && ((*val & 0x2222UL) != 0x2222UL) && ctx->ctx_fl_using_dbreg == 0) {
DPRINT(("pmc[%d]=0x%lx has active pmc14 settings, clearing ibr\n", cnum, *val));
/* don't mix debug with perfmon */ /* don't mix debug with perfmon */
if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL; if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
...@@ -170,7 +182,7 @@ pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu ...@@ -170,7 +182,7 @@ pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu
&& ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0) && ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0)
||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0)); ||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0));
if (ret) printk("perfmon: failure check_case1\n"); if (ret) DPRINT((KERN_DEBUG "perfmon: failure check_case1\n"));
} }
return ret ? -EINVAL : 0; return ret ? -EINVAL : 0;
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
*/ */
#define PFM_FL_NOTIFY_BLOCK 0x01 /* block task on user level notifications */ #define PFM_FL_NOTIFY_BLOCK 0x01 /* block task on user level notifications */
#define PFM_FL_SYSTEM_WIDE 0x02 /* create a system wide context */ #define PFM_FL_SYSTEM_WIDE 0x02 /* create a system wide context */
#define PFM_FL_UNSECURE 0x04 /* allow unsecure monitoring for non self-monitoring task */
#define PFM_FL_OVFL_NO_MSG 0x80 /* do not post overflow/end messages for notification */ #define PFM_FL_OVFL_NO_MSG 0x80 /* do not post overflow/end messages for notification */
/* /*
...@@ -162,8 +161,6 @@ typedef union { ...@@ -162,8 +161,6 @@ typedef union {
*/ */
#define PFM_VERSION_MAJ 2U #define PFM_VERSION_MAJ 2U
#define PFM_VERSION_MIN 0U #define PFM_VERSION_MIN 0U
#define PFM_SMPL_HDR_VERSION_MAJ 2U
#define PFM_SMPL_HDR_VERSION_MIN 0U
#define PFM_VERSION (((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff)) #define PFM_VERSION (((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff))
#define PFM_VERSION_MAJOR(x) (((x)>>16) & 0xffff) #define PFM_VERSION_MAJOR(x) (((x)>>16) & 0xffff)
#define PFM_VERSION_MINOR(x) ((x) & 0xffff) #define PFM_VERSION_MINOR(x) ((x) & 0xffff)
...@@ -194,9 +191,8 @@ extern void pfm_handle_work(void); ...@@ -194,9 +191,8 @@ extern void pfm_handle_work(void);
/* /*
* Reset PMD register flags * Reset PMD register flags
*/ */
#define PFM_PMD_NO_RESET 0 #define PFM_PMD_SHORT_RESET 0
#define PFM_PMD_LONG_RESET 1 #define PFM_PMD_LONG_RESET 1
#define PFM_PMD_SHORT_RESET 2
typedef union { typedef union {
unsigned int val; unsigned int val;
...@@ -223,7 +219,7 @@ typedef struct { ...@@ -223,7 +219,7 @@ typedef struct {
} pfm_ovfl_arg_t; } pfm_ovfl_arg_t;
typedef struct _pfm_buffer_fmt_t { typedef struct {
char *fmt_name; char *fmt_name;
pfm_uuid_t fmt_uuid; pfm_uuid_t fmt_uuid;
size_t fmt_arg_size; size_t fmt_arg_size;
...@@ -237,8 +233,7 @@ typedef struct _pfm_buffer_fmt_t { ...@@ -237,8 +233,7 @@ typedef struct _pfm_buffer_fmt_t {
int (*fmt_restart_active)(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs); int (*fmt_restart_active)(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs);
int (*fmt_exit)(struct task_struct *task, void *buf, struct pt_regs *regs); int (*fmt_exit)(struct task_struct *task, void *buf, struct pt_regs *regs);
struct _pfm_buffer_fmt_t *fmt_next; struct list_head fmt_list;
struct _pfm_buffer_fmt_t *fmt_prev;
} pfm_buffer_fmt_t; } pfm_buffer_fmt_t;
extern int pfm_register_buffer_fmt(pfm_buffer_fmt_t *fmt); extern int pfm_register_buffer_fmt(pfm_buffer_fmt_t *fmt);
......
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