[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] Re: [Xen-changelog] [xen-unstable] Spinlock profiling (enable in buildwith lock_profile=y)



Hi,

I got the following error.

gcc  -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls -m32 -march
=i686 -g -fno-strict-aliasing -std=gnu99 -Wall -Wstrict-prototypes -Wno-
unused-value -Wdeclaration-after-statement  -D__XEN_TOOLS__ -MMD -MF .
xenlockprof.o.d -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -
D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -mno-tls-direct-seg-refs -
Werror -I ../../tools/python/xen/lowlevel/xc -I ../../tools/libxc -I ../..
/tools/include -c -o xenlockprof.o xenlockprof.c
cc1: warnings being treated as errors
xenlockprof.c: In function ‘main’:
xenlockprof.c:128: warning: format ‘%12ld’ expects type ‘long int’, 
but argument 3 has type ‘uint64_t’
xenlockprof.c:128: warning: format ‘%12ld’ expects type ‘long int’, 
but argument 5 has type ‘uint64_t’
make[4]: *** [xenlockprof.o] Error 1
make[4]: Leaving directory `/xen/xen-unstable.hg/tools/misc'
make[3]: *** [subdir-install-misc] Error 2
make[3]: Leaving directory `/xen/xen-unstable.hg/tools'
make[2]: *** [subdirs-install] Error 2
make[2]: Leaving directory `/xen/xen-unstable.hg/tools'
make[1]: *** [install-tools] Error 2
make[1]: Leaving directory `/xen/xen-unstable.hg'
make: *** [world] Error 2

Best regards,
 Kan

Wed, 14 Oct 2009 01:15:19 -0700, Xen patchbot-unstable wrote:

