The bug in the offset correction code for the 'shrink region from below' case can easily case an assert(foundregion->offset == offset) to trigger (if the blocks are touched afterwards, e.g. on fork()) as the offsets become wrong. This commit is a fix & regression test. Change-Id: I28ed403e3891362a2dea674a49e786d3450d2983
		
			
				
	
	
		
			131 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Test 74 - mmap functionality test.
 | 
						|
 */
 | 
						|
 | 
						|
#include <sys/types.h>
 | 
						|
#include <sys/mman.h>
 | 
						|
#include <sys/ioc_memory.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <assert.h>
 | 
						|
#include <string.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <fcntl.h>
 | 
						|
 | 
						|
#include "common.h"
 | 
						|
#include "testcache.h"
 | 
						|
 | 
						|
int
 | 
						|
dowriteblock(int b, int blocksize, u32_t seed, char *data)
 | 
						|
{
 | 
						|
	u64_t offset;
 | 
						|
	int fd;
 | 
						|
 | 
						|
	get_fd_offset(b, blocksize, &offset, &fd);
 | 
						|
 | 
						|
	if(pwrite(fd, data, blocksize, offset) < blocksize) {
 | 
						|
		perror("pwrite");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	return blocksize;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
readblock(int b, int blocksize, u32_t seed, char *data)
 | 
						|
{
 | 
						|
	u64_t offset;
 | 
						|
	int fd;
 | 
						|
	char *mmapdata;
 | 
						|
	int pread_first = random() % 2;
 | 
						|
 | 
						|
	get_fd_offset(b, blocksize, &offset, &fd);
 | 
						|
 | 
						|
	if(pread_first) {
 | 
						|
		if(pread(fd, data, blocksize, offset) < blocksize) {
 | 
						|
			perror("pread");
 | 
						|
			return -1;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if((mmapdata = minix_mmap(NULL, blocksize, PROT_READ, MAP_PRIVATE | MAP_FILE,
 | 
						|
		fd, offset)) == MAP_FAILED) {
 | 
						|
		perror("mmap");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	if(!pread_first) {
 | 
						|
		if(pread(fd, data, blocksize, offset) < blocksize) {
 | 
						|
			perror("pread");
 | 
						|
			return -1;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if(memcmp(mmapdata, data, blocksize)) {
 | 
						|
		fprintf(stderr, "readblock: mmap, pread mismatch\n");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	if(minix_munmap(mmapdata, blocksize) < 0) {
 | 
						|
		perror("munmap");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	return blocksize;
 | 
						|
}
 | 
						|
 | 
						|
void testend(void) { }
 | 
						|
 | 
						|
void basic_regression(void)
 | 
						|
{
 | 
						|
	void *block;
 | 
						|
#define BLOCKSIZE (PAGE_SIZE*10)
 | 
						|
	block = minix_mmap(0, BLOCKSIZE, PROT_READ | PROT_WRITE,
 | 
						|
		MAP_PRIVATE | MAP_ANON, -1, 0);
 | 
						|
 | 
						|
	if(block == MAP_FAILED) { e(1); exit(1); }
 | 
						|
 | 
						|
	memset(block, 0, BLOCKSIZE);
 | 
						|
 | 
						|
	/* shrink from bottom */
 | 
						|
	minix_munmap(block, PAGE_SIZE);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
main(int argc, char *argv[])
 | 
						|
{
 | 
						|
	int iter = 2;
 | 
						|
 | 
						|
	start(74);
 | 
						|
 | 
						|
	basic_regression();
 | 
						|
 | 
						|
	makefiles(MAXFILES);
 | 
						|
 | 
						|
	cachequiet(!bigflag);
 | 
						|
	if(bigflag) iter = 3;
 | 
						|
 | 
						|
	/* Try various combinations working set sizes
 | 
						|
	 * and block sizes in order to specifically 
 | 
						|
	 * target the primary cache, then primary+secondary
 | 
						|
	 * cache, then primary+secondary cache+secondary
 | 
						|
	 * cache eviction.
 | 
						|
	 */
 | 
						|
 | 
						|
	if(dotest(PAGE_SIZE,    100, iter)) e(5);
 | 
						|
	if(dotest(PAGE_SIZE*2,  100, iter)) e(2);
 | 
						|
	if(dotest(PAGE_SIZE*3,  100, iter)) e(3);
 | 
						|
	if(dotest(PAGE_SIZE,  20000, iter)) e(5);
 | 
						|
 | 
						|
	if(bigflag) {
 | 
						|
		u32_t totalmem, freemem, cachedmem;
 | 
						|
		if(dotest(PAGE_SIZE,  150000, iter)) e(5);
 | 
						|
		getmem(&totalmem, &freemem, &cachedmem);
 | 
						|
		if(dotest(PAGE_SIZE,  totalmem*1.5, iter)) e(6);
 | 
						|
	}
 | 
						|
 | 
						|
	quit();
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 |