os-linux.h revision ff2451922f21826c2047208c2c3963843b1ffdcc
1#ifndef FIO_OS_LINUX_H 2#define FIO_OS_LINUX_H 3 4#include <sys/ioctl.h> 5#include <sys/uio.h> 6#include <sys/syscall.h> 7#include <sys/vfs.h> 8#include <unistd.h> 9#include <fcntl.h> 10#include <errno.h> 11#include <sched.h> 12#include <linux/unistd.h> 13#include <linux/raw.h> 14#include <linux/major.h> 15#include <endian.h> 16 17#include "indirect.h" 18#include "binject.h" 19#include "../file.h" 20 21#define FIO_HAVE_LIBAIO 22#define FIO_HAVE_POSIXAIO 23#define FIO_HAVE_FADVISE 24#define FIO_HAVE_CPU_AFFINITY 25#define FIO_HAVE_DISK_UTIL 26#define FIO_HAVE_SGIO 27#define FIO_HAVE_IOPRIO 28#define FIO_HAVE_SPLICE 29#define FIO_HAVE_IOSCHED_SWITCH 30#define FIO_HAVE_ODIRECT 31#define FIO_HAVE_HUGETLB 32#define FIO_HAVE_RAWBIND 33#define FIO_HAVE_BLKTRACE 34#define FIO_HAVE_STRSEP 35#define FIO_HAVE_FALLOCATE 36#define FIO_HAVE_POSIXAIO_FSYNC 37#define FIO_HAVE_PSHARED_MUTEX 38#define FIO_HAVE_CL_SIZE 39#define FIO_HAVE_CGROUPS 40#define FIO_HAVE_FDATASYNC 41#define FIO_HAVE_FS_STAT 42#define FIO_HAVE_TRIM 43#define FIO_HAVE_BINJECT 44#define FIO_HAVE_CLOCK_MONOTONIC 45#define FIO_HAVE_GETTID 46 47/* 48 * Can only enable this for newer glibcs, or the header and defines are 49 * missing 50 */ 51#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 6 52#define FIO_HAVE_LINUX_FALLOCATE 53#endif 54 55#ifdef SYNC_FILE_RANGE_WAIT_BEFORE 56#define FIO_HAVE_SYNC_FILE_RANGE 57#endif 58 59#define OS_MAP_ANON MAP_ANONYMOUS 60 61#ifndef CLOCK_MONOTONIC 62#define CLOCK_MONOTONIC 1 63#endif 64 65typedef cpu_set_t os_cpu_mask_t; 66 67typedef struct drand48_data os_random_state_t; 68 69/* 70 * we want fadvise64 really, but it's so tangled... later 71 */ 72#ifdef FIO_HAVE_FADVISE 73#define fadvise(fd, off, len, advice) \ 74 posix_fadvise((fd), (off_t)(off), (len), (advice)) 75#endif 76 77/* 78 * If you are on an ancient glibc (2.3.2), then define GLIBC_2_3_2 if you want 79 * the affinity helpers to work. 80 */ 81#ifndef GLIBC_2_3_2 82#define fio_setaffinity(pid, cpumask) \ 83 sched_setaffinity((pid), sizeof(cpumask), &(cpumask)) 84#define fio_getaffinity(pid, ptr) \ 85 sched_getaffinity((pid), sizeof(cpu_set_t), (ptr)) 86#else 87#define fio_setaffinity(pid, cpumask) \ 88 sched_setaffinity((pid), &(cpumask)) 89#define fio_getaffinity(pid, ptr) \ 90 sched_getaffinity((pid), (ptr)) 91#endif 92 93#define fio_cpu_clear(mask, cpu) CPU_CLR((cpu), (mask)) 94#define fio_cpu_set(mask, cpu) CPU_SET((cpu), (mask)) 95 96static inline int fio_cpuset_init(os_cpu_mask_t *mask) 97{ 98 CPU_ZERO(mask); 99 return 0; 100} 101 102static inline int fio_cpuset_exit(os_cpu_mask_t *mask) 103{ 104 return 0; 105} 106 107#define FIO_MAX_CPUS CPU_SETSIZE 108 109static inline int ioprio_set(int which, int who, int ioprio) 110{ 111 return syscall(__NR_ioprio_set, which, who, ioprio); 112} 113 114static inline int gettid(void) 115{ 116 return syscall(__NR_gettid); 117} 118 119/* 120 * Just check for SPLICE_F_MOVE, if that isn't there, assume the others 121 * aren't either. 122 */ 123#ifndef SPLICE_F_MOVE 124#define SPLICE_F_MOVE (0x01) /* move pages instead of copying */ 125#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */ 126 /* we may still block on the fd we splice */ 127 /* from/to, of course */ 128#define SPLICE_F_MORE (0x04) /* expect more data */ 129#define SPLICE_F_GIFT (0x08) /* pages passed in are a gift */ 130 131static inline int splice(int fdin, loff_t *off_in, int fdout, loff_t *off_out, 132 size_t len, unsigned int flags) 133{ 134 return syscall(__NR_sys_splice, fdin, off_in, fdout, off_out, len, flags); 135} 136 137static inline int tee(int fdin, int fdout, size_t len, unsigned int flags) 138{ 139 return syscall(__NR_sys_tee, fdin, fdout, len, flags); 140} 141 142static inline int vmsplice(int fd, const struct iovec *iov, 143 unsigned long nr_segs, unsigned int flags) 144{ 145 return syscall(__NR_sys_vmsplice, fd, iov, nr_segs, flags); 146} 147#endif 148 149#define SPLICE_DEF_SIZE (64*1024) 150 151#ifdef FIO_HAVE_SYSLET 152 153struct syslet_uatom; 154struct async_head_user; 155 156/* 157 * syslet stuff 158 */ 159static inline struct syslet_uatom * 160async_exec(struct syslet_uatom *atom, struct async_head_user *ahu) 161{ 162 return (struct syslet_uatom *) syscall(__NR_async_exec, atom, ahu); 163} 164 165static inline long 166async_wait(unsigned long min_wait_events, unsigned long user_ring_idx, 167 struct async_head_user *ahu) 168{ 169 return syscall(__NR_async_wait, min_wait_events, 170 user_ring_idx, ahu); 171} 172 173static inline long async_thread(void *event, struct async_head_user *ahu) 174{ 175 return syscall(__NR_async_thread, event, ahu); 176} 177 178static inline long umem_add(unsigned long *uptr, unsigned long inc) 179{ 180 return syscall(__NR_umem_add, uptr, inc); 181} 182#endif /* FIO_HAVE_SYSLET */ 183 184enum { 185 IOPRIO_CLASS_NONE, 186 IOPRIO_CLASS_RT, 187 IOPRIO_CLASS_BE, 188 IOPRIO_CLASS_IDLE, 189}; 190 191enum { 192 IOPRIO_WHO_PROCESS = 1, 193 IOPRIO_WHO_PGRP, 194 IOPRIO_WHO_USER, 195}; 196 197#define IOPRIO_BITS 16 198#define IOPRIO_CLASS_SHIFT 13 199 200#ifndef BLKGETSIZE64 201#define BLKGETSIZE64 _IOR(0x12,114,size_t) 202#endif 203 204#ifndef BLKFLSBUF 205#define BLKFLSBUF _IO(0x12,97) 206#endif 207 208#ifndef BLKDISCARD 209#define BLKDISCARD _IO(0x12,119) 210#endif 211 212static inline int blockdev_invalidate_cache(struct fio_file *f) 213{ 214 return ioctl(f->fd, BLKFLSBUF); 215} 216 217static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes) 218{ 219 if (!ioctl(f->fd, BLKGETSIZE64, bytes)) 220 return 0; 221 222 return errno; 223} 224 225static inline unsigned long long os_phys_mem(void) 226{ 227 long pagesize, pages; 228 229 pagesize = sysconf(_SC_PAGESIZE); 230 pages = sysconf(_SC_PHYS_PAGES); 231 if (pages == -1 || pagesize == -1) 232 return 0; 233 234 return (unsigned long long) pages * (unsigned long long) pagesize; 235} 236 237static inline void os_random_seed(unsigned long seed, os_random_state_t *rs) 238{ 239 srand48_r(seed, rs); 240} 241 242static inline long os_random_long(os_random_state_t *rs) 243{ 244 long val; 245 246 lrand48_r(rs, &val); 247 return val; 248} 249 250static inline int fio_lookup_raw(dev_t dev, int *majdev, int *mindev) 251{ 252 struct raw_config_request rq; 253 int fd; 254 255 if (major(dev) != RAW_MAJOR) 256 return 1; 257 258 /* 259 * we should be able to find /dev/rawctl or /dev/raw/rawctl 260 */ 261 fd = open("/dev/rawctl", O_RDONLY); 262 if (fd < 0) { 263 fd = open("/dev/raw/rawctl", O_RDONLY); 264 if (fd < 0) 265 return 1; 266 } 267 268 rq.raw_minor = minor(dev); 269 if (ioctl(fd, RAW_GETBIND, &rq) < 0) { 270 close(fd); 271 return 1; 272 } 273 274 close(fd); 275 *majdev = rq.block_major; 276 *mindev = rq.block_minor; 277 return 0; 278} 279 280#ifdef O_NOATIME 281#define FIO_O_NOATIME O_NOATIME 282#else 283#define FIO_O_NOATIME 0 284#endif 285 286#ifdef MADV_REMOVE 287#define FIO_MADV_FREE MADV_REMOVE 288#endif 289 290#if __BYTE_ORDER == __LITTLE_ENDIAN 291#define FIO_LITTLE_ENDIAN 292#elif __BYTE_ORDER == __BIG_ENDIAN 293#define FIO_BIG_ENDIAN 294#else 295#error "Unknown endianness" 296#endif 297 298#define fio_swap16(x) __bswap_16(x) 299#define fio_swap32(x) __bswap_32(x) 300#define fio_swap64(x) __bswap_64(x) 301 302#define CACHE_LINE_FILE \ 303 "/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size" 304 305static inline int arch_cache_line_size(void) 306{ 307 char size[32]; 308 int fd, ret; 309 310 fd = open(CACHE_LINE_FILE, O_RDONLY); 311 if (fd < 0) 312 return -1; 313 314 ret = read(fd, size, sizeof(size)); 315 316 close(fd); 317 318 if (ret <= 0) 319 return -1; 320 else 321 return atoi(size); 322} 323 324static inline unsigned long long get_fs_size(const char *path) 325{ 326 unsigned long long ret; 327 struct statfs s; 328 329 if (statfs(path, &s) < 0) 330 return -1ULL; 331 332 ret = s.f_bsize; 333 ret *= (unsigned long long) s.f_bfree; 334 return ret; 335} 336 337static inline int os_trim(int fd, unsigned long long start, 338 unsigned long long len) 339{ 340 uint64_t range[2]; 341 342 range[0] = start; 343 range[1] = len; 344 345 if (!ioctl(fd, BLKDISCARD, range)) 346 return 0; 347 348 return errno; 349} 350 351#endif 352