ia64/xen-unstable

changeset 11728:c1a8785f0eb1

[IA64] p2m exposure test module

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author awilliam@xenbuild.aw
date Wed Oct 04 22:12:50 2006 -0600 (2006-10-04)
parents d1d9f3f6ca09
children 3e9fcbee3c09
files xen/arch/ia64/tools/p2m_expose/Makefile xen/arch/ia64/tools/p2m_expose/README.p2m_expose xen/arch/ia64/tools/p2m_expose/expose_p2m.c
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/xen/arch/ia64/tools/p2m_expose/Makefile	Wed Oct 04 22:12:50 2006 -0600
     1.3 @@ -0,0 +1,28 @@
     1.4 +ifneq ($(KERNELRELEASE),)
     1.5 +obj-m += expose_p2m.o
     1.6 +else
     1.7 +PWD := $(shell pwd)
     1.8 +TOPDIR ?= $(abspath $(PWD)/../../../../..)
     1.9 +KDIR ?= $(TOPDIR)/linux-$(shell awk '/^LINUX_VER\>/{print $$3}' $(TOPDIR)/buildconfigs/mk.linux-2.6-xen)-xen
    1.10 +#CROSS_COMPILE ?= ia64-unknown-linux-
    1.11 +#ARCH ?= ia64
    1.12 +
    1.13 +ifneq ($(O),)
    1.14 +OPT_O := O=$(realpath $(O))
    1.15 +endif
    1.16 +
    1.17 +ifneq ($(V),)
    1.18 +OPT_V := V=$(V)
    1.19 +endif
    1.20 +
    1.21 +ifneq ($(ARCH),)
    1.22 +OPT_ARCH := ARCH=$(ARCH)
    1.23 +endif
    1.24 +
    1.25 +ifneq ($(CROSS_COMPILE),)
    1.26 +OPT_CORSS_COMPILE := CROSS_COMPILE=$(CROSS_COMPILE)
    1.27 +endif
    1.28 +
    1.29 +default:
    1.30 +	$(MAKE) -C $(KDIR) $(OPT_O) $(OPT_V) $(OPT_CORSS_COMPILE) $(OPT_ARCH) M=$(PWD)
    1.31 +endif
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xen/arch/ia64/tools/p2m_expose/README.p2m_expose	Wed Oct 04 22:12:50 2006 -0600
     2.3 @@ -0,0 +1,12 @@
     2.4 +This directory contains Linux kernel module for p2m exposure test/benchmark.
     2.5 +
     2.6 +1. build kernel module
     2.7 +   - At fist build, linux-xen as usual
     2.8 +   - then type just 'make' in this directory, then you'll have expose_p2m.ko.
     2.9 +     See Makefile for details.
    2.10 +
    2.11 +2. test, benchmark.
    2.12 +   - type 'insmod expose_p2m.ko' on the system.
    2.13 +   Then the result is printed out to your console.
    2.14 +   insmod fails with EINVAL so that you don't have to execute rmmod.
    2.15 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen/arch/ia64/tools/p2m_expose/expose_p2m.c	Wed Oct 04 22:12:50 2006 -0600
     3.3 @@ -0,0 +1,185 @@
     3.4 +/******************************************************************************
     3.5 + * arch/ia64/xen/expose_p2m.c
     3.6 + *
     3.7 + * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
     3.8 + *                    VA Linux Systems Japan K.K.
     3.9 + *
    3.10 + * This program is free software; you can redistribute it and/or modify
    3.11 + * it under the terms of the GNU General Public License as published by
    3.12 + * the Free Software Foundation; either version 2 of the License, or
    3.13 + * (at your option) any later version.
    3.14 + *
    3.15 + * This program is distributed in the hope that it will be useful,
    3.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.18 + * GNU General Public License for more details.
    3.19 + *
    3.20 + * You should have received a copy of the GNU General Public License
    3.21 + * along with this program; if not, write to the Free Software
    3.22 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.23 + *
    3.24 + */
    3.25 +
    3.26 +#include <linux/module.h>
    3.27 +#include <linux/init.h>
    3.28 +#include <asm/page.h>
    3.29 +#include <asm/pgtable.h>
    3.30 +#include <asm/hypercall.h>
    3.31 +#include <asm/hypervisor.h>
    3.32 +
    3.33 +#define printd(fmt, ...)	printk("%s:%d " fmt, __func__, __LINE__, \
    3.34 +				       ##__VA_ARGS__)
    3.35 +
    3.36 +// copied from arch/ia64/mm/tlb.c. it isn't exported.
    3.37 +void
    3.38 +local_flush_tlb_all (void)
    3.39 +{
    3.40 +        unsigned long i, j, flags, count0, count1, stride0, stride1, addr;
    3.41 +
    3.42 +        addr    = local_cpu_data->ptce_base;
    3.43 +        count0  = local_cpu_data->ptce_count[0];
    3.44 +        count1  = local_cpu_data->ptce_count[1];
    3.45 +        stride0 = local_cpu_data->ptce_stride[0];
    3.46 +        stride1 = local_cpu_data->ptce_stride[1];
    3.47 +
    3.48 +        local_irq_save(flags);
    3.49 +        for (i = 0; i < count0; ++i) {
    3.50 +                for (j = 0; j < count1; ++j) {
    3.51 +                        ia64_ptce(addr);
    3.52 +                        addr += stride1;
    3.53 +                }
    3.54 +                addr += stride0;
    3.55 +        }
    3.56 +        local_irq_restore(flags);
    3.57 +        ia64_srlz_i();                  /* srlz.i implies srlz.d */
    3.58 +}
    3.59 +
    3.60 +static void
    3.61 +do_p2m(unsigned long (*conv)(unsigned long),
    3.62 +       const char* msg, const char* prefix, 
    3.63 +       unsigned long start_gpfn, unsigned end_gpfn, unsigned long stride)
    3.64 +{
    3.65 +	struct timeval before_tv;
    3.66 +	struct timeval after_tv;
    3.67 +	unsigned long gpfn;
    3.68 +	unsigned long mfn;
    3.69 +	unsigned long count;
    3.70 +	nsec_t nsec;
    3.71 +
    3.72 +	count = 0;
    3.73 +	do_gettimeofday(&before_tv);
    3.74 +	for (gpfn = start_gpfn; gpfn < end_gpfn; gpfn += stride) {
    3.75 +		mfn = (*conv)(gpfn);
    3.76 +		count++;
    3.77 +	}
    3.78 +	do_gettimeofday(&after_tv);
    3.79 +	nsec = timeval_to_ns(&after_tv) - timeval_to_ns(&before_tv);
    3.80 +	printk("%s stride %4ld %s: %9ld / %6ld = %5ld nsec\n",
    3.81 +	       msg, stride, prefix,
    3.82 +	       nsec, count, nsec/count);
    3.83 +}
    3.84 +
    3.85 +
    3.86 +static void
    3.87 +do_with_hypercall(const char* msg,
    3.88 +		  unsigned long start_gpfn, unsigned long end_gpfn,
    3.89 +		  unsigned long stride)
    3.90 +{
    3.91 +	do_p2m(&HYPERVISOR_phystomach, msg, "hypercall",
    3.92 +	       start_gpfn, end_gpfn, stride);
    3.93 +}
    3.94 +
    3.95 +static void
    3.96 +do_with_table(const char* msg,
    3.97 +	    unsigned long start_gpfn, unsigned long end_gpfn,
    3.98 +	    unsigned long stride)
    3.99 +{
   3.100 +	do_p2m(&p2m_phystomach, msg, "p2m table",
   3.101 +	       start_gpfn, end_gpfn, stride);
   3.102 +}
   3.103 +
   3.104 +static int __init
   3.105 +expose_p2m_init(void)
   3.106 +{
   3.107 +	unsigned long gpfn;
   3.108 +	unsigned long mfn;
   3.109 +	unsigned long p2m_mfn;
   3.110 +
   3.111 +	int error_count = 0;
   3.112 +
   3.113 +	const int strides[] = {
   3.114 +		PTRS_PER_PTE, PTRS_PER_PTE/2, PTRS_PER_PTE/3, PTRS_PER_PTE/4,
   3.115 +		L1_CACHE_BYTES/sizeof(pte_t), 1
   3.116 +	};
   3.117 +	int i;
   3.118 +	
   3.119 +
   3.120 +#if 0
   3.121 +	printd("about to call p2m_expose_init()\n");
   3.122 +	if (p2m_expose_init() < 0) {
   3.123 +		printd("p2m_expose_init() failed\n");
   3.124 +		return -EINVAL;
   3.125 +	}
   3.126 +	printd("p2m_expose_init() success\n");
   3.127 +#else
   3.128 +	if (!p2m_initialized) {
   3.129 +		printd("p2m exposure isn't initialized\n");
   3.130 +		return -EINVAL;
   3.131 +	}
   3.132 +#endif
   3.133 +
   3.134 +	printd("p2m expose test begins\n");
   3.135 +	for (gpfn = p2m_min_low_pfn; gpfn < p2m_max_low_pfn; gpfn++) {
   3.136 +		mfn = HYPERVISOR_phystomach(gpfn);
   3.137 +		p2m_mfn = p2m_phystomach(gpfn);
   3.138 +		if (mfn != p2m_mfn) {
   3.139 +			printd("gpfn 0x%016lx "
   3.140 +			       "mfn 0x%016lx p2m_mfn 0x%016lx\n",
   3.141 +			       gpfn, mfn, p2m_mfn);
   3.142 +			printd("mpaddr 0x%016lx "
   3.143 +			       "maddr 0x%016lx p2m_maddr 0x%016lx\n",
   3.144 +			       gpfn << PAGE_SHIFT,
   3.145 +			       mfn << PAGE_SHIFT, p2m_mfn << PAGE_SHIFT);
   3.146 +
   3.147 +			error_count++;
   3.148 +			if (error_count > 16) {
   3.149 +				printk("too many errors\n");
   3.150 +				return -EINVAL;
   3.151 +			}
   3.152 +		}
   3.153 +	}
   3.154 +	printd("p2m expose test done!\n");
   3.155 +
   3.156 +	printk("type     "
   3.157 +	       "stride      "
   3.158 +	       "type     : "
   3.159 +	       "     nsec /  count = "
   3.160 +	       "nsec per conv\n");
   3.161 +	for (i = 0; i < sizeof(strides)/sizeof(strides[0]); i++) {
   3.162 +		int stride = strides[i];
   3.163 +		local_flush_tlb_all();
   3.164 +		do_with_hypercall("cold tlb",
   3.165 +				  p2m_min_low_pfn, p2m_max_low_pfn, stride);
   3.166 +		do_with_hypercall("warm tlb",
   3.167 +				  p2m_min_low_pfn, p2m_max_low_pfn, stride);
   3.168 +
   3.169 +		local_flush_tlb_all();
   3.170 +		do_with_table("cold tlb",
   3.171 +			      p2m_min_low_pfn, p2m_max_low_pfn, stride);
   3.172 +		do_with_table("warm tlb",
   3.173 +			      p2m_min_low_pfn, p2m_max_low_pfn, stride);
   3.174 +	}
   3.175 +
   3.176 +	return -EINVAL;
   3.177 +}
   3.178 +
   3.179 +static void __exit
   3.180 +expose_p2m_cleanup(void)
   3.181 +{
   3.182 +}
   3.183 +
   3.184 +module_init(expose_p2m_init);
   3.185 +module_exit(expose_p2m_cleanup);
   3.186 +
   3.187 +MODULE_LICENSE("GPL");
   3.188 +MODULE_AUTHOR("Isaku Yamahata <yamahata@valinux.co.jp>");