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