Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(RFC) Improve network bandwidth by using shared memory between tender and bindings for hvt #290

Closed
wants to merge 23 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Intermediate commit. Eventloop is still broken
nikhilap1 committed Apr 3, 2018

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit efc539d996121d9f3f7ad2c7a5c8bf96db3f2789
64 changes: 64 additions & 0 deletions kernel/acscope.files
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
./cpu_aarch64.h
./cpu_x86_64.h
./solo5.h
./kernel.h
./muen/muschedinfo.h
./muen/muen-net.h
./muen/musinfo.h
./muen/util.h
./muen/mutimeinfo.h
./muen/channel.h
./muen/shm_net.h
./muen/sinfo.h
./muen/reader.h
./muen/writer.h
./ukvm/kernel.h
./ukvm/ukvm_guest.h
./virtio/virtio_ring.h
./virtio/multiboot.h
./virtio/kernel.h
./virtio/clock_subr.h
./virtio/virtio_pci.h
./abort.c
./cpu_x86_64.c
./ee_printf.c
./cmdline.c
./cpu_aarch64.c
./exit.c
./mem.c
./muen/muen-net.c
./muen/muen-platform_lifecycle.c
./muen/muen-sinfo.c
./muen/muen-console.c
./muen/reader.c
./muen/shm_net.c
./muen/writer.c
./muen/muen-clock.c
./muen/muen-yield.c
./muen/channel.c
./muen/muen-block.c
./ukvm/platform_lifecycle.c
./ukvm/platform_intr.c
./ukvm/block.c
./ukvm/net.c
./ukvm/time.c
./ukvm/console.c
./ukvm/yield.c
./ukvm/kernel.c
./ukvm/platform.c
./ukvm/tscclock.c
./log.c
./lib.c
./virtio/virtio_ring.c
./virtio/pvclock.c
./virtio/platform_intr.c
./virtio/clock_subr.c
./virtio/virtio_blk.c
./virtio/pci.c
./virtio/time.c
./virtio/serial.c
./virtio/virtio_net.c
./virtio/kernel.c
./virtio/platform.c
./virtio/tscclock.c
./intr.c
6 changes: 1 addition & 5 deletions kernel/muen/muen-net.c
Original file line number Diff line number Diff line change
@@ -36,11 +36,7 @@ solo5_result_t solo5_net_write(const uint8_t *buf, size_t size)

solo5_result_t solo5_net_read(uint8_t *buf, size_t size, size_t *read_size)
{
int ret = shm_net_read(net_in, &net_rdr, buf, size, read_size);
if (ret == MUCHANNEL_SUCCESS || ret == MUCHANNEL_XON) {
return SOLO5_R_OK;
}
return SOLO5_R_AGAIN;
return shm_net_read(net_in, &net_rdr, buf, size, read_size);
}

bool muen_net_pending_data()
21 changes: 14 additions & 7 deletions kernel/muen/shm_net.c
Original file line number Diff line number Diff line change
@@ -23,35 +23,42 @@
#include "writer.h"
#include "shm_net.h"

