os-linux.h revision c2acfbac7e9eb8ac5407ac024c0fd000614c77e2
1#ifndef FIO_OS_LINUX_H 2#define FIO_OS_LINUX_H 3 4#define FIO_OS os_linux 5 6#include <sys/ioctl.h> 7#include <sys/uio.h> 8#include <sys/syscall.h> 9#include <sys/vfs.h> 10#include <sys/mman.h> 11#include <unistd.h> 12#include <fcntl.h> 13#include <errno.h> 14#include <sched.h> 15#include <linux/unistd.h> 16#include <linux/raw.h> 17#include <linux/major.h> 18 19#include "binject.h" 20#include "../file.h" 21 22#define FIO_HAVE_CPU_AFFINITY 23#define FIO_HAVE_DISK_UTIL 24#define FIO_HAVE_SGIO 25#define FIO_HAVE_IOPRIO 26#define FIO_HAVE_IOSCHED_SWITCH 27#define FIO_HAVE_ODIRECT 28#define FIO_HAVE_HUGETLB 29#define FIO_HAVE_RAWBIND 30#define FIO_HAVE_BLKTRACE 31#define FIO_HAVE_PSHARED_MUTEX 32#define FIO_HAVE_CL_SIZE 33#define FIO_HAVE_CGROUPS 34#define FIO_HAVE_FS_STAT 35#define FIO_HAVE_TRIM 36#define FIO_HAVE_BINJECT 37#define FIO_HAVE_GETTID 38#define FIO_USE_GENERIC_INIT_RANDOM_STATE 39 40#ifdef MAP_HUGETLB 41#define FIO_HAVE_MMAP_HUGE 42#endif 43 44#define OS_MAP_ANON MAP_ANONYMOUS 45 46typedef cpu_set_t os_cpu_mask_t; 47 48typedef struct drand48_data os_random_state_t; 49 50#ifdef CONFIG_3ARG_AFFINITY 51#define fio_setaffinity(pid, cpumask) \ 52 sched_setaffinity((pid), sizeof(cpumask), &(cpumask)) 53#define fio_getaffinity(pid, ptr) \ 54 sched_getaffinity((pid), sizeof(cpu_set_t), (ptr)) 55#elif defined(CONFIG_2ARG_AFFINITY) 56#define fio_setaffinity(pid, cpumask) \ 57 sched_setaffinity((pid), &(cpumask)) 58#define fio_getaffinity(pid, ptr) \ 59 sched_getaffinity((pid), (ptr)) 60#endif 61 62#define fio_cpu_clear(mask, cpu) (void) CPU_CLR((cpu), (mask)) 63#define fio_cpu_set(mask, cpu) (void) CPU_SET((cpu), (mask)) 64#define fio_cpu_count(maks) CPU_COUNT((mask)) 65 66static inline int fio_cpuset_init(os_cpu_mask_t *mask) 67{ 68 CPU_ZERO(mask); 69 return 0; 70} 71 72static inline int fio_cpuset_exit(os_cpu_mask_t *mask) 73{ 74 return 0; 75} 76 77#define FIO_MAX_CPUS CPU_SETSIZE 78 79enum { 80 IOPRIO_CLASS_NONE, 81 IOPRIO_CLASS_RT, 82 IOPRIO_CLASS_BE, 83 IOPRIO_CLASS_IDLE, 84}; 85 86enum { 87 IOPRIO_WHO_PROCESS = 1, 88 IOPRIO_WHO_PGRP, 89 IOPRIO_WHO_USER, 90}; 91 92#define IOPRIO_BITS 16 93#define IOPRIO_CLASS_SHIFT 13 94 95static inline int ioprio_set(int which, int who, int ioprio_class, int ioprio) 96{ 97 /* 98 * If no class is set, assume BE 99 */ 100 if (!ioprio_class) 101 ioprio_class = IOPRIO_CLASS_BE; 102 103 ioprio |= ioprio_class << IOPRIO_CLASS_SHIFT; 104 return syscall(__NR_ioprio_set, which, who, ioprio); 105} 106 107static inline int gettid(void) 108{ 109 return syscall(__NR_gettid); 110} 111 112#define SPLICE_DEF_SIZE (64*1024) 113 114#ifndef BLKGETSIZE64 115#define BLKGETSIZE64 _IOR(0x12,114,size_t) 116#endif 117 118#ifndef BLKFLSBUF 119#define BLKFLSBUF _IO(0x12,97) 120#endif 121 122#ifndef BLKDISCARD 123#define BLKDISCARD _IO(0x12,119) 124#endif 125 126static inline int blockdev_invalidate_cache(struct fio_file *f) 127{ 128 return ioctl(f->fd, BLKFLSBUF); 129} 130 131static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes) 132{ 133 if (!ioctl(f->fd, BLKGETSIZE64, bytes)) 134 return 0; 135 136 return errno; 137} 138 139static inline unsigned long long os_phys_mem(void) 140{ 141 long pagesize, pages; 142 143 pagesize = sysconf(_SC_PAGESIZE); 144 pages = sysconf(_SC_PHYS_PAGES); 145 if (pages == -1 || pagesize == -1) 146 return 0; 147 148 return (unsigned long long) pages * (unsigned long long) pagesize; 149} 150 151static inline void os_random_seed(unsigned long seed, os_random_state_t *rs) 152{ 153 srand48_r(seed, rs); 154} 155 156static inline long os_random_long(os_random_state_t *rs) 157{ 158 long val; 159 160 lrand48_r(rs, &val); 161 return val; 162} 163 164static inline int fio_lookup_raw(dev_t dev, int *majdev, int *mindev) 165{ 166 struct raw_config_request rq; 167 int fd; 168 169 if (major(dev) != RAW_MAJOR) 170 return 1; 171 172 /* 173 * we should be able to find /dev/rawctl or /dev/raw/rawctl 174 */ 175 fd = open("/dev/rawctl", O_RDONLY); 176 if (fd < 0) { 177 fd = open("/dev/raw/rawctl", O_RDONLY); 178 if (fd < 0) 179 return 1; 180 } 181 182 rq.raw_minor = minor(dev); 183 if (ioctl(fd, RAW_GETBIND, &rq) < 0) { 184 close(fd); 185 return 1; 186 } 187 188 close(fd); 189 *majdev = rq.block_major; 190 *mindev = rq.block_minor; 191 return 0; 192} 193 194#ifdef O_NOATIME 195#define FIO_O_NOATIME O_NOATIME 196#else 197#define FIO_O_NOATIME 0 198#endif 199 200#ifdef O_ATOMIC 201#define OS_O_ATOMIC O_ATOMIC 202#else 203#define OS_O_ATOMIC 040000000 204#endif 205 206#ifdef MADV_REMOVE 207#define FIO_MADV_FREE MADV_REMOVE 208#endif 209 210#define fio_swap16(x) __bswap_16(x) 211#define fio_swap32(x) __bswap_32(x) 212#define fio_swap64(x) __bswap_64(x) 213 214#define CACHE_LINE_FILE \ 215 "/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size" 216 217static inline int arch_cache_line_size(void) 218{ 219 char size[32]; 220 int fd, ret; 221 222 fd = open(CACHE_LINE_FILE, O_RDONLY); 223 if (fd < 0) 224 return -1; 225 226 ret = read(fd, size, sizeof(size)); 227 228 close(fd); 229 230 if (ret <= 0) 231 return -1; 232 else 233 return atoi(size); 234} 235 236static inline unsigned long long get_fs_size(const char *path) 237{ 238 unsigned long long ret; 239 struct statfs s; 240 241 if (statfs(path, &s) < 0) 242 return -1ULL; 243 244 ret = s.f_bsize; 245 ret *= (unsigned long long) s.f_bfree; 246 return ret; 247} 248 249static inline int os_trim(int fd, unsigned long long start, 250 unsigned long long len) 251{ 252 uint64_t range[2]; 253 254 range[0] = start; 255 range[1] = len; 256 257 if (!ioctl(fd, BLKDISCARD, range)) 258 return 0; 259 260 return errno; 261} 262 263#ifdef CONFIG_SCHED_IDLE 264static inline int fio_set_sched_idle(void) 265{ 266 struct sched_param p = { .sched_priority = 0, }; 267 return sched_setscheduler(gettid(), SCHED_IDLE, &p); 268} 269#endif 270 271#endif 272