⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bte_regr_test.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * * * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved. *  * This program is free software; you can redistribute it and/or modify it  * under the terms of version 2 of the GNU General Public License  * as published by the Free Software Foundation. *  * This program is distributed in the hope that it would be useful, but  * WITHOUT ANY WARRANTY; without even the implied warranty of  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  *  * Further, this software is distributed without any warranty that it is  * free of the rightful claim of any third person regarding infringement  * or the like.  Any license provided herein, whether implied or  * otherwise, applies only to this software file.  Patent licenses, if  * any, provided herein do not apply to combinations of this program with  * other software, or any other product whatsoever. *  * You should have received a copy of the GNU General Public  * License along with this program; if not, write the Free Software  * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. *  * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,  * Mountain View, CA  94043, or: *  * http://www.sgi.com  *  * For further information regarding this notice, see:  *  * http://oss.sgi.com/projects/GenInfo/NoticeExplan *//*********************************************************************** * Block Transfer Engine regression tests. * *	The following set of tests can be used to test for regressions. *	It is implemented as a loadable module. * *	To enable the tests, the kernel must be booted with the *	"btetest" command line flag.  If the tests are compiled into the *	kernel, additional values may be passed with *	"bte_test=t,v,ht,tn,tx,ti,ta,tc" *	where: *	    t = Bitmask of tests to run. *	    v = Level of verbosity. *	    ht = Number of seconds to try to force a notification hang. *          hu = Number of uSecs to wait until warning of hang. *	    tn = Min number of lines to rate test with (2 raised to). *	    tx = Max number of lines to rate test with (2 raised to). *	    ti = Number of iterations per timing. *          ta = Aternate through cpus on each pass. *	    tc = Use/Don't Use memcopy * *	When loaded as a module, each of those values has a seperate *	parameter.  Just do a modinfo bte_test.o to get those names *	and valid ranges. * *	Tests are performed in the following order. * *	Standard Transfer Test - Just transfers a block of initialized *	data to a cleared block and ensures that memory before and after *	is untouched, but that the body has all the correct values. * *	Transfer Rate Test - Data is transfered from node to node *	to ensure every node is able to BTE data.  Timings are created *	for each node. * *	Notification Hang Test - Attempts to force the Notification *	hang problem to arise.  A hang occurs when the BTE fails *	to invalidate a processors cache line for the notification *	word, resulting in the processor not seeing the updated *	value. * *	Invalid Transfer Test - In this test, we attempt to transfer *	data from a valid address to a nasid which does not exist. * **********************************************************************/#define BTE_TIME 1		/* Needed to ensure bte_copy records				 * timings */// #define BTE_DEBUG// #define BTE_DEBUG_VERBOSE#include <linux/kernel.h>#include <linux/init.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/sched.h>#include <asm/sn/nodepda.h>#include <asm/processor.h>#include <asm/sn/bte_copy.h>/*********************************************************************** * Local defines, structs, and typedefs. * **********************************************************************//* * The following struct defines standard transfers to use while * testing. */typedef struct brt_xfer_entry_s {	int source_offset;	int dest_offset;	int length;} brt_xfer_entry_t;/* * BRT_TEST_BLOCK_SIZE needs to accomodate the largest transfer that * is found in brt_xfer_tests. */#define BRT_TEST_BLOCK_SIZE 1024/* Flags for selecting tests to run. */#define TEST_REGRESSION		0x00000001	/* Standard Transfer */#define TEST_TIME		0x00000002	/* Timed Transfer */#define TEST_NOTIFY		0x00000004	/* Notification Hang */#define TEST_NONODE		0x00000008	/* Invalid Nasid Xfer *//*********************************************************************** * Global variables. *  **********************************************************************//* * bte_setup_time - Time it takes for bte_copy to get locks * 		    acquired and values into SHUB registers to start the * 		    xfer. * * bte_transfer_time - Time where hardware is doing the xfer. * * bte_tear_down_time - Time to unlock and return. * * bte_execute_time - Time from first call until return. */volatile static u64 bte_setup_time;volatile static u64 bte_transfer_time;volatile static u64 bte_tear_down_time;volatile static u64 bte_execute_time;/* Tests to run during standard transfer tests. */static brt_xfer_entry_t brt_xfer_tests[] = {	{0, 0, 2 * L1_CACHE_BYTES},	/* The ideal case. */	{0, 0, 35},		/* Symetrical aligned test. */	{L1_CACHE_BYTES, L1_CACHE_BYTES, 35},	{0, 0, L1_CACHE_BYTES + 35},	{L1_CACHE_BYTES, L1_CACHE_BYTES, L1_CACHE_BYTES + 35},	{0, 0, (2 * L1_CACHE_BYTES) + 35},	{L1_CACHE_BYTES, L1_CACHE_BYTES, (2 * L1_CACHE_BYTES) + 35},	{0, 0, (4 * L1_CACHE_BYTES) + 35},	{L1_CACHE_BYTES, L1_CACHE_BYTES, (4 * L1_CACHE_BYTES) + 35},	{(0 + 25), (0 + 25), 35},	/* Symetrical unaligned test. */	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25), 35},	{(0 + 25), (0 + 25), L1_CACHE_BYTES + 35},	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25),	 (L1_CACHE_BYTES + 25) + 35},	{(0 + 25), (0 + 25), (2 * L1_CACHE_BYTES) + 35},	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25),	 (2 * L1_CACHE_BYTES) + 35},	{(0 + 25), (0 + 25), (4 * L1_CACHE_BYTES) + 35},	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25),	 (4 * L1_CACHE_BYTES) + 35},	{(0 + 25), (0 + 26), 35},	/* Asymetrical unaligned test. */	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26), 35},	{(0 + 25), (0 + 26), L1_CACHE_BYTES + 35},	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26),	 (L1_CACHE_BYTES + 25) + 35},	{(0 + 25), (0 + 26), (2 * L1_CACHE_BYTES) + 35},	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26),	 (2 * L1_CACHE_BYTES) + 35},	{(0 + 25), (0 + 26), (4 * L1_CACHE_BYTES) + 35},	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26),	 (4 * L1_CACHE_BYTES) + 35},	{0, 0, 0}		/* Terminator */};static atomic_t brt_thread_cnt;	/* Threads in test. */volatile static int brt_exit_flag;	/* Flag termination of hang test *//* command line/module parameters */static int selected_tests = 0;static int verbose = 0;static int hang_timeout = 10;static int hang_usec = 12;static int tm_min_lines = 1;static int tm_max_lines = 3;static int tm_iterations = 1;static int tm_alternate = 0;static int tm_memcpy = 1;static int ix_iterations = 1000;static int ix_srcnasid = -1;/*********************************************************************** * Local Function Prototypes. *  **********************************************************************/static int __init brt_test_init(void);static void __exit brt_test_exit(void);/* Standard Transfer Test related functions. */static int brt_tst_std_xfer(void);static int brt_std_xfer(char *, char *, int, int, int, int);static void brt_hex_dump(char *, int);/* Timed Transfer Test related functions. */static int brt_tst_time_xfers(void);static void brt_time_xfer(int, int, int);/* Notification Hang Test related functions. */static int brt_tst_notify_hang(void);static int brt_notify_thrd(void *);/* Transfers to Invalid Nasid Test related functions. */static int brt_tst_invalid_xfers(void);#if !defined(MODULE)/* Kernel command line handler. */static int __init brt_setup(char *);#endif				/* !defined(MODULE) *//*********************************************************************** * Module Load/Unload. *  **********************************************************************/#define brt_marker() \	printk("**************************************************" \	       "**********************.\n"); \	printk("\n"); \	printk("**************************************************" \	       "**********************.\n"); \	printk("\n"); \	printk("**************************************************" \	       "**********************.\n"); \	printk("\n");static int __initbrt_test_init(void){	int some_tests_removed;	if (numnodes < 2) {		printk("These tests are best run on multinode "		       "systems.\n");	}	if (!pda.cpu_bte_if[0]->bte_test_buf) {		some_tests_removed = 0;		/* Timed Transfers go node-to-node. */		if (selected_tests & TEST_TIME) {			some_tests_removed = 1;			selected_tests &= ~(TEST_TIME);		}		/* Notification Hang runs on all cpus simultaneously */		if (selected_tests & TEST_NOTIFY) {			some_tests_removed = 1;			selected_tests &= ~(TEST_NOTIFY);		}		/* Invalid Tests */		if (selected_tests & TEST_NONODE) {			some_tests_removed = 1;			selected_tests &= ~(TEST_NONODE);		}		if (some_tests_removed) {			printk("Test Buffers were not allocated.\n");			printk("Please reboot the system and supply "			       "the \"btetest\" kernel flag\n");			printk("Some tests were removed.\n");		}	}	brt_marker();	printk("brt_test(): Starting.\n");	if (selected_tests & TEST_REGRESSION) {		if (brt_tst_std_xfer()) {			printk("Standard Transfers had errors.\n");		}	}	if (selected_tests & TEST_TIME) {		if (tm_min_lines < 0) {			tm_min_lines = 0;		}		if (tm_max_lines < 0) {			tm_max_lines = 0;		}		if (tm_max_lines > BTE_LEN_MASK) {			tm_max_lines = BTE_LEN_MASK;		}		if (tm_min_lines > tm_max_lines) {			tm_min_lines = tm_max_lines;		}		if (brt_tst_time_xfers()) {			printk("Timed transfers had errors.\n");		}	}	if (selected_tests & TEST_NOTIFY) {		if (hang_usec < 8) {			hang_usec = 8;		}		if (hang_usec > 256) {			hang_usec = 256;		}		if (brt_tst_notify_hang()) {			printk("Notification Hang test had errors.\n");		}	}	if (selected_tests & TEST_NONODE) {		if (brt_tst_invalid_xfers()) {			printk("Invalid Nasid test had errors.\n");		}	}	return (1);		/* Prevent module load. */}static void __exitbrt_test_exit(void){}/*********************************************************************** * Standard Transfer Test. *	 *	This test has a table of transfers defined above.  For each *	transfer, it calls bte_unaligned_copy.  It compares the actual *	result with the expected result.  If they differ, it prints out *	information about the transfer and hex dumps the actual block * **********************************************************************//* * Allocate the needed buffers and then initiate each xfer specified * by brt_xfer_tests. */static intbrt_tst_std_xfer(void){	char *block_1;	char *block_2;	int iteration = 0;	brt_xfer_entry_t *cur_test;	int cpu;	int err_cnt;	block_1 = kmalloc(BRT_TEST_BLOCK_SIZE, GFP_KERNEL);	ASSERT(!((u64) block_1 & L1_CACHE_MASK));	block_2 = kmalloc(BRT_TEST_BLOCK_SIZE, GFP_KERNEL);	ASSERT(!((u64) block_2 & L1_CACHE_MASK));	cur_test = brt_xfer_tests;	err_cnt = 0;	while (cur_test->length) {		for (cpu = 0; cpu < smp_num_cpus; cpu++) {			set_cpus_allowed(current, (1UL << cpu));			if (verbose > 1) {				printk("Cpu %d Transfering %d from "				       "%d to %d.\n",				       smp_processor_id(),				       cur_test->length,				       cur_test->source_offset,				       cur_test->dest_offset);			}			err_cnt += brt_std_xfer(block_1, block_2,						cur_test->source_offset,						cur_test->dest_offset,						cur_test->length,						++iteration);		}		cur_test++;	}	kfree(block_2);	kfree(block_1);	return ((err_cnt ? 1 : 0));}/* * Perform a single transfer and ensure the result matches * the expected.  Returns the number of differences found. * * Testing is performed by setting the source buffer to a * known value, and zeroing out the destination. * * After the copy, if the destination has only the known * source values at the correct place, we know we had a * good transfer. * */static intbrt_std_xfer(char *src, char *dst,	     int src_offset, int dst_offset, int len,	     int magic){	int i, ret;	int err_cnt = 0;	if (verbose > 3) {		printk("brt_test(src=0x%lx, dst=0x%lx, src_offset=%d, "		       "dst_offset=%d, len=%d, magic=%d\n",		       (u64) src, (u64) dst, src_offset,		       dst_offset, len, magic);	}	memset(src, ((magic + 1) & 0xff), BRT_TEST_BLOCK_SIZE);	memset((src + src_offset), magic, len);	if (verbose > 8) {		printk("Before transfer: Source is\n");		brt_hex_dump(src, BRT_TEST_BLOCK_SIZE);	}	memset(dst, 0, BRT_TEST_BLOCK_SIZE);	if (verbose > 8) {		printk("Before transfer: dest is\n");		brt_hex_dump(dst, BRT_TEST_BLOCK_SIZE);	}	ret = BTE_UNALIGNED_COPY(__pa(src + src_offset),				 __pa(dst + dst_offset),				 len, BTE_NOTIFY);	if (ret != BTE_SUCCESS) {		printk("brt_test: BTE_UNALIGNED_COPY() error: %d\n", ret);		return (1);	}	/* Check head */	for (i = 0; i < dst_offset; i++) {		if ((dst[i] & 0xff) != 0) {			err_cnt++;		}	}	/* Check body */	for (i = 0; i < len; i++) {		if ((dst[dst_offset + i] & 0xff) != (magic & 0xff)) {			err_cnt++;		}	}	/* Check foot */	for (i = (dst_offset + len); i < BRT_TEST_BLOCK_SIZE; i++) {		if ((dst[i] & 0xff) != 0) {			err_cnt++;		}	}	if ((verbose > 3) || err_cnt) {		printk("brt_test: %d errors during basic "		       "transfer test.\n", err_cnt);		brt_hex_dump(dst, BRT_TEST_BLOCK_SIZE);	}	return (err_cnt);}/* * Dump a block of data to console as hex. */static voidbrt_hex_dump(char *block_to_dump, int block_len){	int i;	char fmt_line[128];	char *fmt_eol = fmt_line;	for (i = 0; i < block_len; i++) {		if (!(i % 16)) {			if (i > 0) {				printk("%s\n", fmt_line);			}			sprintf(fmt_line, "0x%lx %05d ",				__pa(&block_to_dump[i]), i);			fmt_eol = fmt_line;		}		while (*fmt_eol++) {	/* empty */		};		fmt_eol--;		sprintf(fmt_eol, "%s%02x",			(!(i % 4) ? " " : ""), (block_to_dump[i] & 0xff));	}	printk("%s\n", fmt_line);}/*********************************************************************** * Transfer Rate Test. *  *	This test migrates to each cpu one at a time.  This is done to *	get a complete view of how each of the bte engines is performing *	and help ensure that each virtual interface is being used. *	NOTE: All virtual interfaces will not necessarily be used. * *	Now that we have migrated to the desired cpu, we transfer from

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -