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