># HG changeset patch
># User Keir Fraser <keir.fraser@xxxxxxxxxx>
># Date 1255507671 -3600
># Node ID 10c0942ed2409b740f516b41781e6051e206c984
># Parent  71c859535c6bb7ba543ae3d483c830ca88cf4022
>Spinlock profiling (enable in build with lock_profile=y)
>
>Adds new tool xenlockprof to run from dom0.
>
>From: Juergen Gross <juergen.gross@xxxxxxxxxxxxxx>
>Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
>---
> tools/libxc/xc_misc.c       |   24 ++++
> tools/libxc/xenctrl.h       |    8 +
> tools/misc/Makefile         |    6 -
> tools/misc/xenlockprof.c    |  136 +++++++++++++++++++++++
> xen/Rules.mk                |    7 -
> xen/arch/x86/domain.c       |    2 
> xen/arch/x86/xen.lds.S      |    7 +
> xen/common/domain.c         |    7 -
> xen/common/keyhandler.c     |   20 +++
> xen/common/spinlock.c       |  258 +++++++++++++++++++++++++++++++++++++++
>+++++
> xen/common/sysctl.c         |   12 ++
> xen/include/public/sysctl.h |   35 +++++
> xen/include/xen/sched.h     |    2 
> xen/include/xen/spinlock.h  |   97 ++++++++++++++++
> 14 files changed, 609 insertions(+), 12 deletions(-)
>
>diff -r 71c859535c6b -r 10c0942ed240 tools/libxc/xc_misc.c
>--- a/tools/libxc/xc_misc.c    Wed Oct 14 08:58:47 2009 +0100
>+++ b/tools/libxc/xc_misc.c    Wed Oct 14 09:07:51 2009 +0100
>@@ -117,6 +117,30 @@ int xc_perfc_control(int xc_handle,
>         *nbr_desc = sysctl.u.perfc_op.nr_counters;
>     if ( nbr_val )
>         *nbr_val = sysctl.u.perfc_op.nr_vals;
>+
>+    return rc;
>+}
>+
>+int xc_lockprof_control(int xc_handle,
>+                        uint32_t opcode,
>+                        uint32_t *n_elems,
>+                        uint64_t *time,
>+                        xc_lockprof_data_t *data)
>+{
>+    int rc;
>+    DECLARE_SYSCTL;
>+
>+    sysctl.cmd = XEN_SYSCTL_lockprof_op;
>+    sysctl.u.lockprof_op.cmd = opcode;
>+    sysctl.u.lockprof_op.max_elem = n_elems ? *n_elems : 0;
>+    set_xen_guest_handle(sysctl.u.lockprof_op.data, data);
>+
>+    rc = do_sysctl(xc_handle, &sysctl);
>+
>+    if (n_elems)
>+        *n_elems = sysctl.u.lockprof_op.nr_elem;
>+    if (time)
>+        *time = sysctl.u.lockprof_op.time;
> 
>     return rc;
> }
>diff -r 71c859535c6b -r 10c0942ed240 tools/libxc/xenctrl.h
>--- a/tools/libxc/xenctrl.h    Wed Oct 14 08:58:47 2009 +0100
>+++ b/tools/libxc/xenctrl.h    Wed Oct 14 09:07:51 2009 +0100
>@@ -700,6 +700,14 @@ int xc_perfc_control(int xc_handle,
>                      int *nbr_desc,
>                      int *nbr_val);
> 
>+typedef xen_sysctl_lockprof_data_t xc_lockprof_data_t;
>+/* IMPORTANT: The caller is responsible for mlock()'ing the @data array. */
>+int xc_lockprof_control(int xc_handle,
>+                        uint32_t opcode,
>+                        uint32_t *n_elems,
>+                        uint64_t *time,
>+                        xc_lockprof_data_t *data);
>+
> /**
>  * Memory maps a range within one domain to a local address range.  Mappings
>  * should be unmapped with munmap and should follow the same rules as mmap
>diff -r 71c859535c6b -r 10c0942ed240 tools/misc/Makefile
>--- a/tools/misc/Makefile      Wed Oct 14 08:58:47 2009 +0100
>+++ b/tools/misc/Makefile      Wed Oct 14 09:07:51 2009 +0100
>@@ -10,7 +10,7 @@ CFLAGS   += $(INCLUDES)
> 
> HDRS     = $(wildcard *.h)
> 
>-TARGETS-y := xenperf xenpm xen-tmem-list-parse gtraceview gtracestat
>+TARGETS-y := xenperf xenpm xen-tmem-list-parse gtraceview gtracestat 
>xenlockprof
> TARGETS-$(CONFIG_X86) += xen-detect xen-hvmctx
> TARGETS := $(TARGETS-y)
> 
>@@ -22,7 +22,7 @@ INSTALL_BIN-$(CONFIG_X86) += xen-detect
> INSTALL_BIN-$(CONFIG_X86) += xen-detect
> INSTALL_BIN := $(INSTALL_BIN-y)
> 
>-INSTALL_SBIN-y := xm xen-bugtool xen-python-path xend xenperf xsview xenpm
> xen-tmem-list-parse gtraceview gtracestat
>+INSTALL_SBIN-y := xm xen-bugtool xen-python-path xend xenperf xsview xenpm
> xen-tmem-list-parse gtraceview gtracestat xenlockprof
> INSTALL_SBIN-$(CONFIG_X86) += xen-hvmctx
> INSTALL_SBIN := $(INSTALL_SBIN-y)
> 
>@@ -49,7 +49,7 @@ clean:
> %.o: %.c $(HDRS) Makefile
>       $(CC) -c $(CFLAGS) -o $@ $<
> 
>-xen-hvmctx xenperf xenpm gtracestat: %: %.o Makefile
>+xen-hvmctx xenperf xenpm gtracestat xenlockprof: %: %.o Makefile
>       $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LDFLAGS_libxenctrl)
> 
> gtraceview: %: %.o Makefile
>diff -r 71c859535c6b -r 10c0942ed240 tools/misc/xenlockprof.c
>--- /dev/null  Thu Jan 01 00:00:00 1970 +0000
>+++ b/tools/misc/xenlockprof.c Wed Oct 14 09:07:51 2009 +0100
>@@ -0,0 +1,136 @@
>+/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
>+ *************************************************************************
>***
>+ * (C) 2009 - Juergen Gross - Fujitsu Technology Solutions
>+ *************************************************************************
>***
>+ *
>+ *        File: xenlockprof.c
>+ *      Author: Juergen Gross (juergen.gross@xxxxxxxxxxxxxx)
>+ *        Date: Oct 2009
>+ * 
>+ * Description: 
>+ */
>+
>+#include <xenctrl.h>
>+#include <stdio.h>
>+#include <stdlib.h>
>+#include <sys/mman.h>
>+#include <errno.h>
>+#include <string.h>
>+
>+static int lock_pages(void *addr, size_t len)
>+{
>+    int e = 0;
>+#ifndef __sun__
>+    e = mlock(addr, len);
>+#endif
>+    return (e);
>+}
>+
>+static void unlock_pages(void *addr, size_t len)
>+{
>+#ifndef __sun__
>+    munlock(addr, len);
>+#endif
>+}
>+
>+int main(int argc, char *argv[])
>+{
>+    int                xc_handle;
>+    uint32_t           i, j, n;
>+    uint64_t           time;
>+    double             l, b, sl, sb;
>+    char               name[60];
>+    xc_lockprof_data_t *data;
>+
>+    if ((argc > 2) || ((argc == 2) && (strcmp(argv[1], "-r") != 0)))
>+    {
>+        printf("%s: [-r]\n", argv[0]);
>+        printf("no args: print lock profile data\n");
>+        printf("    -r : reset profile data\n");
>+        return 1;
>+    }
>+
>+    if ((xc_handle = xc_interface_open()) == -1)
>+    {
>+        fprintf(stderr, "Error opening xc interface: %d (%s)\n",
>+                errno, strerror(errno));
>+        return 1;
>+    }
>+
>+    if (argc > 1)
>+    {
>+        if (xc_lockprof_control(xc_handle, XEN_SYSCTL_LOCKPROF_reset, NULL,
>+                                NULL, NULL) != 0)
>+        {
>+            fprintf(stderr, "Error reseting profile data: %d (%s)\n",
>+                    errno, strerror(errno));
>+            return 1;
>+        }
>+        return 1;
>+    }
>+
>+    n = 0;
>+    if (xc_lockprof_control(xc_handle, XEN_SYSCTL_LOCKPROF_query, &n,
>+                            NULL, NULL) != 0)
>+    {
>+        fprintf(stderr, "Error getting number of profile records: %d (%s)\
>n",
>+                errno, strerror(errno));
>+        return 1;
>+    }
>+
>+    n += 32;    /* just to be sure */
>+    data = malloc(sizeof(*data) * n);
>+    if ((data == NULL) || (lock_pages(data, sizeof(*data) * n) != 0))
>+    {
>+        fprintf(stderr, "Could not alloc or lock buffers: %d (%s)\n",
>+                errno, strerror(errno));
>+        return 1;
>+    }
>+
>+    i = n;
>+    if ( xc_lockprof_control(xc_handle, XEN_SYSCTL_LOCKPROF_query, &i,
>+                             &time, data) != 0)
>+    {
>+        fprintf(stderr, "Error getting profile records: %d (%s)\n",
>+                errno, strerror(errno));
>+        return 1;
>+    }
>+
>+    unlock_pages(data, sizeof(*data) * n);
>+
>+    if (i > n)
>+    {
>+        printf("data incomplete, %d records are missing!\n\n", i - n);
>+        i = n;
>+    }
>+    sl = 0;
>+    sb = 0;
>+    for (j = 0; j < i; j++)
>+    {
>+        switch (data[j].type)
>+        {
>+        case LOCKPROF_TYPE_GLOBAL:
>+            sprintf(name, "global lock %s", data[j].name);
>+            break;
>+        case LOCKPROF_TYPE_PERDOM:
>+            sprintf(name, "domain %d lock %s", data[j].idx, data[j].name);
>+            break;
>+        default:
>+            sprintf(name, "unknown type(%d) %d lock %s", data[j].type,
>+                data[j].idx, data[j].name);
>+            break;
>+        }
>+        l = (double)(data[j].lock_time) / 1E+09;
>+        b = (double)(data[j].block_time) / 1E+09;
>+        sl += l;
>+        sb += b;
>+        printf("%-50s: lock:%12ld(%20.9fs), block:%12ld(%20.9fs)\n",
>+            name, data[j].lock_cnt, l, data[j].block_cnt, b);
>+    }
>+    l = (double)time / 1E+09;
>+    printf("total profiling time: %20.9fs\n", l);
>+    printf("total locked time:    %20.9fs\n", sl);
>+    printf("total blocked time:   %20.9fs\n", sb);
>+
>+    return 0;
>+}
>diff -r 71c859535c6b -r 10c0942ed240 xen/Rules.mk
>--- a/xen/Rules.mk     Wed Oct 14 08:58:47 2009 +0100
>+++ b/xen/Rules.mk     Wed Oct 14 09:07:51 2009 +0100
>@@ -6,6 +6,7 @@ verbose       ?= n
> verbose       ?= n
> perfc         ?= n
> perfc_arrays  ?= n
>+lock_profile  ?= n
> crash_debug   ?= n
> frame_pointer ?= n
> 
>@@ -52,17 +53,15 @@ CFLAGS-$(crash_debug)   += -DCRASH_DEBUG
> CFLAGS-$(crash_debug)   += -DCRASH_DEBUG
> CFLAGS-$(perfc)         += -DPERF_COUNTERS
> CFLAGS-$(perfc_arrays)  += -DPERF_ARRAYS
>+CFLAGS-$(lock_profile)  += -DLOCK_PROFILE
> CFLAGS-$(frame_pointer) += -fno-omit-frame-pointer -DCONFIG_FRAME_POINTER
>+CFLAGS-$(privileged_stubdoms) += -DPRIVILEGED_STUBDOMS
> 
> ifneq ($(max_phys_cpus),)
> CFLAGS-y                += -DMAX_PHYS_CPUS=$(max_phys_cpus)
> endif
> ifneq ($(max_phys_irqs),)
> CFLAGS-y                += -DMAX_PHYS_IRQS=$(max_phys_irqs)
>-endif
>-
>-ifeq ($(privileged_stubdoms),y)
>-CFLAGS += -DPRIVILEGED_STUBDOMS
> endif
> 
> AFLAGS-y                += -D__ASSEMBLY__
>diff -r 71c859535c6b -r 10c0942ed240 xen/arch/x86/domain.c
>--- a/xen/arch/x86/domain.c    Wed Oct 14 08:58:47 2009 +0100
>+++ b/xen/arch/x86/domain.c    Wed Oct 14 09:07:51 2009 +0100
>@@ -32,6 +32,7 @@
> #include <xen/acpi.h>
> #include <xen/pci.h>
> #include <xen/paging.h>
>+#include <public/sysctl.h>
> #include <asm/regs.h>
> #include <asm/mc146818rtc.h>
> #include <asm/system.h>
>@@ -185,6 +186,7 @@ struct domain *alloc_domain_struct(void)
> 
> void free_domain_struct(struct domain *d)
> {
>+    lock_profile_deregister_struct(LOCKPROF_TYPE_PERDOM, d);
>     free_xenheap_pages(d, get_order_from_bytes(sizeof(*d)));
> }
> 
>diff -r 71c859535c6b -r 10c0942ed240 xen/arch/x86/xen.lds.S
>--- a/xen/arch/x86/xen.lds.S   Wed Oct 14 08:58:47 2009 +0100
>+++ b/xen/arch/x86/xen.lds.S   Wed Oct 14 09:07:51 2009 +0100
>@@ -61,6 +61,13 @@ SECTIONS
>   .data.read_mostly : {
>        *(.data.read_mostly)
>   } :text
>+
>+#ifdef LOCK_PROFILE
>+  . = ALIGN(32);
>+  __lock_profile_start = .;
>+  .lockprofile.data : { *(.lockprofile.data) } :text
>+  __lock_profile_end = .;
>+#endif
> 
>   . = ALIGN(4096);             /* Init code and data */
>   __init_begin = .;
>diff -r 71c859535c6b -r 10c0942ed240 xen/common/domain.c
>--- a/xen/common/domain.c      Wed Oct 14 08:58:47 2009 +0100
>+++ b/xen/common/domain.c      Wed Oct 14 09:07:51 2009 +0100
>@@ -29,6 +29,7 @@
> #include <acpi/cpufreq/cpufreq.h>
> #include <asm/debugger.h>
> #include <public/sched.h>
>+#include <public/sysctl.h>
> #include <public/vcpu.h>
> #include <xsm/xsm.h>
> #include <xen/trace.h>
>@@ -221,13 +222,15 @@ struct domain *domain_create(
>     memset(d, 0, sizeof(*d));
>     d->domain_id = domid;
> 
>+    lock_profile_register_struct(LOCKPROF_TYPE_PERDOM, d, domid, "Domain");
>+
>     if ( xsm_alloc_security_domain(d) != 0 )
>         goto fail;
>     init_status |= INIT_xsm;
> 
>     atomic_set(&d->refcnt, 1);
>-    spin_lock_init(&d->domain_lock);
>-    spin_lock_init(&d->page_alloc_lock);
>+    spin_lock_init_prof(d, domain_lock);
>+    spin_lock_init_prof(d, page_alloc_lock);
>     spin_lock_init(&d->shutdown_lock);
>     spin_lock_init(&d->hypercall_deadlock_mutex);
>     INIT_PAGE_LIST_HEAD(&d->page_list);
>diff -r 71c859535c6b -r 10c0942ed240 xen/common/keyhandler.c
>--- a/xen/common/keyhandler.c  Wed Oct 14 08:58:47 2009 +0100
>+++ b/xen/common/keyhandler.c  Wed Oct 14 09:07:51 2009 +0100
>@@ -347,6 +347,20 @@ static struct keyhandler perfc_reset_key
> };
> #endif
> 
>+#ifdef LOCK_PROFILE
>+extern void spinlock_profile_printall(unsigned char key);
>+static struct keyhandler spinlock_printall_keyhandler = {
>+    .diagnostic = 1,
>+    .u.fn = spinlock_profile_printall,
>+    .desc = "print lock profile info"
>+};
>+extern void spinlock_profile_reset(unsigned char key);
>+static struct keyhandler spinlock_reset_keyhandler = {
>+    .u.fn = spinlock_profile_reset,
>+    .desc = "reset lock profile info"
>+};
>+#endif
>+
> static void run_all_nonirq_keyhandlers(unsigned long unused)
> {
>     /* Fire all the non-IRQ-context diagnostic keyhandlers */
>@@ -428,6 +442,12 @@ void __init initialize_keytable(void)
>     register_keyhandler('p', &perfc_printall_keyhandler);
>     register_keyhandler('P', &perfc_reset_keyhandler);
> #endif
>+
>+#ifdef LOCK_PROFILE
>+    register_keyhandler('l', &spinlock_printall_keyhandler);
>+    register_keyhandler('L', &spinlock_reset_keyhandler);
>+#endif
>+
> }
> 
> /*
>diff -r 71c859535c6b -r 10c0942ed240 xen/common/spinlock.c
>--- a/xen/common/spinlock.c    Wed Oct 14 08:58:47 2009 +0100
>+++ b/xen/common/spinlock.c    Wed Oct 14 09:07:51 2009 +0100
>@@ -1,7 +1,11 @@
>+#include <xen/lib.h>
> #include <xen/config.h>
> #include <xen/irq.h>
> #include <xen/smp.h>
>+#include <xen/time.h>
> #include <xen/spinlock.h>
>+#include <xen/guest_access.h>
>+#include <public/sysctl.h>
> #include <asm/processor.h>
> 
> #ifndef NDEBUG
>@@ -41,56 +45,97 @@ void spin_debug_disable(void)
> 
> #endif
> 
>+#ifdef LOCK_PROFILE
>+
>+#define LOCK_PROFILE_REL                                               \
>+    lock->profile.time_hold += NOW() - lock->profile.time_locked;      \
>+    lock->profile.lock_cnt++;
>+#define LOCK_PROFILE_VAR    s_time_t block = 0
>+#define LOCK_PROFILE_BLOCK  block = block ? : NOW();
>+#define LOCK_PROFILE_GOT                                               \
>+    lock->profile.time_locked = NOW();                                 \
>+    if (block)                                                         \
>+    {                                                                  \
>+        lock->profile.time_block += lock->profile.time_locked - block; \
>+        lock->profile.block_cnt++;                                     \
>+    }
>+
>+#else
>+
>+#define LOCK_PROFILE_REL
>+#define LOCK_PROFILE_VAR
>+#define LOCK_PROFILE_BLOCK
>+#define LOCK_PROFILE_GOT
>+
>+#endif
>+
> void _spin_lock(spinlock_t *lock)
> {
>+    LOCK_PROFILE_VAR;
>+
>     check_lock(&lock->debug);
>     while ( unlikely(!_raw_spin_trylock(&lock->raw)) )
>+    {
>+        LOCK_PROFILE_BLOCK;
>         while ( likely(_raw_spin_is_locked(&lock->raw)) )
>             cpu_relax();
>+    }
>+    LOCK_PROFILE_GOT;
> }
> 
> void _spin_lock_irq(spinlock_t *lock)
> {
>+    LOCK_PROFILE_VAR;
>+
>     ASSERT(local_irq_is_enabled());
>     local_irq_disable();
>     check_lock(&lock->debug);
>     while ( unlikely(!_raw_spin_trylock(&lock->raw)) )
>     {
>+        LOCK_PROFILE_BLOCK;
>         local_irq_enable();
>         while ( likely(_raw_spin_is_locked(&lock->raw)) )
>             cpu_relax();
>         local_irq_disable();
>     }
>+    LOCK_PROFILE_GOT;
> }
> 
> unsigned long _spin_lock_irqsave(spinlock_t *lock)
> {
>     unsigned long flags;
>+    LOCK_PROFILE_VAR;
>+
>     local_irq_save(flags);
>     check_lock(&lock->debug);
>     while ( unlikely(!_raw_spin_trylock(&lock->raw)) )
>     {
>+        LOCK_PROFILE_BLOCK;
>         local_irq_restore(flags);
>         while ( likely(_raw_spin_is_locked(&lock->raw)) )
>             cpu_relax();
>         local_irq_save(flags);
>     }
>+    LOCK_PROFILE_GOT;
>     return flags;
> }
> 
> void _spin_unlock(spinlock_t *lock)
> {
>+    LOCK_PROFILE_REL;
>     _raw_spin_unlock(&lock->raw);
> }
> 
> void _spin_unlock_irq(spinlock_t *lock)
> {
>+    LOCK_PROFILE_REL;
>     _raw_spin_unlock(&lock->raw);
>     local_irq_enable();
> }
> 
> void _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
> {
>+    LOCK_PROFILE_REL;
>     _raw_spin_unlock(&lock->raw);
>     local_irq_restore(flags);
> }
>@@ -104,13 +149,32 @@ int _spin_trylock(spinlock_t *lock)
> int _spin_trylock(spinlock_t *lock)
> {
>     check_lock(&lock->debug);
>+#ifndef LOCK_PROFILE
>     return _raw_spin_trylock(&lock->raw);
>+#else
>+    if (!_raw_spin_trylock(&lock->raw)) return 0;
>+    lock->profile.time_locked = NOW();
>+    return 1;
>+#endif
> }
> 
> void _spin_barrier(spinlock_t *lock)
> {
>+#ifdef LOCK_PROFILE
>+    s_time_t block = NOW();
>+    u64      loop = 0;
>+
>+    check_lock(&lock->debug);
>+    do { mb(); loop++;} while ( _raw_spin_is_locked(&lock->raw) );
>+    if (loop > 1)
>+    {
>+        lock->profile.time_block += NOW() - block;
>+        lock->profile.block_cnt++;
>+    }
>+#else
>     check_lock(&lock->debug);
>     do { mb(); } while ( _raw_spin_is_locked(&lock->raw) );
>+#endif
>     mb();
> }
> 
>@@ -248,3 +312,197 @@ int _rw_is_write_locked(rwlock_t *lock)
>     check_lock(&lock->debug);
>     return _raw_rw_is_write_locked(&lock->raw);
> }
>+
>+#ifdef LOCK_PROFILE
>+struct lock_profile_anc {
>+    struct lock_profile_qhead *head_q;   /* first head of this type */
>+    char                      *name;     /* descriptive string for print */
>+};
>+
>+typedef void lock_profile_subfunc(struct lock_profile *, int32_t, int32_t,
>+                                  void *);
>+
>+extern struct lock_profile *__lock_profile_start;
>+extern struct lock_profile *__lock_profile_end;
>+
>+static s_time_t lock_profile_start = 0;
>+static struct lock_profile_anc lock_profile_ancs[LOCKPROF_TYPE_N];
>+static struct lock_profile_qhead lock_profile_glb_q;
>+static spinlock_t lock_profile_lock = SPIN_LOCK_UNLOCKED;
>+
>+static void spinlock_profile_iterate(lock_profile_subfunc *sub, void *par)
>+{
>+    int  i;
>+    struct lock_profile_qhead *hq;
>+    struct lock_profile *eq;
>+
>+    spin_lock(&lock_profile_lock);
>+    for (i = 0; i < LOCKPROF_TYPE_N; i++)
>+    {
>+        for (hq = lock_profile_ancs[i].head_q; hq; hq = hq->head_q)
>+        {
>+            for (eq = hq->elem_q; eq; eq = eq->next)
>+            {
>+                sub(eq, i, hq->idx, par);
>+            }
>+        }
>+    }
>+    spin_unlock(&lock_profile_lock);
>+    return;
>+}
>+
>+static void spinlock_profile_print_elem(struct lock_profile *data,
>+    int32_t type, int32_t idx, void *par)
>+{
>+    if (type == LOCKPROF_TYPE_GLOBAL)
>+        printk("%s %s:\n", lock_profile_ancs[idx].name, data->name);
>+    else
>+        printk("%s %d %s:\n", lock_profile_ancs[idx].name, idx, data->name);
>+    printk("  lock:%12ld(%08X:%08X), block:%12ld(%08X:%08X)\n",
>+        data->lock_cnt, (u32)(data->time_hold >> 32), (u32)data->time_hold,
>+        data->block_cnt, (u32)(data->time_block >> 32), (u32)data->
>time_block);
>+    return;
>+}
>+
>+void spinlock_profile_printall(unsigned char key)
>+{
>+    s_time_t now = NOW();
>+    s_time_t diff;
>+
>+    diff = now - lock_profile_start;
>+    printk("Xen lock profile info SHOW  (now = %08X:%08X, "
>+        "total = %08X:%08X)\n", (u32)(now>>32), (u32)now,
>+        (u32)(diff>>32), (u32)diff);
>+    spinlock_profile_iterate(spinlock_profile_print_elem, NULL);
>+    return;
>+}
>+
>+static void spinlock_profile_reset_elem(struct lock_profile *data,
>+    int32_t type, int32_t idx, void *par)
>+{
>+    data->lock_cnt = 0;
>+    data->block_cnt = 0;
>+    data->time_hold = 0;
>+    data->time_block = 0;
>+    return;
>+}
>+
>+void spinlock_profile_reset(unsigned char key)
>+{
>+    s_time_t now = NOW();
>+
>+    if ( key != '\0' )
>+        printk("Xen lock profile info RESET (now = %08X:%08X)\n",
>+            (u32)(now>>32), (u32)now);
>+    lock_profile_start = now;
>+    spinlock_profile_iterate(spinlock_profile_reset_elem, NULL);
>+    return;
>+}
>+
>+typedef struct {
>+    xen_sysctl_lockprof_op_t *pc;
>+    int                      rc;
>+} spinlock_profile_ucopy_t;
>+
>+static void spinlock_profile_ucopy_elem(struct lock_profile *data,
>+    int32_t type, int32_t idx, void *par)
>+{
>+    spinlock_profile_ucopy_t *p;
>+    xen_sysctl_lockprof_data_t elem;
>+
>+    p = (spinlock_profile_ucopy_t *)par;
>+    if (p->rc)
>+        return;
>+
>+    if (p->pc->nr_elem < p->pc->max_elem)
>+    {
>+        safe_strcpy(elem.name, data->name);
>+        elem.type = type;
>+        elem.idx = idx;
>+        elem.lock_cnt = data->lock_cnt;
>+        elem.block_cnt = data->block_cnt;
>+        elem.lock_time = data->time_hold;
>+        elem.block_time = data->time_block;
>+        if (copy_to_guest_offset(p->pc->data, p->pc->nr_elem, &elem, 1))
>+        {
>+            p->rc = -EFAULT;
>+            return;
>+        }
>+    }
>+    p->pc->nr_elem++;
>+    
>+    return;
>+}
>+
>+/* Dom0 control of lock profiling */
>+int spinlock_profile_control(xen_sysctl_lockprof_op_t *pc)
>+{
>+    int rc;
>+    spinlock_profile_ucopy_t par;
>+
>+    rc = 0;
>+    switch (pc->cmd)
>+    {
>+    case XEN_SYSCTL_LOCKPROF_reset:
>+        spinlock_profile_reset('\0');
>+        break;
>+    case XEN_SYSCTL_LOCKPROF_query:
>+      pc->nr_elem = 0;
>+      par.rc = 0;
>+      par.pc = pc;
>+        spinlock_profile_iterate(spinlock_profile_ucopy_elem, &par);
>+        pc->time = NOW() - lock_profile_start;
>+      rc = par.rc;
>+        break;
>+    default:
>+        rc = -EINVAL;
>+        break;
>+    }
>+    return rc;
>+}
>+
>+void _lock_profile_register_struct(int32_t type,
>+    struct lock_profile_qhead *qhead, int32_t idx, char *name)
>+{
>+    qhead->idx = idx;
>+    spin_lock(&lock_profile_lock);
>+    qhead->head_q = lock_profile_ancs[type].head_q;
>+    lock_profile_ancs[type].head_q = qhead;
>+    lock_profile_ancs[type].name = name;
>+    spin_unlock(&lock_profile_lock);
>+    return;
>+}
>+
>+void _lock_profile_deregister_struct(int32_t type,
>+    struct lock_profile_qhead *qhead)
>+{
>+    struct lock_profile_qhead **q;
>+
>+    spin_lock(&lock_profile_lock);
>+    for (q = &lock_profile_ancs[type].head_q; *q; q = &((*q)->head_q))
>+    {
>+        if (*q == qhead)
>+        {
>+            *q = qhead->head_q;
>+            break;
>+        }
>+    }
>+    spin_unlock(&lock_profile_lock);
>+    return;
>+}
>+
>+static int __init lock_prof_init(void)
>+{
>+    struct lock_profile **q;
>+
>+    for (q = &__lock_profile_start; q < &__lock_profile_end; q++)
>+    {
>+        (*q)->next = lock_profile_glb_q.elem_q;
>+      lock_profile_glb_q.elem_q = *q;
>+    }
>+    _lock_profile_register_struct(LOCKPROF_TYPE_GLOBAL, &lock_profile_glb_q,
>+        0, "Global lock");
>+    return 0;
>+}
>+__initcall(lock_prof_init);
>+#endif
>diff -r 71c859535c6b -r 10c0942ed240 xen/common/sysctl.c
>--- a/xen/common/sysctl.c      Wed Oct 14 08:58:47 2009 +0100
>+++ b/xen/common/sysctl.c      Wed Oct 14 09:07:51 2009 +0100
>@@ -29,6 +29,9 @@
> 
> extern long arch_do_sysctl(
>     struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
>+#ifdef LOCK_PROFILE
>+extern int spinlock_profile_control(xen_sysctl_lockprof_op_t *pc);
>+#endif
> 
> long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
> {
>@@ -144,6 +147,15 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
>     break;
> #endif
> 
>+#ifdef LOCK_PROFILE
>+    case XEN_SYSCTL_lockprof_op:
>+    {
>+        ret = spinlock_profile_control(&op->u.lockprof_op);
>+        if ( copy_to_guest(u_sysctl, op, 1) )
>+            ret = -EFAULT;
>+    }
>+    break;
>+#endif
>     case XEN_SYSCTL_debug_keys:
>     {
>         char c;
>diff -r 71c859535c6b -r 10c0942ed240 xen/include/public/sysctl.h
>--- a/xen/include/public/sysctl.h      Wed Oct 14 08:58:47 2009 +0100
>+++ b/xen/include/public/sysctl.h      Wed Oct 14 09:07:51 2009 +0100
>@@ -396,7 +396,7 @@ struct xen_sysctl_pm_op {
>         struct xen_get_cpufreq_para get_para;
>         struct xen_set_cpufreq_gov  set_gov;
>         struct xen_set_cpufreq_para set_para;
>-        uint64_t get_avgfreq;
>+        uint64_aligned_t get_avgfreq;
>         struct xen_get_cputopo      get_topo;
>         uint32_t                    set_sched_opt_smt;
>         uint32_t                    get_max_cstate;
>@@ -453,6 +453,38 @@ struct xen_sysctl_page_offline_op {
> #define PG_ONLINE_BROKEN     PG_OFFLINE_BROKEN
> 
> #define PG_OFFLINE_OWNER_SHIFT 16
>+
>+#define XEN_SYSCTL_lockprof_op       11
>+/* Sub-operations: */
>+#define XEN_SYSCTL_LOCKPROF_reset 1   /* Reset all profile data to zero. */
>+#define XEN_SYSCTL_LOCKPROF_query 2   /* Get lock profile information. */
>+/* Record-type: */
>+#define LOCKPROF_TYPE_GLOBAL      0   /* global lock, idx meaningless */
>+#define LOCKPROF_TYPE_PERDOM      1   /* per-domain lock, idx is domid */
>+#define LOCKPROF_TYPE_N           2   /* number of types */
>+struct xen_sysctl_lockprof_data {
>+    char     name[40];     /* lock name (may include up to 2 %d specifiers
>) */
>+    int32_t  type;         /* LOCKPROF_TYPE_??? */
>+    int32_t  idx;          /* index (e.g. domain id) */
>+    uint64_aligned_t lock_cnt;     /* # of locking succeeded */
>+    uint64_aligned_t block_cnt;    /* # of wait for lock */
>+    uint64_aligned_t lock_time;    /* nsecs lock held */
>+    uint64_aligned_t block_time;   /* nsecs waited for lock */
>+};
>+typedef struct xen_sysctl_lockprof_data xen_sysctl_lockprof_data_t;
>+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_lockprof_data_t);
>+struct xen_sysctl_lockprof_op {
>+    /* IN variables. */
>+    uint32_t       cmd;               /* XEN_SYSCTL_LOCKPROF_??? */
>+    uint32_t       max_elem;          /* size of output buffer */
>+    /* OUT variables (query only). */
>+    uint32_t       nr_elem;           /* number of elements available */
>+    uint64_aligned_t time;            /* nsecs of profile measurement */
>+    /* profile information (or NULL) */
>+    XEN_GUEST_HANDLE_64(xen_sysctl_lockprof_data_t) data;
>+};
>+typedef struct xen_sysctl_lockprof_op xen_sysctl_lockprof_op_t;
>+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_lockprof_op_t);
> 
> struct xen_sysctl {
>     uint32_t cmd;
>@@ -471,6 +503,7 @@ struct xen_sysctl {
>         struct xen_sysctl_cpu_hotplug       cpu_hotplug;
>         struct xen_sysctl_pm_op             pm_op;
>         struct xen_sysctl_page_offline_op   page_offline;
>+        struct xen_sysctl_lockprof_op       lockprof_op;
>         uint8_t                             pad[128];
>     } u;
> };
>diff -r 71c859535c6b -r 10c0942ed240 xen/include/xen/sched.h
>--- a/xen/include/xen/sched.h  Wed Oct 14 08:58:47 2009 +0100
>+++ b/xen/include/xen/sched.h  Wed Oct 14 09:07:51 2009 +0100
>@@ -276,6 +276,8 @@ struct domain
> 
>     /* transcendent memory, auto-allocated on first tmem op by each domain
> */
>     void *tmem;
>+
>+    struct lock_profile_qhead profile_head;
> };
> 
> struct domain_setup_info
>diff -r 71c859535c6b -r 10c0942ed240 xen/include/xen/spinlock.h
>--- a/xen/include/xen/spinlock.h       Wed Oct 14 08:58:47 2009 +0100
>+++ b/xen/include/xen/spinlock.h       Wed Oct 14 09:07:51 2009 +0100
>@@ -19,16 +19,109 @@ struct lock_debug { };
> #define spin_debug_disable() ((void)0)
> #endif
> 
>+#ifdef LOCK_PROFILE
>+/*
>+    lock profiling on:
>+
>+    Global locks which should be subject to profiling must be declared via
>+    DEFINE_SPINLOCK.
>+
>+    For locks in structures further measures are necessary:
>+    - the structure definition must include a profile_head with exactly this
>+      name:
>+
>+      struct lock_profile_qhead   profile_head;
>+
>+    - the single locks which are subject to profiling have to be initialized
>+      via
>+
>+      spin_lock_init_prof(ptr, lock);
>+
>+      with ptr being the main structure pointer and lock the spinlock field
>+
>+    - each structure has to be added to profiling with
>+
>+      lock_profile_register_struct(type, ptr, idx, print);
>+
>+      with:
>+        type:  something like LOCKPROF_TYPE_PERDOM
>+        ptr:   pointer to the structure
>+        idx:   index of that structure, e.g. domid
>+        print: descriptive string like "domain"
>+
>+    - removing of a structure is done via
>+
>+      lock_profile_deregister_struct(type, ptr);
>+*/
>+
>+struct lock_profile {
>+    struct lock_profile *next;       /* forward link */
>+    char                *name;       /* lock name */
>+    u64                 lock_cnt;    /* # of complete locking ops */
>+    u64                 block_cnt;   /* # of complete wait for lock */
>+    s64                 time_hold;   /* cumulated lock time */
>+    s64                 time_block;  /* cumulated wait time */
>+    s64                 time_locked; /* system time of last locking */
>+};
>+
>+struct lock_profile_qhead {
>+    struct lock_profile_qhead *head_q; /* next head of this type */
>+    struct lock_profile       *elem_q; /* first element in q */
>+    int32_t                   idx;     /* index for printout */
>+};
>+
>+#define _LOCK_PROFILE(name) { 0, name, 0, 0, 0, 0, 0 }
>+#define _LOCK_NO_PROFILE _LOCK_PROFILE(NULL)
>+#define _LOCK_PROFILE_PTR(name)                                           
>    \
>+    static struct lock_profile *__lock_profile_##name __attribute_used__  
>    \
>+    __attribute__ ((__section__(".lockprofile.data"))) = &name.profile
>+#define _SPIN_LOCK_UNLOCKED(x) { _RAW_SPIN_LOCK_UNLOCKED, 0xfffu, 0,      
>    \
>+                                 _LOCK_DEBUG, x }
>+#define SPIN_LOCK_UNLOCKED _SPIN_LOCK_UNLOCKED(_LOCK_NO_PROFILE)
>+#define DEFINE_SPINLOCK(l)                                                
>    \
>+    spinlock_t l = _SPIN_LOCK_UNLOCKED(_LOCK_PROFILE(#l));                
>    \
>+    _LOCK_PROFILE_PTR(l)
>+
>+#define spin_lock_init_prof(s, l)                                         
>    \
>+    do {                                                                  
>    \
>+        (s)->l = (spinlock_t)_SPIN_LOCK_UNLOCKED(_LOCK_PROFILE(#l));      
>    \
>+      (s)->l.profile.next = (s)->profile_head.elem_q;                       \

>+      (s)->profile_head.elem_q = &((s)->l.profile);                         \

>+    } while(0)
>+
>+void _lock_profile_register_struct(int32_t, struct lock_profile_qhead *,  
>    \
>+                                   int32_t, char *);
>+void _lock_profile_deregister_struct(int32_t, struct lock_profile_qhead *);
>+
>+#define lock_profile_register_struct(type, ptr, idx, print)               
>    \
>+    _lock_profile_register_struct(type, &((ptr)->profile_head), idx, print)
>+#define lock_profile_deregister_struct(type, ptr)                         
>    \
>+    _lock_profile_deregister_struct(type, &((ptr)->profile_head))
>+
>+#else
>+
>+struct lock_profile { };
>+struct lock_profile_qhead { };
>+
>+#define SPIN_LOCK_UNLOCKED                                                
>    \
>+    { _RAW_SPIN_LOCK_UNLOCKED, 0xfffu, 0, _LOCK_DEBUG, { } }
>+#define DEFINE_SPINLOCK(l) spinlock_t l = SPIN_LOCK_UNLOCKED
>+
>+#define spin_lock_init_prof(s, l) spin_lock_init(&((s)->l))
>+#define lock_profile_register_struct(type, ptr, idx, print)
>+#define lock_profile_deregister_struct(type, ptr)
>+
>+#endif
>+
> typedef struct {
>     raw_spinlock_t raw;
>     u16 recurse_cpu:12;
>     u16 recurse_cnt:4;
>     struct lock_debug debug;
>+    struct lock_profile profile;
> } spinlock_t;
> 
> 
>-#define SPIN_LOCK_UNLOCKED { _RAW_SPIN_LOCK_UNLOCKED, 0xfffu, 0, 
>_LOCK_DEBUG }
>-#define DEFINE_SPINLOCK(l) spinlock_t l = SPIN_LOCK_UNLOCKED
> #define spin_lock_init(l) (*(l) = (spinlock_t)SPIN_LOCK_UNLOCKED)
> 
> typedef struct {
>
>_______________________________________________
>Xen-changelog mailing list
>Xen-changelog@xxxxxxxxxxxxxxxxxxx
>http://lists.xensource.com/xen-changelog


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.