int shm_net_write(struct muchannel *channel,
solo5_result_t shm_net_write(struct muchannel *channel,
const uint8_t *buf, size_t size)
{
struct net_msg pkt;

if (size > PACKET_SIZE)
return -1;
return SOLO5_R_EINVAL;

memset(&pkt, 0, sizeof(struct net_msg));
cc_barrier();
pkt.length = size;
memcpy(&pkt.data, buf, size);
return muen_channel_write(channel, &pkt);
if (muen_channel_write(channel, &pkt) != 0) {
return SOLO5_R_AGAIN;
}

return SOLO5_R_OK;
}

int shm_net_read(struct muchannel *channel,
solo5_result_t shm_net_read(struct muchannel *channel,
struct muchannel_reader *reader,
uint8_t *buf, size_t size, size_t *read_size)
{
enum muchannel_reader_result result;
struct net_msg pkt;

if (size < PACKET_SIZE)
return -1;
return SOLO5_R_EINVAL;

result = muen_channel_read(channel, reader, &pkt);
if ((result == MUCHANNEL_SUCCESS) || (result == MUCHANNEL_XON)) {
if (result == MUCHANNEL_SUCCESS) {
memcpy(buf, &pkt.data, pkt.length);
*read_size = pkt.length;
return SOLO5_R_OK;
} else {
//return result;
return SOLO5_R_AGAIN;
}
return result;
}
4 changes: 2 additions & 2 deletions kernel/muen/shm_net.h
Original file line number Diff line number Diff line change
@@ -30,8 +30,8 @@ struct net_msg {
uint16_t length;
} __attribute__((packed));

int shm_net_write(struct muchannel *channel,
solo5_result_t shm_net_write(struct muchannel *channel,
const uint8_t *buf, size_t size);
int shm_net_read(struct muchannel *channel,
solo5_result_t shm_net_read(struct muchannel *channel,
struct muchannel_reader *reader,
uint8_t *buf, size_t size, size_t *read_size);
25 changes: 12 additions & 13 deletions kernel/ukvm/net.c
Original file line number Diff line number Diff line change
@@ -45,17 +45,19 @@ void solo5_net_flush()
solo5_result_t solo5_net_write(const uint8_t *buf, size_t size)
{
if (shm_event_enabled) {
#if 0
int ret = solo5_net_queue(buf, size);
solo5_net_flush();
if (ret < 0) {
return SOLO5_R_AGAIN;
}
return SOLO5_R_OK;
#endif
int ret = solo5_net_queue(buf, size);
solo5_net_flush();
return ret;
} else if (shm_poll_enabled) {
if (shm_net_write(tx_channel, buf, size) < 0) {
return SOLO5_R_AGAIN;
}
return SOLO5_R_OK;
return shm_net_write(tx_channel, buf, size);
} else {
volatile struct ukvm_netwrite wr;

@@ -72,6 +74,7 @@ solo5_result_t solo5_net_write(const uint8_t *buf, size_t size)
solo5_result_t solo5_net_read(uint8_t *buf, size_t size, size_t *read_size)
{
if (shm_event_enabled) {
#if 0
int ret = shm_net_read(rx_channel, &net_rdr,
buf, size, read_size);

@@ -82,15 +85,12 @@ solo5_result_t solo5_net_read(uint8_t *buf, size_t size, size_t *read_size)
return SOLO5_R_OK;
}
return SOLO5_R_AGAIN;
#endif
return shm_net_read(rx_channel, &net_rdr,
buf, size, read_size);
} else if (shm_poll_enabled) {
int ret = shm_net_read(rx_channel, &net_rdr,
return shm_net_read(rx_channel, &net_rdr,
buf, size, read_size);

/* Don't need Xon/Xoff for polling. Remove it */
if (ret == MUCHANNEL_SUCCESS || ret == MUCHANNEL_XON) {
return SOLO5_R_OK;
}
return SOLO5_R_AGAIN;
} else {
volatile struct ukvm_netread rd;

@@ -117,9 +117,8 @@ void solo5_net_info(struct solo5_net_info *info)
info->mtu = 1500;
}

void net_init()
void net_init(void)
{

volatile struct ukvm_net_shm_info ni = { 0 };
ukvm_do_hypercall(UKVM_HYPERCALL_NET_SHMINFO, &ni);

2 changes: 1 addition & 1 deletion kernel/virtio/kernel.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) 2015-2017 Contributors as noted in the AUTHORS file
*
* This file is part of Solo5, a unikernel base layer.
10 changes: 9 additions & 1 deletion tests/test_ping_serve/test_ping_serve.c
Original file line number Diff line number Diff line change
@@ -127,6 +127,7 @@ uint8_t ipaddr[4] = { 0x0a, 0x00, 0x00, 0x02 }; /* 10.0.0.2 */
uint8_t ipaddr_brdnet[4] = { 0x0a, 0x00, 0x00, 0xff }; /* 10.0.0.255 */
uint8_t ipaddr_brdall[4] = { 0xff, 0xff, 0xff, 0xff }; /* 255.255.255.255 */
uint8_t macaddr[HLEN_ETHER];
uint8_t xmacaddr[HLEN_ETHER];
uint8_t macaddr_brd[HLEN_ETHER] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

static int handle_arp(uint8_t *buf)
@@ -267,10 +268,17 @@ static void ping_serve(int verbose, int limit)
while (solo5_net_read(buf, sizeof buf, &len) == SOLO5_R_AGAIN) {
solo5_yield(solo5_clock_monotonic() + NSEC_PER_SEC);
}
memcpy(xmacaddr, p->target, sizeof macaddr);
tohexs(macaddr_s, xmacaddr, sizeof macaddr);
puts("Comparing ping:");
puts(macaddr_s);
puts("\n");

if (memcmp(p->target, macaddr, HLEN_ETHER) &&
memcmp(p->target, macaddr_brd, HLEN_ETHER))
memcmp(p->target, macaddr_brd, HLEN_ETHER)) {
puts("Not addressed to us");
continue; /* not ether addressed to us */
}

switch (htons(p->type)) {
case ETHERTYPE_ARP:
36 changes: 21 additions & 15 deletions ukvm/ukvm_module_net.c
Original file line number Diff line number Diff line change
@@ -220,9 +220,9 @@ void read_solo5_rx_fd()

void* io_event_loop()
{
struct net_msg pkt;
struct net_msg pkt = { 0 };
int ret, n, i, err;
uint64_t clear = 0, wrote = 1;
uint64_t clear = 0, wrote = 1, test = 0;
struct epoll_event event;
struct epoll_event *events;

@@ -239,8 +239,9 @@ void* io_event_loop()
close(events[i].data.fd);
continue;
} else if (netfd == events[i].data.fd) {
clock_gettime(CLOCK_MONOTONIC, &writetime);
if ((ret = read(netfd, pkt.data, PACKET_SIZE)) > 0) {
memcpy(&test, pkt.data, 6);
warnx("Read ev mac: %lx", test);
if (shm_net_write(tx_channel, pkt.data, ret) != 0) {
/* Don't read from netfd. Instead, wait for tx_channel to
* be writable */
@@ -256,8 +257,9 @@ void* io_event_loop()
}

/* Start reading from netfd */
assert(0);
event.data.fd = netfd;
event.events = EPOLLIN | EPOLLET;
event.events = EPOLLIN;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, netfd, &event);
} else if (shm_rx_fd == events[i].data.fd) {
/* Read data from shmstream and write to tap interface */
@@ -289,12 +291,15 @@ void* io_thread()
struct net_msg pkt;
int ret, tap_no_data = 0, shm_no_data = 0;
uint64_t packets_read = 0;
uint64_t test = 0;

while (1) {
/* Read packets from tap interface and write to shmstream */
while (packets_read < MAX_PACKETS_READ &&
((ret = read(netfd, pkt.data, PACKET_SIZE)) > 0)) {
packets_read++;
memcpy(&test, pkt.data, 6);
warnx("Read mac: %lx", test);
if (shm_net_write(tx_channel, pkt.data, ret) != 0) {
ret = 0;
break;
@@ -447,16 +452,15 @@ static int handle_cmdarg(char *cmdarg)
static int configure_epoll()
{
struct epoll_event event;
int efd;

if ((efd = epoll_create1(0)) < 0) {
if ((epoll_fd = epoll_create1(0)) < 0) {
warnx("Failed to create epoll fd");
return -1;
}

event.data.fd = netfd;
event.events = EPOLLIN | EPOLLET;
if (epoll_ctl(efd, EPOLL_CTL_ADD, netfd, &event) < 0) {
event.events = EPOLLIN;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, netfd, &event) < 0) {
warnx("Failed to set up fd at epoll_ctl");
return -1;
}
@@ -467,8 +471,8 @@ static int configure_epoll()
}

event.data.fd = shm_rx_fd;
event.events = EPOLLIN | EPOLLET;
if (epoll_ctl(efd, EPOLL_CTL_ADD, shm_rx_fd, &event) < 0) {
event.events = EPOLLIN;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, shm_rx_fd, &event) < 0) {
warnx("Failed to set up fd at epoll_ctl");
return -1;
}
@@ -479,7 +483,7 @@ static int configure_epoll()
}

event.data.fd = shm_tx_fd;
event.events = EPOLLIN | EPOLLET;
event.events = EPOLLIN;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, shm_tx_fd, &event);

solo5_tx_xon_fd = eventfd(0, EFD_NONBLOCK);
@@ -488,7 +492,7 @@ static int configure_epoll()
return -1;
}

return efd;
return 0;
}

static int configure_shmstream(struct ukvm_hv *hv)
@@ -510,7 +514,7 @@ static int configure_shmstream(struct ukvm_hv *hv)

if (use_event_thread) {
/* Set up epoll */
if ((epoll_fd = configure_epoll()) < 0) {
if ((configure_epoll()) < 0) {
err(1, "Failed to configure epoll");
goto err;
}
@@ -565,8 +569,9 @@ static int configure_shmstream(struct ukvm_hv *hv)

/* Init tx ring as a writer */
tx_channel = (struct muchannel *)(shm_mem + offset);
clock_gettime(CLOCK_MONOTONIC, &readtime);
muen_channel_init_writer(tx_channel, MUENNET_PROTO, sizeof(struct net_msg),
tx_shm_size, 10);
tx_shm_size, readtime.tv_nsec);
offset += txring_region.memory_size;

printf("offset = 0x%"PRIx64", total_pagesize = 0x%"PRIx64"\n", offset, total_pagesize);
@@ -604,7 +609,8 @@ static int setup(struct ukvm_hv *hv)
close(rfd);
guest_mac[0] &= 0xfe;
guest_mac[0] |= 0x02;
memcpy(netinfo.mac_address, guest_mac, sizeof netinfo.mac_address);
uint64_t val = 0xf6e358284e50;
memcpy(netinfo.mac_address, &val, sizeof netinfo.mac_address);
}

if (use_shm_stream) {