1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Author: SeongJae Park <sj@kernel.org> 4 */ 5#define _GNU_SOURCE 6 7#include <fcntl.h> 8#include <stdbool.h> 9#include <stdint.h> 10#include <stdio.h> 11#include <stdlib.h> 12#include <sys/types.h> 13#include <sys/wait.h> 14#include <time.h> 15#include <unistd.h> 16 17#define DBGFS_MONITOR_ON "/sys/kernel/debug/damon/monitor_on_DEPRECATED" 18#define DBGFS_TARGET_IDS "/sys/kernel/debug/damon/target_ids" 19 20static void turn_damon_on_exit(void) 21{ 22 int target_ids_fd = open(DBGFS_TARGET_IDS, O_RDWR); 23 int monitor_on_fd = open(DBGFS_MONITOR_ON, O_RDWR); 24 char pid_str[128]; 25 26 snprintf(pid_str, sizeof(pid_str), "%d", getpid()); 27 write(target_ids_fd, pid_str, sizeof(pid_str)); 28 write(monitor_on_fd, "on\n", 3); 29 close(target_ids_fd); 30 close(monitor_on_fd); 31 usleep(1000); 32 exit(0); 33} 34 35static void try_race(void) 36{ 37 int target_ids_fd = open(DBGFS_TARGET_IDS, O_RDWR); 38 int pid = fork(); 39 int buf[256]; 40 41 if (pid < 0) { 42 fprintf(stderr, "fork() failed\n"); 43 exit(1); 44 } 45 if (pid == 0) 46 turn_damon_on_exit(); 47 while (true) { 48 int status; 49 50 read(target_ids_fd, buf, sizeof(buf)); 51 if (waitpid(-1, &status, WNOHANG) == pid) 52 break; 53 } 54 close(target_ids_fd); 55} 56 57static inline uint64_t ts_to_ms(struct timespec *ts) 58{ 59 return (uint64_t)ts->tv_sec * 1000 + (uint64_t)ts->tv_nsec / 1000000; 60} 61 62int main(int argc, char *argv[]) 63{ 64 struct timespec start_time, now; 65 int runtime_ms; 66 67 if (argc != 2) { 68 fprintf(stderr, "Usage: %s <runtime in ms>\n", argv[0]); 69 exit(1); 70 } 71 runtime_ms = atoi(argv[1]); 72 clock_gettime(CLOCK_MONOTONIC, &start_time); 73 while (true) { 74 try_race(); 75 clock_gettime(CLOCK_MONOTONIC, &now); 76 if (ts_to_ms(&now) - ts_to_ms(&start_time) > runtime_ms) 77 break; 78 } 79 return 0; 80} 81