[IA64] xenoprof ia64 xen side

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
This commit is contained in:
awilliam@xenbuild.aw committed 2006-11-28 21:35:13 -07:00
1 parent e5b50237ff
commit 2a615d53c7
17 files changed
+1327 -69

No files matched your search

+1
View File
@@ -3,6 +3,7 @@
HAS_ACPI := y
HAS_VGA := y
xenoprof := y
VALIDATE_VT ?= n
no_warns ?= n
xen_ia64_expose_p2m ?= y
+2
View File
@@ -18,3 +18,5 @@ obj-y += unwind.o
obj-y += iosapic.o
obj-y += numa.o
obj-y += mm_numa.o
obj-y += perfmon.o
obj-y += perfmon_default_smpl.o
File diff suppressed because it is too large. Load diff
@@ -16,9 +16,15 @@
#include <asm/perfmon.h>
#include <asm/perfmon_default_smpl.h>
#ifndef XEN
MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>");
MODULE_DESCRIPTION("perfmon default sampling format");
MODULE_LICENSE("GPL");
#endif
#ifdef XEN
#define pid vcpu_id
#endif
#define DEFAULT_DEBUG 1
@@ -157,7 +163,9 @@ default_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct
* system-wide:
* - this is not necessarily the task controlling the session
*/
#ifndef XEN
ent->pid = current->pid;
#endif
ent->ovfl_pmd = ovfl_pmd;
ent->last_reset_val = arg->pmd_last_reset; //pmd[0].reg_last_reset_val;
@@ -169,7 +177,9 @@ default_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct
ent->tstamp = stamp;
ent->cpu = smp_processor_id();
ent->set = arg->active_set;
#ifndef XEN
ent->tgid = current->tgid;
#endif
/*
* selectively store PMDs in increasing index number
@@ -263,6 +273,7 @@ static pfm_buffer_fmt_t default_fmt={
.fmt_exit = default_exit,
};
#ifndef XEN
static int __init
pfm_default_smpl_init_module(void)
{
@@ -282,6 +293,7 @@ pfm_default_smpl_init_module(void)
return ret;
}
#endif
static void __exit
pfm_default_smpl_cleanup_module(void)
@@ -292,6 +304,8 @@ pfm_default_smpl_cleanup_module(void)
printk("perfmon_default_smpl: unregister %s=%d\n", default_fmt.fmt_name, ret);
}
#ifndef XEN
module_init(pfm_default_smpl_init_module);
module_exit(pfm_default_smpl_cleanup_module);
#endif
+1
View File
@@ -22,6 +22,7 @@ obj-y += __divdi3.o
obj-y += __udivdi3.o
obj-y += __moddi3.o
obj-y += __umoddi3.o
obj-y += carta_random.o
## variants of divide/modulo
## see files in xen/arch/ia64/linux/lib (linux/arch/ia64/lib)
+2
View File
@@ -1,3 +1,5 @@
subdir-y += oprofile
obj-y += acpi.o
obj-y += dom0_ops.o
obj-y += domain.o
+6
View File
@@ -343,6 +343,12 @@ do_dom0vp_op(unsigned long cmd,
case IA64_DOM0VP_expose_p2m:
ret = dom0vp_expose_p2m(d, arg0, arg1, arg2, arg3);
break;
case IA64_DOM0VP_perfmon: {
XEN_GUEST_HANDLE(void) hnd;
set_xen_guest_handle(hnd, (void*)arg1);
ret = do_perfmon_op(arg0, hnd, arg2);
break;
}
default:
ret = -1;
printk("unknown dom0_vp_op 0x%lx\n", cmd);
+30 -2
View File
@@ -48,6 +48,7 @@
#include <asm/shadow.h>
#include <xen/guest_access.h>
#include <asm/tlb_track.h>
#include <asm/perfmon.h>
unsigned long dom0_size = 512*1024*1024;
@@ -231,11 +232,35 @@ void continue_running(struct vcpu *same)
/* nothing to do */
}
#ifdef CONFIG_PERFMON
static int pal_halt = 1;
static int can_do_pal_halt = 1;
static int __init nohalt_setup(char * str)
{
pal_halt = can_do_pal_halt = 0;
return 1;
}
__setup("nohalt", nohalt_setup);
void
update_pal_halt_status(int status)
{
can_do_pal_halt = pal_halt && status;
}
#else
#define can_do_pal_halt (1)
#endif
static void default_idle(void)
{
local_irq_disable();
if ( !softirq_pending(smp_processor_id()) )
safe_halt();
if ( !softirq_pending(smp_processor_id()) ) {
if (can_do_pal_halt)
safe_halt();
else
cpu_relax();
}
local_irq_enable();
}
@@ -628,6 +653,9 @@ void domain_relinquish_resources(struct domain *d)
if (d->arch.is_vti && d->arch.sal_data)
xfree(d->arch.sal_data);
/* Free page used by xen oprofile buffer */
free_xenoprof_pages(d);
}
unsigned long
+1 -1
View File
@@ -68,7 +68,7 @@ const hypercall_t ia64_hypercall_table[NR_hypercalls] =
(hypercall_t)do_ni_hypercall, /* do_nmi_op */
(hypercall_t)do_sched_op,
(hypercall_t)do_callback_op, /* */ /* 30 */
(hypercall_t)do_ni_hypercall, /* */
(hypercall_t)do_xenoprof_op, /* */
(hypercall_t)do_event_channel_op,
(hypercall_t)do_physdev_op,
(hypercall_t)do_hvm_op, /* */
+1
View File
@@ -0,0 +1 @@
obj-y += perfmon.o xenoprof.o
+165 -65
View File
@@ -1,3 +1,25 @@
/******************************************************************************
* perfmon.c for xenoprof
* This is based linux/arch/ia64/oprofile/perfmon.c, but heavily rewritten.
*
* Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/**
* @file perfmon.c
*
@@ -7,94 +29,172 @@
* @author John Levon <levon@movementarian.org>
*/
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/oprofile.h>
#include <linux/sched.h>
#include <xen/config.h>
#include <xen/sched.h>
#include <xen/event.h>
#include <xen/xenoprof.h>
#include <asm/perfmon.h>
#include <asm/ptrace.h>
#include <asm/errno.h>
// XXX move them to an appropriate header file
extern void xenoprof_log_event(struct vcpu *vcpu,
unsigned long eip, int mode, int event);
extern int is_active(struct domain *d);
static int allow_virq;
static int allow_ints;
static int
perfmon_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg,
struct pt_regs *regs, unsigned long stamp)
xenoprof_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg,
struct pt_regs *regs, unsigned long stamp)
{
int event = arg->pmd_eventid;
unsigned long ip = regs->cr_iip;
int event = arg->pmd_eventid;
arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1;
arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1;
if (!allow_virq || !allow_ints)
return 0;
/* the owner of the oprofile event buffer may have exited
* without perfmon being shutdown (e.g. SIGSEGV)
*/
if (allow_ints)
oprofile_add_sample(regs, event);
return 0;
xenoprof_log_event(current, ip, xenoprofile_get_mode(task, regs), event);
// send VIRQ_XENOPROF
if (is_active(current->domain) && !ring_0(regs))
send_guest_vcpu_virq(current, VIRQ_XENOPROF);
return 0;
}
// same as linux OPROFILE_FMT_UUID
#define XENOPROF_FMT_UUID { \
0x77, 0x7a, 0x6e, 0x61, 0x20, 0x65, 0x73, 0x69, 0x74, 0x6e, 0x72, 0x20, 0x61, 0x65, 0x0a, 0x6c }
static int perfmon_start(void)
static pfm_buffer_fmt_t xenoprof_fmt = {
.fmt_name = "xenoprof_format",
.fmt_uuid = XENOPROF_FMT_UUID,
.fmt_handler = xenoprof_handler,
};
static char * get_cpu_type(void)
{
__u8 family = local_cpu_data->family;
switch (family) {
case 0x07:
return "ia64/itanium";
case 0x1f:
return "ia64/itanium2";
default:
return "ia64/ia64";
}
}
static int using_xenoprof;
int __init
xenprof_perfmon_init(void)
{
int ret = pfm_register_buffer_fmt(&xenoprof_fmt);
if (ret)
return -ENODEV;
using_xenoprof = 1;
printk("xenoprof: using perfmon.\n");
return 0;
}
__initcall(xenprof_perfmon_init);
#ifdef notyet
void xenoprof_perfmon_exit(void)
{
if (!using_xenoprof)
return;
pfm_unregister_buffer_fmt(xenoprof_fmt.fmt_uuid);
}
__exitcall(xenoprof_perfmon_exit);
#endif
///////////////////////////////////////////////////////////////////////////
// glue methods for xenoprof and perfmon.
int
xenoprof_arch_init(int *num_events, int *is_primary, char *cpu_type)
{
*num_events = 0;
strncpy(cpu_type, get_cpu_type(), XENOPROF_CPU_TYPE_SIZE - 1);
cpu_type[XENOPROF_CPU_TYPE_SIZE - 1] = '\0';
*is_primary = 0;
if (xenoprof_primary_profiler == NULL) {
/* For now, only dom0 can be the primary profiler */
if (current->domain->domain_id == 0) {
*is_primary = 1;
}
} else if (xenoprof_primary_profiler == current->domain)
*is_primary = 1;
return 0;
}
int
xenoprof_arch_reserve_counters(void)
{
// perfmon takes care
return 0;
}
int
xenoprof_arch_counter(XEN_GUEST_HANDLE(void) arg)
{
return -ENOSYS;
}
int
xenoprof_arch_setup_events(void)
{
// perfmon takes care
return 0;
}
//XXX SMP: sync by IPI?
int
xenoprof_arch_enable_virq(void)
{
allow_virq = 1;
return 0;
}
//XXX SMP: sync by IPI?
int
xenoprof_arch_start(void)
{
allow_ints = 1;
return 0;
return 0;
}
static void perfmon_stop(void)
//XXX SMP: sync by IPI?
void
xenoprof_arch_stop(void)
{
allow_ints = 0;
}
#define OPROFILE_FMT_UUID { \
0x77, 0x7a, 0x6e, 0x61, 0x20, 0x65, 0x73, 0x69, 0x74, 0x6e, 0x72, 0x20, 0x61, 0x65, 0x0a, 0x6c }
static pfm_buffer_fmt_t oprofile_fmt = {
.fmt_name = "oprofile_format",
.fmt_uuid = OPROFILE_FMT_UUID,
.fmt_handler = perfmon_handler,
};
static char * get_cpu_type(void)
//XXX SMP: sync by IPI?
void
xenoprof_arch_disable_virq(void)
{
__u8 family = local_cpu_data->family;
switch (family) {
case 0x07:
return "ia64/itanium";
case 0x1f:
return "ia64/itanium2";
default:
return "ia64/ia64";
}
allow_virq = 0;
}
/* all the ops are handled via userspace for IA64 perfmon */
static int using_perfmon;
int perfmon_init(struct oprofile_operations * ops)
void
xenoprof_arch_release_counters(void)
{
int ret = pfm_register_buffer_fmt(&oprofile_fmt);
if (ret)
return -ENODEV;
ops->cpu_type = get_cpu_type();
ops->start = perfmon_start;
ops->stop = perfmon_stop;
using_perfmon = 1;
printk(KERN_INFO "oprofile: using perfmon.\n");
return 0;
// perfmon takes care
}
void perfmon_exit(void)
{
if (!using_perfmon)
return;
pfm_unregister_buffer_fmt(oprofile_fmt.fmt_uuid);
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+56
View File
@@ -0,0 +1,56 @@
/******************************************************************************
* xenoprof.c
*
* Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <xen/config.h>
#include <xen/sched.h>
#include <public/xen.h>
#include <xen/xenoprof.h>
int
xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs)
{
int mode = 0;
// mode
// 0: user, 1: kernel, 2: xen
// Xen/IA64 uses ring2 for kernel, and doesn't use ring1.
if (ring_2(regs))
mode = 1;
else if (ring_0(regs))
mode = 2;
else if (ring_1(regs)) {
gdprintk(XENLOG_ERR, "%s:%d ring1 is used!\n", __func__, __LINE__);
mode = 1;// fall back to kernel mode.
}
return mode;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+3
View File
@@ -125,6 +125,7 @@ extern char _end[]; /* standard ELF symbol */
// from include/asm-ia64/smp.h
#define get_cpu() smp_processor_id()
#define put_cpu() do {} while(0)
#define put_cpu_no_resched() do{} while (0)
// needed for common/dom0_ops.c until hyperthreading is supported
#ifdef CONFIG_SMP
@@ -166,6 +167,8 @@ extern int smp_num_siblings;
#define ____cacheline_aligned_in_smp ____cacheline_aligned
#endif
#define CONFIG_PERFMON
#ifndef __ASSEMBLY__
#include "asm/types.h" // for u64
#include "linux/linkage.h" // for asmlinkage which is used by
+4
View File
@@ -211,6 +211,10 @@ struct arch_vcpu {
#define IO_PORTS_PADDR 0x00000ffffc000000UL
#define IO_PORTS_SIZE 0x0000000004000000UL
int
do_perfmon_op(unsigned long cmd,
XEN_GUEST_HANDLE(void) arg1, unsigned long arg2);
#endif /* __ASM_DOMAIN_H__ */
/*
@@ -6,6 +6,14 @@
#ifndef _ASM_IA64_PERFMON_H
#define _ASM_IA64_PERFMON_H
#ifdef XEN
#include <asm/config.h>
#ifndef pt_regs
#define pt_regs cpu_user_regs
#endif
struct cpu_user_regs;
#endif
/*
* perfmon comamnds supported on all CPU models
*/
+64
View File
@@ -0,0 +1,64 @@
/******************************************************************************
* asm-ia64/xenoprof.h
* xenoprof ia64 arch specific header file
*
* Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __ASM_XENOPROF_H__
#define __ASM_XENOPROF_H__
int xenoprof_arch_init(int *num_events, int *is_primary, char *cpu_type);
int xenoprof_arch_reserve_counters(void);
int xenoprof_arch_counter(XEN_GUEST_HANDLE(void) arg);
int xenoprof_arch_setup_events(void);
int xenoprof_arch_enable_virq(void);
int xenoprof_arch_start(void);
void xenoprof_arch_stop(void);
void xenoprof_arch_disable_virq(void);
void xenoprof_arch_release_counters(void);
struct vcpu;
struct cpu_user_regs;
int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs);
#define xenoprof_shared_gmfn(d, gmaddr, maddr) \
assign_domain_page((d), (gmaddr), (maddr));
static inline int
ring(const struct pt_regs* regs)
{
return ((struct ia64_psr*)(&(regs)->cr_ipsr))->cpl;
}
#define ring_0(r) (ring(r) == 0)
#define ring_1(r) (ring(r) == 1)
#define ring_2(r) (ring(r) == 2)
#define ring_3(r) (ring(r) == 3)
#endif /* __ASM_XENOPROF_H__ */
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+22
View File
@@ -376,6 +376,9 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
/* expose the p2m table into domain */
#define IA64_DOM0VP_expose_p2m 7
/* xen perfmon */
#define IA64_DOM0VP_perfmon 8
// flags for page assignement to pseudo physical address space
#define _ASSIGN_readonly 0
#define ASSIGN_readonly (1UL << _ASSIGN_readonly)
@@ -462,6 +465,25 @@ struct xen_ia64_boot_param {
(((unsigned long)(addr) & XENCOMM_INLINE_MASK) == XENCOMM_INLINE_FLAG)
#define XENCOMM_INLINE_ADDR(addr) \
((unsigned long)(addr) & ~XENCOMM_INLINE_MASK)
/* xen perfmon */
#ifdef XEN
#ifndef __ASSEMBLY__
#ifndef _ASM_IA64_PERFMON_H
#include <xen/list.h> // asm/perfmon.h requires struct list_head
#include <asm/perfmon.h>
// for PFM_xxx and pfarg_features_t, pfarg_context_t, pfarg_reg_t, pfarg_load_t
#endif /* _ASM_IA64_PERFMON_H */
DEFINE_XEN_GUEST_HANDLE(pfarg_features_t);
DEFINE_XEN_GUEST_HANDLE(pfarg_context_t);
DEFINE_XEN_GUEST_HANDLE(pfarg_reg_t);
DEFINE_XEN_GUEST_HANDLE(pfarg_load_t);
#endif /* __ASSEMBLY__ */
#endif /* XEN */
#endif /* __HYPERVISOR_IF_IA64_H__ */
/*
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.