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