// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2016 Red Hat, Inc. * Author: Michael S. Tsirkin <mst@redhat.com> * * Partial implementation of virtio 0.9. event index is used for signalling, * unconditionally. Design roughly follows linux kernel implementation in order * to be able to judge its performance.
*/ #define _GNU_SOURCE #include"main.h" #include <stdlib.h> #include <stdio.h> #include <assert.h> #include <string.h> #include <linux/virtio_ring.h>
struct data { void *data;
} *data;
struct vring ring;
/* enabling the below activates experimental ring polling code * (which skips index reads on consumer in favor of looking at * high bits of ring id ^ 0x8000).
*/ /* #ifdef RING_POLL */ /* enabling the below activates experimental in-order code * (which skips ring updates and reads and writes len in descriptor).
*/ /* #ifdef INORDER */
#ifdefined(RING_POLL) && defined(INORDER) #error"RING_POLL and INORDER are mutually exclusive" #endif
/* how much padding is needed to avoid false cache sharing */ #define HOST_GUEST_PADDING 0x80
struct host { /* we do not need to track last avail index * unless we have more than one in flight.
*/ unsignedshort used_idx; unsignedshort called_used_idx; unsignedchar reserved[HOST_GUEST_PADDING - 4];
} host;
/* implemented by ring */ void alloc_ring(void)
{ int ret; int i; void *p;
ret = posix_memalign(&p, 0x1000, vring_size(ring_size, 0x1000)); if (ret) {
perror("Unable to allocate ring buffer.\n"); exit(3);
}
memset(p, 0, vring_size(ring_size, 0x1000));
vring_init(&ring, ring_size, p, 0x1000);
guest.avail_idx = 0;
guest.kicked_avail_idx = -1;
guest.last_used_idx = 0; #ifndef INORDER /* Put everything in free lists. */
guest.free_head = 0; #endif for (i = 0; i < ring_size - 1; i++)
ring.desc[i].next = i + 1;
host.used_idx = 0;
host.called_used_idx = -1;
guest.num_free = ring_size;
data = malloc(ring_size * sizeof *data); if (!data) {
perror("Unable to allocate data buffer.\n"); exit(3);
}
memset(data, 0, ring_size * sizeof *data);
}
#ifdef INORDER
head = (ring_size - 1) & (guest.avail_idx++); #else
head = guest.free_head; #endif
guest.num_free--;
desc = ring.desc;
desc[head].flags = VRING_DESC_F_NEXT;
desc[head].addr = (unsignedlong)(void *)buf;
desc[head].len = len; /* We do it like this to simulate the way * we'd have to flip it if we had multiple * descriptors.
*/
desc[head].flags &= ~VRING_DESC_F_NEXT; #ifndef INORDER
guest.free_head = desc[head].next; #endif
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.