add routine to fault in whole mapping in reverse
[trinity.git] / maps-fault.c
blobcf4043cce7c652e43bb58d62d97ef5b29e26130d
1 /*
2 * Routines to dirty/fault-in mapped pages.
3 */
5 #include <stdlib.h>
6 #include <string.h>
7 #include <sys/mman.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include "arch.h"
11 #include "maps.h"
12 #include "random.h"
13 #include "utils.h"
15 /*****************************************************************************/
16 /* dirty page routines */
18 static void dirty_one_page(struct map *map)
20 char *p = map->ptr;
22 p[rand() % map->size] = rand();
25 static void dirty_whole_mapping(struct map *map)
27 char *p = map->ptr;
28 unsigned int i;
30 for (i = 0; i < map->size; i += page_size)
31 p[i] = rand();
34 static void dirty_every_other_page(struct map *map)
36 char *p = map->ptr;
37 unsigned int i;
39 for (i = 0; i < map->size; i += (page_size * 2))
40 p[i] = rand();
43 static void dirty_mapping_reverse(struct map *map)
45 char *p = map->ptr;
46 unsigned int i;
48 for (i = (map->size - page_size); i > 0; i -= page_size)
49 p[i] = rand();
52 /* fault in a random set of map->size pages. (some may be faulted >once) */
53 static void dirty_random_pages(struct map *map)
55 char *p = map->ptr;
56 unsigned int i;
57 unsigned int num_pages = map->size / page_size;
59 for (i = 0; i < num_pages; i++)
60 p[(rand() % (num_pages + 1)) * page_size] = rand();
63 /* fault in the last page in a mapping
64 * Fill it with ascii, in the hope we do something like
65 * a strlen and go off the end. */
66 static void dirty_last_page(struct map *map)
68 char *p = map->ptr;
70 memset((void *) p + (map->size - page_size), 'A', page_size);
73 struct faultfn {
74 void (*func)(struct map *map);
77 /*****************************************************************************/
78 /* routines to fault in pages */
80 static void read_one_page(struct map *map)
82 char *p = map->ptr;
83 unsigned long offset = (rand() % map->size) & PAGE_MASK;
84 char buf[page_size];
86 p += offset;
87 memcpy(buf, p, page_size);
91 static void read_whole_mapping(struct map *map)
93 char *p = map->ptr;
94 unsigned int i;
95 char buf[page_size];
97 for (i = 0; i < map->size; i += page_size)
98 memcpy(buf, p + i, page_size);
101 static void read_every_other_page(struct map *map)
103 char *p = map->ptr;
104 unsigned int i;
105 char buf[page_size];
107 for (i = 0; i < map->size; i += (page_size * 2))
108 memcpy(buf, p + i, page_size);
111 static void read_mapping_reverse(struct map *map)
113 char *p = map->ptr;
114 unsigned int i;
115 char buf[page_size];
117 for (i = (map->size - page_size); i > 0; i -= page_size)
118 memcpy(buf, p + i, page_size);
122 /*****************************************************************************/
124 static const struct faultfn write_faultfns[] = {
125 { .func = dirty_one_page },
126 { .func = dirty_whole_mapping },
127 { .func = dirty_every_other_page },
128 { .func = dirty_mapping_reverse },
129 { .func = dirty_random_pages },
130 { .func = dirty_last_page },
133 static const struct faultfn read_faultfns[] = {
134 { .func = read_one_page },
135 { .func = read_whole_mapping },
136 { .func = read_every_other_page },
137 { .func = read_mapping_reverse },
141 * Routine to perform various kinds of write operations to a mapping
142 * that we created.
144 void dirty_mapping(struct map *map)
146 bool rw = rand_bool();
148 if (rw == TRUE) {
149 /* Check mapping is writable, or we'll segv.
150 * TODO: Perhaps we should do that, and trap it, mark it writable,
151 * then reprotect after we dirtied it ? */
152 if (!(map->prot & PROT_WRITE))
153 return;
155 write_faultfns[rand() % ARRAY_SIZE(write_faultfns)].func(map);
156 return;
157 } else {
158 if (!(map->prot & PROT_READ))
159 return;
161 read_faultfns[rand() % ARRAY_SIZE(read_faultfns)].func(map);