aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNamhoon Kim <namhoonk@cs.unc.edu>2016-05-03 15:01:14 -0400
committerNamhoon Kim <namhoonk@cs.unc.edu>2016-05-03 15:01:14 -0400
commite1e24f60f63ca339f91051e70d371e565547df96 (patch)
tree0c42c53a7196a0bfd53ab0a0dd32fa13a38883d6
parentcc61f79e3a7f5b28c8731d0e041dd57cdcd812ca (diff)
Add PGM^RT support
-rw-r--r--Makefile12
-rw-r--r--bin/mttest.c33
-rw-r--r--include/cache_common.h213
-rw-r--r--include/color_shm.h12
-rw-r--r--include/litmus.h12
-rw-r--r--src/color_shm.c42
-rw-r--r--src/syscalls.c11
7 files changed, 327 insertions, 8 deletions
diff --git a/Makefile b/Makefile
index 5ceaedf..b135529 100644
--- a/Makefile
+++ b/Makefile
@@ -73,7 +73,8 @@ AR := ${CROSS_COMPILE}${AR}
73 73
74all = lib ${rt-apps} 74all = lib ${rt-apps}
75rt-apps = cycles base_task rt_launch rtspin release_ts measure_syscall \ 75rt-apps = cycles base_task rt_launch rtspin release_ts measure_syscall \
76 base_mt_task uncache runtests resctrl mc2spin test1 mttest 76 base_mt_task uncache runtests resctrl mc2spin test1 mttest \
77 mc2thrash mc2shm mc2bench
77 78
78.PHONY: all lib clean dump-config TAGS tags cscope help doc 79.PHONY: all lib clean dump-config TAGS tags cscope help doc
79 80
@@ -254,6 +255,15 @@ lib-test1 = -lrt -static
254 255
255obj-mttest = mttest.o 256obj-mttest = mttest.o
256ldf-mttest = -pthread 257ldf-mttest = -pthread
258
259obj-mc2thrash = mc2thrash.o common.o
260lib-mc2thrash = -lrt -static
261
262obj-mc2shm = mc2shm.o common.o
263lib-mc2shm = -lrt -static
264
265obj-mc2bench = mc2bench.o common.o
266lib-mc2bench = -lrt -static
257# ############################################################################## 267# ##############################################################################
258# Build everything that depends on liblitmus. 268# Build everything that depends on liblitmus.
259 269
diff --git a/bin/mttest.c b/bin/mttest.c
index 7d573cc..d502778 100644
--- a/bin/mttest.c
+++ b/bin/mttest.c
@@ -101,7 +101,11 @@ int main(int argc, char** argv)
101 shm_info.bank = 0x000000ac; 101 shm_info.bank = 0x000000ac;
102 102
103 ret = ioctl(fd, SET_COLOR_SHM_CMD, &shm_info); 103 ret = ioctl(fd, SET_COLOR_SHM_CMD, &shm_info);
104 104 if (ret < 0) {
105 printf("ioctl failed.\n");
106 return -1;
107 }
108
105 shm = mmap(NULL, 6000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 109 shm = mmap(NULL, 6000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
106 if (shm == MAP_FAILED) { 110 if (shm == MAP_FAILED) {
107 printf("mmap failed.\n"); 111 printf("mmap failed.\n");
@@ -154,6 +158,8 @@ void* rt_thread(void *tcontext)
154 struct thread_context *ctx = (struct thread_context *) tcontext; 158 struct thread_context *ctx = (struct thread_context *) tcontext;
155 struct rt_task param; 159 struct rt_task param;
156 int ret; 160 int ret;
161 struct mc2_task mc2_param;
162 struct reservation_config res_config;
157 163
158 /* Set up task parameters */ 164 /* Set up task parameters */
159 init_rt_task_param(&param); 165 init_rt_task_param(&param);
@@ -173,11 +179,27 @@ void* rt_thread(void *tcontext)
173 /* Make presence visible. */ 179 /* Make presence visible. */
174 printf("RT Thread %d active.\n", ctx->id); 180 printf("RT Thread %d active.\n", ctx->id);
175 181
182 /* reservation config */
183 res_config.id = gettid();
184 res_config.polling_params.budget = ms2ns(EXEC_COST+1);
185 res_config.polling_params.period = param.period;
186 res_config.polling_params.offset = 0;
187 res_config.polling_params.relative_deadline = 0;
188 res_config.priority = LITMUS_MAX_PRIORITY;
189 res_config.cpu = ctx->cpu;
190 mc2_param.crit = CRIT_LEVEL_A;
191 mc2_param.res_id = gettid();
176 /***** 192 /*****
177 * 1) Initialize real-time settings. 193 * 1) Initialize real-time settings.
178 */ 194 */
179 CALL( init_rt_thread() ); 195 CALL( init_rt_thread() );
180 196
197 ret = reservation_create(PERIODIC_POLLING, &res_config);
198 if (ret < 0) {
199 printf("reservation failed.\n");
200 return NULL;
201 }
202
181 /* To specify a partition, do 203 /* To specify a partition, do
182 * 204 *
183 * param.cpu = CPU; 205 * param.cpu = CPU;
@@ -194,6 +216,7 @@ void* rt_thread(void *tcontext)
194 } 216 }
195 CALL( set_rt_task_param(gettid(), &param) ); 217 CALL( set_rt_task_param(gettid(), &param) );
196 218
219 CALL( set_mc2_task_param(gettid(), &mc2_param) );
197 /***** 220 /*****
198 * 2) Transition to real-time mode. 221 * 2) Transition to real-time mode.
199 */ 222 */
@@ -220,7 +243,7 @@ void* rt_thread(void *tcontext)
220 * 4) Transition to background mode. 243 * 4) Transition to background mode.
221 */ 244 */
222 CALL( task_mode(BACKGROUND_TASK) ); 245 CALL( task_mode(BACKGROUND_TASK) );
223 246 reservation_destroy(gettid(), res_config.cpu);
224 247
225 return NULL; 248 return NULL;
226} 249}
@@ -236,14 +259,14 @@ int job(struct thread_context *tcx)
236 259
237 if (tcx->id == 0) { 260 if (tcx->id == 0) {
238 printf("WRITE\n"); 261 printf("WRITE\n");
239 for (i=0; i<6000; i++) { 262 for (i=0; i<600; i++) {
240 buf[i] = rand()%255; 263 buf[i] = rand()%255;
241 printf("%x ",buf[i]); 264 printf("%x ",buf[i]);
242 } 265 }
243 printf("\n"); 266 printf("\n");
244 } else if (tcx->id == 1) { 267 } else if (tcx->id == 1) {
245 printf("READ\n"); 268 printf("READ\n");
246 for (i=0; i<6000; i++) { 269 for (i=0; i<600; i++) {
247 char t = buf[i]; 270 char t = buf[i];
248 printf("%x ", t); 271 printf("%x ", t);
249 } 272 }
@@ -251,7 +274,7 @@ int job(struct thread_context *tcx)
251 } 274 }
252 //test_call(0); 275 //test_call(0);
253 tcx->job_no++; 276 tcx->job_no++;
254 if (tcx->job_no == 1) 277 if (tcx->job_no == 10)
255 return 1; 278 return 1;
256 /* Don't exit. */ 279 /* Don't exit. */
257 return 0; 280 return 0;
diff --git a/include/cache_common.h b/include/cache_common.h
new file mode 100644
index 0000000..2957dd3
--- /dev/null
+++ b/include/cache_common.h
@@ -0,0 +1,213 @@
1#ifndef __CACHE_COMMON_H__
2#define __CACHE_COMMON_H__
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <time.h>
7#include <string.h>
8#include <assert.h>
9
10#include <signal.h>
11#include <sys/mman.h>
12#include <sys/types.h>
13#include <sys/stat.h>
14#include <fcntl.h>
15#include <unistd.h>
16
17#include <sys/io.h>
18#include <sys/utsname.h>
19
20#include <sched.h>
21#include <sys/time.h>
22#include <sys/resource.h>
23
24#include "litmus.h"
25#include "asm/cycles.h"
26
27#if defined(__i386__) || defined(__x86_64__)
28#include "asm/irq.h"
29#endif
30
31
32#define UNCACHE_DEV "/dev/litmus/uncache"
33
34static void die(char *error)
35{
36 fprintf(stderr, "Error: %s (errno: %m)\n",
37 error);
38 exit(1);
39}
40
41static int migrate_to(int cpu)
42{
43 int ret;
44
45 static __thread cpu_set_t* cpu_set = NULL;
46 static __thread size_t cpu_set_sz;
47 static __thread int num_cpus;
48 if(!cpu_set)
49 {
50 num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
51 cpu_set = CPU_ALLOC(num_cpus);
52 cpu_set_sz = CPU_ALLOC_SIZE(num_cpus);
53 }
54
55 CPU_ZERO_S(cpu_set_sz, cpu_set);
56 CPU_SET_S(cpu, cpu_set_sz, cpu_set);
57 ret = sched_setaffinity(0 /* self */, cpu_set_sz, cpu_set);
58 return ret;
59}
60
61static int check_migrations(int num_cpus)
62{
63 int cpu, err;
64
65 for (cpu = 0; cpu < num_cpus; cpu++) {
66 err = migrate_to(cpu);
67 if (err != 0) {
68 fprintf(stderr, "Migration to CPU %d failed: %m.\n",
69 cpu + 1);
70 return 1;
71 }
72 }
73 return 0;
74}
75
76static int become_posix_realtime_task(int prio)
77{
78 struct sched_param param;
79 memset(&param, 0, sizeof(param));
80 param.sched_priority = prio;
81 return sched_setscheduler(0 /* self */, SCHED_FIFO, &param);
82}
83
84static int renice(int nice_val)
85{
86 return setpriority(PRIO_PROCESS, 0 /* self */, nice_val);
87}
88
89static int lock_memory(void)
90{
91 return mlockall(MCL_CURRENT | MCL_FUTURE);
92}
93
94/* define CACHELINE_SIZE if not provided by compiler args */
95#ifndef CACHELINE_SIZE
96#if defined(__i386__) || defined(__x86_64__)
97/* recent intel cpus */
98#define CACHELINE_SIZE 64
99#elif defined(__arm__)
100/* at least with Cortex-A9 cpus ("8 words") */
101#define CACHELINE_SIZE 32
102#else
103#error "Could not determine cacheline size!"
104#endif
105#endif
106
107//#define INTS_IN_CACHELINE (CACHELINE_SIZE/sizeof(int))
108//typedef struct cacheline
109//{
110// int line[INTS_IN_CACHELINE];
111//} __attribute__((aligned(CACHELINE_SIZE))) cacheline_t;
112
113static cacheline_t* alloc_arena(size_t size, int use_huge_pages, int use_uncache_pages)
114{
115 int flags = MAP_PRIVATE | MAP_POPULATE;
116 cacheline_t* arena = NULL;
117 int fd;
118
119 if(use_huge_pages)
120 flags |= MAP_HUGETLB;
121
122 if(use_uncache_pages) {
123 fd = open(UNCACHE_DEV, O_RDWR);
124 if (fd == -1)
125 die("Failed to open uncache device. Are you running the LITMUS^RT kernel?");
126 }
127 else {
128 fd = -1;
129 flags |= MAP_ANONYMOUS;
130 }
131
132 arena = mmap(0, size, PROT_READ | PROT_WRITE, flags, fd, 0);
133
134 if(use_uncache_pages)
135 close(fd);
136
137 assert(arena);
138
139 return arena;
140}
141
142static void dealloc_arena(cacheline_t* arena, size_t size)
143{
144 int ret = munmap((void*)arena, size);
145 if(ret != 0)
146 die("munmap() error");
147}
148
149static int randrange(int min, int max)
150{
151 /* generate a random number on the range [min, max) w/o skew */
152 int limit = max - min;
153 int devisor = RAND_MAX/limit;
154 int retval;
155
156 do {
157 retval = rand() / devisor;
158 } while(retval == limit);
159 retval += min;
160
161 return retval;
162}
163
164static void init_arena(cacheline_t* arena, size_t size)
165{
166 int i;
167 size_t num_arena_elem = size / sizeof(cacheline_t);
168
169 /* Generate a cycle among the cache lines using Sattolo's algorithm.
170 Every int in the cache line points to the same cache line.
171 Note: Sequential walk doesn't care about these values. */
172 for (i = 0; i < num_arena_elem; i++) {
173 int j;
174 for(j = 0; j < INTS_IN_CACHELINE; ++j)
175 arena[i].line[j] = i;
176 }
177 while(1 < i--) {
178 int j = randrange(0, i);
179 cacheline_t temp = arena[j];
180 arena[j] = arena[i];
181 arena[i] = temp;
182 }
183}
184
185static void sleep_us(int microseconds)
186{
187 struct timespec delay;
188
189 delay.tv_sec = 0;
190 delay.tv_nsec = microseconds * 1000;
191 if (nanosleep(&delay, NULL) != 0)
192 die("sleep failed");
193}
194
195static int completed(int nSamples, int* history, int nCategories)
196{
197 int i;
198 for(i = 0; i < nCategories; ++i)
199 if(history[i] < nSamples)
200 return 0;
201 return 1;
202}
203
204inline unsigned long get_cyclecount (void)
205{
206 unsigned long value;
207 // Read CCNT Register
208 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
209 return value;
210}
211
212
213#endif
diff --git a/include/color_shm.h b/include/color_shm.h
index f6ad8a5..ffa90dd 100644
--- a/include/color_shm.h
+++ b/include/color_shm.h
@@ -1,3 +1,4 @@
1#include <sys/types.h>
1#include <sys/ioctl.h> 2#include <sys/ioctl.h>
2#include <fcntl.h> 3#include <fcntl.h>
3 4
@@ -8,6 +9,13 @@ struct color_ioctl_cmd {
8 unsigned int bank; 9 unsigned int bank;
9}; 10};
10 11
11#define SET_COLOR_SHM_CMD \ 12struct color_ioctl_offset {
12 _IOW(SHM_MAJOR, 0x1, struct color_ioctl_cmd) 13 unsigned long offset;
14 int lock;
15};
16
17#define SET_COLOR_SHM_CMD _IOW(SHM_MAJOR, 0x1, struct color_ioctl_cmd)
18#define SET_COLOR_SHM_OFFSET _IOW(SHM_MAJOR, 0x2, struct color_ioctl_offset)
19
20void* color_mmap(size_t size, struct color_ioctl_cmd cmd, struct color_ioctl_offset offset);
13 21
diff --git a/include/litmus.h b/include/litmus.h
index aaa8d1c..4a4ea39 100644
--- a/include/litmus.h
+++ b/include/litmus.h
@@ -48,6 +48,14 @@ extern "C" {
48 */ 48 */
49#define SCHED_LITMUS 7 49#define SCHED_LITMUS 7
50 50
51#define CACHELINE_SIZE 32
52#define INTS_IN_CACHELINE (CACHELINE_SIZE/sizeof(int))
53#define CACHELINES_IN_1KB (1024 / sizeof(cacheline_t))
54typedef struct cacheline
55{
56 int line[INTS_IN_CACHELINE];
57} __attribute__((aligned(CACHELINE_SIZE))) cacheline_t;
58
51/** 59/**
52 * Initialise a real-time task param struct 60 * Initialise a real-time task param struct
53 * @param param Pointer to the struct to initialise 61 * @param param Pointer to the struct to initialise
@@ -440,6 +448,10 @@ int set_page_color(int cpu);
440 448
441int test_call(unsigned int param); 449int test_call(unsigned int param);
442 450
451int run_bench(int type, int size, cacheline_t *src, cacheline_t *dst, lt_t __user *ts);
452
453int lock_buffer(void* vaddr, size_t size, unsigned int lock_way, unsigned int unlock_way);
454
443#ifdef __cplusplus 455#ifdef __cplusplus
444} 456}
445#endif 457#endif
diff --git a/src/color_shm.c b/src/color_shm.c
new file mode 100644
index 0000000..15332aa
--- /dev/null
+++ b/src/color_shm.c
@@ -0,0 +1,42 @@
1#include <sys/mman.h>
2#include <stdio.h>
3#include <unistd.h>
4
5#include "color_shm.h"
6
7void* color_mmap(size_t size, struct color_ioctl_cmd cmd, struct color_ioctl_offset offset)
8{
9 int ret, fd;
10 void *mem;
11
12 fd = open("/dev/litmus/color_shm", O_RDWR);
13 if (fd < 0) {
14 printf("Device open error.\n");
15 return NULL;
16 }
17
18 ret = ioctl(fd, SET_COLOR_SHM_CMD, &cmd);
19 if (ret < 0) {
20 printf("ioctl failed.\n");
21 return NULL;
22 }
23
24 ret = ioctl(fd, SET_COLOR_SHM_OFFSET, &offset);
25 if (ret < 0) {
26 printf("ioctl failed.\n");
27 return NULL;
28 }
29
30 size += offset.offset;
31 mem = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
32 if (mem == MAP_FAILED) {
33 printf("mmap failed.\n");
34 return MAP_FAILED;
35 }
36 close(fd);
37
38 mem += offset.offset;
39
40 return mem;
41}
42
diff --git a/src/syscalls.c b/src/syscalls.c
index ab064ad..a4cec67 100644
--- a/src/syscalls.c
+++ b/src/syscalls.c
@@ -111,3 +111,14 @@ int test_call(unsigned int param)
111{ 111{
112 return syscall(__NR_test_call, param); 112 return syscall(__NR_test_call, param);
113} 113}
114
115int run_bench(int type, int wss, cacheline_t *src, cacheline_t *dst, lt_t *ts)
116{
117 return syscall(__NR_run_test, type, wss, src, dst, ts);
118}
119
120int lock_buffer(void* vaddr, size_t size, unsigned int lock_way, unsigned int unlock_way)
121{
122 return syscall(__NR_lock_buffer, vaddr, size, lock_way, unlock_way);
123}
124