コード例 #1
0
ファイル: pagetable.c プロジェクト: baozich/scripts
/**
 * vmr_printmap - Print out a map representing a memory range
 * @mm: The mm to print pages from
 * @addr: The starting address
 * @len: The len of the address space to print
 * @sched_count: A count of how many times schedule() was called
 *
 * This function is used when it is desirable to see what a memory area
 * looks like. Each character in the map has 8 bits. The lower four bits
 * are used to store information about 4 pages. The 5th and 6th bit is set to one.
 * This will guarentee that something printable will show up. Using the
 * whole character for 8 bits leads to unprintable data filled with escape
 * characters.
 */
unsigned long vmr_printmap(struct mm_struct *mm, unsigned long addr,
		unsigned long len, unsigned long *sched_count,
		vmr_desc_t *testinfo)
{
	int mapsize;		/* Size of map */
	int growsize;		/* Number of pages to grow proc */
	int *print_written;	/* Number of bytes written see vmr_snprintf macro*/
	int print_size;	/* Size of proc buffer, see vmr_snprinf macro */
	int present;

	/* Make sure we are the writer */
	if (current->pid != testinfo->pid) return 0;

	print_written = &testinfo->written;
	print_size    = testinfo->procbuf_size;

	/* Calculate if the current proc area needs to be grown 
	 * Each 8 pages is one character hence 
	 *   (len / PAGE_SIZE) gives the number of pages
	 *   no. pages / 4 = number of chars (using only readable chars)
	 */
	mapsize = ((len / PAGE_SIZE) / 4);

	/*
	 * check if we should grow the proc buffer 
	 * The additional 256 bytes is for the header and footer around
	 * the map information
	 * */
	if (testinfo->procbuf_size - *print_written < mapsize + 256) {
		/* Proc buffer has to be grown */
		growsize = PAGE_ALIGN(mapsize + 256) / PAGE_SIZE;
		vmr_printk("Growing proc buffer by %d pages for mapsize %d\n", growsize, mapsize);
		vmrproc_growbuffer(growsize, testinfo);
		print_size = testinfo->procbuf_size;
	}

	/* Zero out the map */
	memset(&testinfo->procbuf[*print_written], 0, mapsize);

	/* Print out header for map (40 is for the actual message to print) */
	vmr_snprintf(testinfo,
			&testinfo->procbuf[*print_written],
			testinfo->procbuf_size - *print_written - 40,
			"BEGIN PAGE MAP 0x%lX - 0x%lX\n",
			addr,
			addr + len);

	/* Set the 5th and 6th bit on the map */
	memset(&testinfo->procbuf[*print_written], 48, mapsize);

	/* Print out the map */
	testinfo->mapaddr = addr;
	present = forall_pte_mm(mm, addr, len, sched_count, testinfo, vmr_printpage);

	/* Print out footer (50 is for the message to print) */
	*print_written += mapsize;
	vmr_snprintf(testinfo,
			&testinfo->procbuf[*print_written],
			testinfo->procbuf_size - *print_written - 50,
			"\nEND PAGE MAP - %d pages of %lu present\n", 
			present, len / PAGE_SIZE);

	return 0;
}
コード例 #2
0
ファイル: fault.c プロジェクト: kosaki/vmregress
/**
 *
 * test_fault_runtest - Allocate and free a number of pages from a zone
 * @params: Parameters read from the proc entry
 * @argc:   Number of parameters actually entered
 * @procentry: Proc buffer to write to
 *
 * If pages is set to 0, pages will be allocated until the pages_high watermark
 * is hit
 * Returns
 * 0  on success
 * -1 on failure
 *
 */
