cregit-Linux how code gets into the kernel

Release 4.7 tools/virtio/ringtest/main.c

/*
 * 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.
 *
 * Command line processing and common functions for ring benchmarking.
 */

#define _GNU_SOURCE
#include <getopt.h>
#include <pthread.h>
#include <assert.h>
#include <sched.h>
#include "main.h"
#include <sys/eventfd.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <limits.h>


int runcycles = 10000000;

int max_outstanding = INT_MAX;

int batch = 1;


bool do_sleep = false;

bool do_relax = false;

bool do_exit = true;


unsigned ring_size = 256;


static int kickfd = -1;

static int callfd = -1;


void notify(int fd) { unsigned long long v = 1; int r; vmexit(); r = write(fd, &v, sizeof v); assert(r == sizeof v); vmentry(); }

Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin45100.00%1100.00%
Total45100.00%1100.00%


void wait_for_notify(int fd) { unsigned long long v = 1; int r; vmexit(); r = read(fd, &v, sizeof v); assert(r == sizeof v); vmentry(); }

Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin45100.00%1100.00%
Total45100.00%1100.00%


void kick(void) { notify(kickfd); }

Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin12100.00%1100.00%
Total12100.00%1100.00%


void wait_for_kick(void) { wait_for_notify(kickfd); }

Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin12100.00%1100.00%
Total12100.00%1100.00%


void call(void) { notify(callfd); }

Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin12100.00%1100.00%
Total12100.00%1100.00%


void wait_for_call(void) { wait_for_notify(callfd); }

Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin12100.00%1100.00%
Total12100.00%1100.00%


void set_affinity(const char *arg) { cpu_set_t cpuset; int ret; pthread_t self; long int cpu; char *endptr; if (!arg) return; cpu = strtol(arg, &endptr, 0); assert(!*endptr); assert(cpu >= 0 || cpu < CPU_SETSIZE); self = pthread_self(); CPU_ZERO(&cpuset); CPU_SET(cpu, &cpuset); ret = pthread_setaffinity_np(self, sizeof(cpu_set_t), &cpuset); assert(!ret); }

Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin103100.00%1100.00%
Total103100.00%1100.00%


static void run_guest(void) { int completed_before; int completed = 0; int started = 0; int bufs = runcycles; int spurious = 0; int r; unsigned len; void *buf; int tokick = batch; for (;;) { if (do_sleep) disable_call(); completed_before = completed; do { if (started < bufs && started - completed < max_outstanding) { r = add_inbuf(0, "Buffer\n", "Hello, world!"); if (__builtin_expect(r == 0, true)) { ++started; if (!--tokick) { tokick = batch; if (do_sleep) kick_available(); } } } else r = -1; /* Flush out completed bufs if any */ if (get_buf(&len, &buf)) { ++completed; if (__builtin_expect(completed == bufs, false)) return; r = 0; } } while (r == 0); if (completed == completed_before) ++spurious; assert(completed <= bufs); assert(started <= bufs); if (do_sleep) { if (enable_call()) wait_for_call(); } else { poll_used(); } } }

Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin216100.00%2100.00%
Total216100.00%2100.00%


static void run_host(void) { int completed_before; int completed = 0; int spurious = 0; int bufs = runcycles; unsigned len; void *buf; for (;;) { if (do_sleep) { if (enable_kick()) wait_for_kick(); } else { poll_avail(); } if (do_sleep) disable_kick(); completed_before = completed; while (__builtin_expect(use_buf(&len, &buf), true)) { if (do_sleep) call_used(); ++completed; if (__builtin_expect(completed == bufs, false)) return; } if (completed == completed_before) ++spurious; assert(completed <= bufs); if (completed == bufs) break; } }

Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin134100.00%1100.00%
Total134100.00%1100.00%


void *start_guest(void *arg) { set_affinity(arg); run_guest(); pthread_exit(NULL); }

Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin23100.00%1100.00%
Total23100.00%1100.00%


void *start_host(void *arg) { set_affinity(arg); run_host(); pthread_exit(NULL); }

Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin23100.00%1100.00%
Total23100.00%1100.00%

static const char optstring[] = ""; static const struct option longopts[] = { { .name = "help", .has_arg = no_argument, .val = 'h', }, { .name = "host-affinity", .has_arg = required_argument, .val = 'H', }, { .name = "guest-affinity", .has_arg = required_argument, .val = 'G', }, { .name = "ring-size", .has_arg = required_argument, .val = 'R', }, { .name = "run-cycles", .has_arg = required_argument, .val = 'C', }, { .name = "outstanding", .has_arg = required_argument, .val = 'o', }, { .name = "batch", .has_arg = required_argument, .val = 'b', }, { .name = "sleep", .has_arg = no_argument, .val = 's', }, { .name = "relax", .has_arg = no_argument, .val = 'x', }, { .name = "exit", .has_arg = no_argument, .val = 'e', }, { } };
static void help(void) { fprintf(stderr, "Usage: <test> [--help]" " [--host-affinity H]" " [--guest-affinity G]" " [--ring-size R (default: %d)]" " [--run-cycles C (default: %d)]" " [--batch b]" " [--outstanding o]" " [--sleep]" " [--relax]" " [--exit]" "\n", ring_size, runcycles); }

Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin29100.00%1100.00%
Total29100.00%1100.00%


int main(int argc, char **argv) { int ret; pthread_t host, guest; void *tret; char *host_arg = NULL; char *guest_arg = NULL; char *endptr; long int c; kickfd = eventfd(0, 0); assert(kickfd >= 0); callfd = eventfd(0, 0); assert(callfd >= 0); for (;;) { int o = getopt_long(argc, argv, optstring, longopts, NULL); switch (o) { case -1: goto done; case '?': help(); exit(2); case 'H': host_arg = optarg; break; case 'G': guest_arg = optarg; break; case 'R': ring_size = strtol(optarg, &endptr, 0); assert(ring_size && !(ring_size & (ring_size - 1))); assert(!*endptr); break; case 'C': c = strtol(optarg, &endptr, 0); assert(!*endptr); assert(c > 0 && c < INT_MAX); runcycles = c; break; case 'o': c = strtol(optarg, &endptr, 0); assert(!*endptr); assert(c > 0 && c < INT_MAX); max_outstanding = c; break; case 'b': c = strtol(optarg, &endptr, 0); assert(!*endptr); assert(c > 0 && c < INT_MAX); batch = c; break; case 's': do_sleep = true; break; case 'x': do_relax = true; break; case 'e': do_exit = true; break; default: help(); exit(4); break; } } /* does nothing here, used to make sure all smp APIs compile */ smp_acquire(); smp_release(); smp_mb(); done: if (batch > max_outstanding) batch = max_outstanding; if (optind < argc) { help(); exit(4); } alloc_ring(); ret = pthread_create(&host, NULL, start_host, host_arg); assert(!ret); ret = pthread_create(&guest, NULL, start_guest, guest_arg); assert(!ret); ret = pthread_join(guest, &tret); assert(!ret); ret = pthread_join(host, &tret); assert(!ret); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin443100.00%1100.00%
Total443100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
michael s. tsirkinmichael s. tsirkin1381100.00%2100.00%
Total1381100.00%2100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}