cregit-Linux how code gets into the kernel

Release 4.16 tools/virtio/ringtest/main.h

/*
 * Copyright (C) 2016 Red Hat, Inc.
 * Author: Michael S. Tsirkin <mst@redhat.com>
 * This work is licensed under the terms of the GNU GPL, version 2.
 *
 * Common macros and functions for ring benchmarking.
 */
#ifndef MAIN_H

#define MAIN_H

#include <stdbool.h>

extern int param;

extern bool do_exit;

#if defined(__x86_64__) || defined(__i386__)
#include "x86intrin.h"


static inline void wait_cycles(unsigned long long cycles) { unsigned long long t; t = __rdtsc(); while (__rdtsc() - t < cycles) {} }

Contributors

PersonTokensPropCommitsCommitProp
Michael S. Tsirkin32100.00%1100.00%
Total32100.00%1100.00%

#define VMEXIT_CYCLES 500 #define VMENTRY_CYCLES 500 #elif defined(__s390x__)
static inline void wait_cycles(unsigned long long cycles) { asm volatile("0: brctg %0,0b" : : "d" (cycles)); }

Contributors

PersonTokensPropCommitsCommitProp
Halil Pasic15100.00%1100.00%
Total15100.00%1100.00%

/* tweak me */ #define VMEXIT_CYCLES 200 #define VMENTRY_CYCLES 200 #else
static inline void wait_cycles(unsigned long long cycles) { _Exit(5); }

Contributors

PersonTokensPropCommitsCommitProp
Michael S. Tsirkin17100.00%1100.00%
Total17100.00%1100.00%

#define VMEXIT_CYCLES 0 #define VMENTRY_CYCLES 0 #endif
static inline void vmexit(void) { if (!do_exit) return; wait_cycles(VMEXIT_CYCLES); }

Contributors

PersonTokensPropCommitsCommitProp
Michael S. Tsirkin20100.00%1100.00%
Total20100.00%1100.00%


static inline void vmentry(void) { if (!do_exit) return; wait_cycles(VMENTRY_CYCLES); }

Contributors

PersonTokensPropCommitsCommitProp
Michael S. Tsirkin20100.00%1100.00%
Total20100.00%1100.00%

/* implemented by ring */ void alloc_ring(void); /* guest side */ int add_inbuf(unsigned, void *, void *); void *get_buf(unsigned *, void **); void disable_call(); bool used_empty(); bool enable_call(); void kick_available(); /* host side */ void disable_kick(); bool avail_empty(); bool enable_kick(); bool use_buf(unsigned *, void **); void call_used(); /* implemented by main */ extern bool do_sleep; void kick(void); void wait_for_kick(void); void call(void); void wait_for_call(void); extern unsigned ring_size; /* Compiler barrier - similar to what Linux uses */ #define barrier() asm volatile("" ::: "memory") /* Is there a portable way to do this? */ #if defined(__x86_64__) || defined(__i386__) #define cpu_relax() asm ("rep; nop" ::: "memory") #elif defined(__s390x__) #define cpu_relax() barrier() #else #define cpu_relax() assert(0) #endif extern bool do_relax;
static inline void busy_wait(void) { if (do_relax) cpu_relax(); else /* prevent compiler from removing busy loops */ barrier(); }

Contributors

PersonTokensPropCommitsCommitProp
Michael S. Tsirkin21100.00%1100.00%
Total21100.00%1100.00%

#if defined(__x86_64__) || defined(__i386__) #define smp_mb() asm volatile("lock; addl $0,-132(%%rsp)" ::: "memory", "cc") #else /* * Not using __ATOMIC_SEQ_CST since gcc docs say they are only synchronized * with other __ATOMIC_SEQ_CST calls. */ #define smp_mb() __sync_synchronize() #endif /* * This abuses the atomic builtins for thread fences, and * adds a compiler barrier. */ #define smp_release() do { \ barrier(); \ __atomic_thread_fence(__ATOMIC_RELEASE); \ } while (0) #define smp_acquire() do { \ __atomic_thread_fence(__ATOMIC_ACQUIRE); \ barrier(); \ } while (0) #if defined(__i386__) || defined(__x86_64__) || defined(__s390x__) #define smp_wmb() barrier() #else #define smp_wmb() smp_release() #endif #ifdef __alpha__ #define smp_read_barrier_depends() smp_acquire() #else #define smp_read_barrier_depends() do {} while(0) #endif
static __always_inline void __read_once_size(const volatile void *p, void *res, int size) { switch (size) { \ case 1: *(unsigned char *)res = *(volatile unsigned char *)p; break; \ case 2: *(unsigned short *)res = *(volatile unsigned short *)p; break; \ case 4: *(unsigned int *)res = *(volatile unsigned int *)p; break; \ case 8: *(unsigned long long *)res = *(volatile unsigned long long *)p; break; \ default: \ barrier(); \ __builtin_memcpy((void *)res, (const void *)p, size); \ barrier(); \ } \ }

Contributors

PersonTokensPropCommitsCommitProp
Michael S. Tsirkin144100.00%1100.00%
Total144100.00%1100.00%


static __always_inline void __write_once_size(volatile void *p, void *res, int size) { switch (size) { case 1: *(volatile unsigned char *)p = *(unsigned char *)res; break; case 2: *(volatile unsigned short *)p = *(unsigned short *)res; break; case 4: *(volatile unsigned int *)p = *(unsigned int *)res; break; case 8: *(volatile unsigned long long *)p = *(unsigned long long *)res; break; default: barrier(); __builtin_memcpy((void *)p, (const void *)res, size); barrier(); } }

Contributors

PersonTokensPropCommitsCommitProp
Michael S. Tsirkin136100.00%1100.00%
Total136100.00%1100.00%

#define READ_ONCE(x) \ ({ \ union { typeof(x) __val; char __c[1]; } __u; \ __read_once_size(&(x), __u.__c, sizeof(x)); \ smp_read_barrier_depends(); /* Enforce dependency ordering from x */ \ __u.__val; \ }) #define WRITE_ONCE(x, val) \ ({ \ union { typeof(x) __val; char __c[1]; } __u = \ { .__val = (typeof(x)) (val) }; \ __write_once_size(&(x), __u.__c, sizeof(x)); \ __u.__val; \ }) #endif

Overall Contributors

PersonTokensPropCommitsCommitProp
Michael S. Tsirkin68593.32%571.43%
Halil Pasic415.59%114.29%
Paolo Bonzini81.09%114.29%
Total734100.00%7100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.