int test_fault_runtest(int *params, int argc, int procentry) {
	unsigned long nopages;		/* Number of pages to allocate */
	int nopasses;			/* Number of times to run test */
	C_ZONE *zone;			/* Zone been tested on */
	unsigned long freelimit;	/* The min no. free pages in zone */
	unsigned long alloccount;	/* Number of pages alloced */
	unsigned long present;		/* Number of pages present */
	unsigned long addr=0;		/* Address mapped area starts */
	unsigned long len;		/* Length of mapped area */
	unsigned long sched_count;	/* How many times schedule is called */
	unsigned long start;		/* Start of a test in jiffies */
	int totalpasses;		/* Total number of passes */
	int failed=0;			/* Failed mappings */

	/* Get the parameters */
	nopasses = params[0];
	nopages  = params[1];

	/* Make sure a buffer is available */
	if (vmrproc_checkbuffer(testinfo[procentry])) BUG();
	vmrproc_openbuffer(&testinfo[procentry]);

	/* Make sure passes is valid */
	if (nopasses <= 0)
	{
		vmr_printk("Cannot make 0 or negative number of passes\n");
		return -1;
	}

	/* Print header */
	printp("%s Test Results (" UTS_RELEASE ").\n\n", testinfo[procentry].name);

	/* Get the parameters for the test */
	if (test_fault_calculate_parameters(procentry, &zone, &nopages, &freelimit) == -1) {
		printp("Test failed\n");
		return -1;
	}
	len = nopages * PAGE_SIZE;

	/*
	 * map a region of memory where our pages are going to be stored 
	 * This is the same as the system call to mmap
	 *
	 */
	addr =  do_mmap(NULL,		/* No struct file */
			0,		/* No starting address */
			len,		/* Length of address space */
			PROT_WRITE | PROT_READ, /* Protection */
			MAP_PRIVATE | MAP_ANONYMOUS,	/* Private mapping */
			0);
			
	/* get_unmapped area has a horrible way of returning errors */
	if (addr == -1) {
		printp("Failed to mmap");
		return -1;
	}

	/* Print area information */
	printp("Mapped Area Information\n");
	printp("o address:  0x%lX\n", addr);
	printp("o length:   %lu (%lu pages)\n", len, nopages);
	printp("\n");

	/* Begin test */
	printp("Test Parameters\n");
	printp("o Passes:	       %d\n",  nopasses);
	printp("o Starting Free pages: %lu\n", zone->free_pages);
	printp("o Free page limit:     %lu\n", freelimit);
	printp("o References:	       %lu\n", nopages);
	printp("\n");

	printp("Test Results\n");
	printp("Pass       Refd     Present   Time\n");
	totalpasses = nopasses;

	/* Copy the string into every page once to alloc all ptes */
	alloccount=0;
	start = jiffies;
	while (nopages-- > 0) {
		check_resched(sched_count);

		copy_to_user((unsigned long *)(addr + (nopages * PAGE_SIZE)),
			test_string,
			strlen(test_string));

		alloccount++;
	}

	/*
	 * Step through the page tables pass number of times swapping in
	 * pages as necessary
	 */
	for (;;) {

		/* Count the number of pages present */
		present = countpages_mm(current->mm, addr, len, &sched_count);

		/* Print test info */
		printp("%-8d %8lu %8lu %8lums\n", totalpasses-nopasses,
							alloccount,
							present,
							jiffies_to_ms(start));

		if (nopasses-- == 0) break;

		/* Touch all the pages in the mapped area */
		start = jiffies;
		alloccount = forall_pte_mm(current->mm, addr, len, 
				&sched_count, NULL, touch_pte);

	}
	
	printp("\nPost Test Information\n");
	printp("o Finishing Free pages: %lu\n", zone->free_pages);
	printp("o Schedule() calls:     %lu\n", sched_count);
	printp("o Failed mappings:      %u\n",  failed);
	printp("\n");

	printp("Test completed successfully\n");

	/* Print out a process map */
	vmr_printmap(current->mm, addr, len, &sched_count, &testinfo[procentry]);
	/* Unmap the area */
	if (do_munmap(current->mm, addr, len) == -1) {
		printp("WARNING: Failed to unmap memory area"); }

	vmrproc_closebuffer(&testinfo[procentry]);
	return 0;
}
コード例 #3
0
ファイル: pagetable.c プロジェクト: baozich/scripts
/**
 * countpages_mm - Count how many pages are present in a mm
 * @mm: The mm to count pages in
 * @addr: The starting address
 * @len: The length of the address space to check
 * @sched_count: A count of how many times schedule() was called
 */
unsigned long countpages_mm(struct mm_struct *mm, unsigned long addr,
		unsigned long len, unsigned long *sched_count) {

	return forall_pte_mm(mm, addr, len, sched_count, NULL, ispage_present);
}