os-linux.h revision a1c58075279454a91ec43366846b93e8dcf9753c
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 <unistd.h> 8#include <fcntl.h> 9#include <errno.h> 10#include <linux/unistd.h> 11#include <linux/raw.h> 12#include <linux/major.h> 13 14#include "indirect.h" 15 16#define FIO_HAVE_LIBAIO 17#define FIO_HAVE_POSIXAIO 18#define FIO_HAVE_FADVISE 19#define FIO_HAVE_CPU_AFFINITY 20#define FIO_HAVE_DISK_UTIL 21#define FIO_HAVE_SGIO 22#define FIO_HAVE_IOPRIO 23#define FIO_HAVE_SPLICE 24#define FIO_HAVE_IOSCHED_SWITCH 25#define FIO_HAVE_ODIRECT 26#define FIO_HAVE_HUGETLB 27#define FIO_HAVE_RAWBIND 28#define FIO_HAVE_BLKTRACE 29#define FIO_HAVE_STRSEP 30#define FIO_HAVE_FALLOCATE 31#define FIO_HAVE_POSIXAIO_FSYNC 32#define FIO_HAVE_PSHARED_MUTEX 33#define FIO_HAVE_CL_SIZE 34 35#define OS_MAP_ANON MAP_ANONYMOUS 36 37#ifndef CLOCK_MONOTONIC 38#define CLOCK_MONOTONIC 1 39#endif 40 41typedef cpu_set_t os_cpu_mask_t; 42 43typedef struct drand48_data os_random_state_t; 44 45/* 46 * we want fadvise64 really, but it's so tangled... later 47 */ 48#ifdef FIO_HAVE_FADVISE 49#define fadvise(fd, off, len, advice) \ 50 posix_fadvise((fd), (off_t)(off), (len), (advice)) 51#endif 52 53/* 54 * If you are on an ancient glibc (2.3.2), then define GLIBC_2_3_2 if you want 55 * the affinity helpers to work. 56 */ 57#ifndef GLIBC_2_3_2 58#define fio_setaffinity(pid, cpumask) \ 59 sched_setaffinity((pid), sizeof(cpumask), &(cpumask)) 60#define fio_getaffinity(pid, ptr) \ 61 sched_getaffinity((pid), sizeof(cpu_set_t), (ptr)) 62#else 63#define fio_setaffinity(pid, cpumask) \ 64 sched_setaffinity((pid), &(cpumask)) 65#define fio_getaffinity(pid, ptr) \ 66 sched_getaffinity((pid), (ptr)) 67#endif 68 69#define fio_cpu_clear(mask, cpu) CPU_CLR((cpu), (mask)) 70#define fio_cpu_set(mask, cpu) CPU_SET((cpu), (mask)) 71 72static inline int fio_cpuset_init(os_cpu_mask_t *mask) 73{ 74 CPU_ZERO(mask); 75 return 0; 76} 77 78static inline int fio_cpuset_exit(os_cpu_mask_t *mask) 79{ 80 return 0; 81} 82 83#define FIO_MAX_CPUS CPU_SETSIZE 84 85static inline int ioprio_set(int which, int who, int ioprio) 86{ 87 return syscall(__NR_ioprio_set, which, who, ioprio); 88} 89 90/* 91 * Just check for SPLICE_F_MOVE, if that isn't there, assume the others 92 * aren't either. 93 */ 94#ifndef SPLICE_F_MOVE 95#define SPLICE_F_MOVE (0x01) /* move pages instead of copying */ 96#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */ 97 /* we may still block on the fd we splice */ 98 /* from/to, of course */ 99#define SPLICE_F_MORE (0x04) /* expect more data */ 100#define SPLICE_F_GIFT (0x08) /* pages passed in are a gift */ 101 102static inline int splice(int fdin, loff_t *off_in, int fdout, loff_t *off_out, 103 size_t len, unsigned int flags) 104{ 105 return syscall(__NR_sys_splice, fdin, off_in, fdout, off_out, len, flags); 106} 107 108static inline int tee(int fdin, int fdout, size_t len, unsigned int flags) 109{ 110 return syscall(__NR_sys_tee, fdin, fdout, len, flags); 111} 112 113static inline int vmsplice(int fd, const struct iovec *iov, 114 unsigned long nr_segs, unsigned int flags) 115{ 116 return syscall(__NR_sys_vmsplice, fd, iov, nr_segs, flags); 117} 118#endif 119 120#define SPLICE_DEF_SIZE (64*1024) 121 122#ifdef FIO_HAVE_SYSLET 123 124struct syslet_uatom; 125struct async_head_user; 126 127/* 128 * syslet stuff 129 */ 130static inline struct syslet_uatom * 131async_exec(struct syslet_uatom *atom, struct async_head_user *ahu) 132{ 133 return (struct syslet_uatom *) syscall(__NR_async_exec, atom, ahu); 134} 135 136static inline long 137async_wait(unsigned long min_wait_events, unsigned long user_ring_idx, 138 struct async_head_user *ahu) 139{ 140 return syscall(__NR_async_wait, min_wait_events, 141 user_ring_idx, ahu); 142} 143 144static inline long async_thread(void *event, struct async_head_user *ahu) 145{ 146 return syscall(__NR_async_thread, event, ahu); 147} 148 149static inline long umem_add(unsigned long *uptr, unsigned long inc) 150{ 151 return syscall(__NR_umem_add, uptr, inc); 152} 153#endif /* FIO_HAVE_SYSLET */ 154 155enum { 156 IOPRIO_CLASS_NONE, 157 IOPRIO_CLASS_RT, 158 IOPRIO_CLASS_BE, 159 IOPRIO_CLASS_IDLE, 160}; 161 162enum { 163 IOPRIO_WHO_PROCESS = 1, 164 IOPRIO_WHO_PGRP, 165 IOPRIO_WHO_USER, 166}; 167 168#define IOPRIO_BITS 16 169#define IOPRIO_CLASS_SHIFT 13 170 171#ifndef BLKGETSIZE64 172#define BLKGETSIZE64 _IOR(0x12,114,size_t) 173#endif 174 175#ifndef BLKFLSBUF 176#define BLKFLSBUF _IO(0x12,97) 177#endif 178 179static inline int blockdev_invalidate_cache(int fd) 180{ 181 return ioctl(fd, BLKFLSBUF); 182} 183 184static inline int blockdev_size(int fd, unsigned long long *bytes) 185{ 186 if (!ioctl(fd, BLKGETSIZE64, bytes)) 187 return 0; 188 189 return errno; 190} 191 192static inline unsigned long long os_phys_mem(void) 193{ 194 long pagesize, pages; 195 196 pagesize = sysconf(_SC_PAGESIZE); 197 pages = sysconf(_SC_PHYS_PAGES); 198 if (pages == -1 || pagesize == -1) 199 return 0; 200 201 return (unsigned long long) pages * (unsigned long long) pagesize; 202} 203 204static inline void os_random_seed(unsigned long seed, os_random_state_t *rs) 205{ 206 srand48_r(seed, rs); 207} 208 209static inline long os_random_long(os_random_state_t *rs) 210{ 211 long val; 212 213 lrand48_r(rs, &val); 214 return val; 215} 216 217static inline int fio_lookup_raw(dev_t dev, int *majdev, int *mindev) 218{ 219 struct raw_config_request rq; 220 int fd; 221 222 if (major(dev) != RAW_MAJOR) 223 return 1; 224 225 /* 226 * we should be able to find /dev/rawctl or /dev/raw/rawctl 227 */ 228 fd = open("/dev/rawctl", O_RDONLY); 229 if (fd < 0) { 230 fd = open("/dev/raw/rawctl", O_RDONLY); 231 if (fd < 0) 232 return 1; 233 } 234 235 rq.raw_minor = minor(dev); 236 if (ioctl(fd, RAW_GETBIND, &rq) < 0) { 237 close(fd); 238 return 1; 239 } 240 241 close(fd); 242 *majdev = rq.block_major; 243 *mindev = rq.block_minor; 244 return 0; 245} 246 247#ifdef O_NOATIME 248#define FIO_O_NOATIME O_NOATIME 249#else 250#define FIO_O_NOATIME 0 251#endif 252 253#ifdef MADV_REMOVE 254#define FIO_MADV_FREE MADV_REMOVE 255#endif 256 257#define CACHE_LINE_FILE \ 258 "/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size" 259 260static inline int arch_cache_line_size(void) 261{ 262 char size[32]; 263 int fd, ret; 264 265 fd = open(CACHE_LINE_FILE, O_RDONLY); 266 if (fd < 0) 267 return -1; 268 269 ret = read(fd, size, sizeof(size)); 270 271 close(fd); 272 273 if (ret <= 0) 274 return -1; 275 else 276 return atoi(size); 277} 278 279#endif 280