Skip to content

Commit

Permalink
net: Remove simple polling and use only event-based
Browse files Browse the repository at this point in the history
  • Loading branch information
niks3089 committed Nov 16, 2018
1 parent 343bca7 commit c024e57
Show file tree
Hide file tree
Showing 15 changed files with 173 additions and 197 deletions.
2 changes: 1 addition & 1 deletion bindings/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ muen/muen-block.o \
muen/muen-clock.o \
muen/muen-console.o \
muen/muen-net.o \
muen/muen-sinfo.o \
muen/muen-platform_lifecycle.o \
muen/muen-yield.o \
muen/muen-sinfo.o \
$(COMMON_COBJS)

GENODE_COBJS=\
Expand Down
42 changes: 16 additions & 26 deletions bindings/hvt/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
struct muchannel *tx_channel;
struct muchannel *rx_channel;
struct muchannel_reader net_rdr;
bool shm_poll_enabled = false;
bool shm_event_enabled = false;
bool shm_enabled = false;

static inline solo5_result_t shm_to_solo5_result(int shm_result)
{
Expand All @@ -41,7 +40,7 @@ static inline solo5_result_t shm_to_solo5_result(int shm_result)
case SHM_NET_EPOCH_CHANGED:
return SOLO5_R_AGAIN;
default:
return SOLO5_R_EUNSPEC;
break;
}
return SOLO5_R_EUNSPEC;
}
Expand All @@ -50,27 +49,24 @@ solo5_result_t solo5_net_queue(const uint8_t *buf, size_t size)
{
int ret;

assert(shm_event_enabled);
assert(shm_enabled);
ret = shm_net_write(tx_channel, buf, size);
return shm_to_solo5_result(ret);
}

void solo5_net_flush()
{
assert(shm_event_enabled);
hvt_do_hypercall(HVT_HYPERCALL_NETNOTIFY, NULL);
assert(shm_enabled);
hvt_do_hypercall(HVT_HYPERCALL_NET_NOTIFY, NULL);
}

solo5_result_t solo5_net_write(int index __attribute__((unused)), const uint8_t *buf, size_t size)
solo5_result_t solo5_net_write(const uint8_t *buf, size_t size)
{
int ret = 0;
if (shm_event_enabled) {
if (shm_enabled) {
ret = solo5_net_queue(buf, size);
solo5_net_flush();
return ret;
} else if (shm_poll_enabled) {
ret = shm_net_write(tx_channel, buf, size);
return shm_to_solo5_result(ret);
} else {
volatile struct hvt_netwrite wr;

Expand All @@ -84,21 +80,17 @@ solo5_result_t solo5_net_write(int index __attribute__((unused)), const uint8_t
}
}

solo5_result_t solo5_net_read(int index __attribute__((unused)), uint8_t *buf, size_t size, size_t *read_size)
solo5_result_t solo5_net_read(uint8_t *buf, size_t size, size_t *read_size)
{
int ret = 0;
if (shm_event_enabled) {
if (shm_enabled) {
ret = shm_net_read(rx_channel, &net_rdr,
buf, size, read_size);

if (ret == SHM_NET_XON) {
hvt_do_hypercall(HVT_HYPERCALL_NETXON, NULL);
hvt_do_hypercall(HVT_HYPERCALL_NET_XON, NULL);
}
return shm_to_solo5_result(ret);
} else if (shm_poll_enabled) {
ret = shm_net_read(rx_channel, &net_rdr,
buf, size, read_size);
return shm_to_solo5_result(ret);
} else {
volatile struct hvt_netread rd;

Expand All @@ -113,7 +105,7 @@ solo5_result_t solo5_net_read(int index __attribute__((unused)), uint8_t *buf, s
}
}

void solo5_net_info(int index __attribute__((unused)), struct solo5_net_info *info)
void solo5_net_info(struct solo5_net_info *info)
{
volatile struct hvt_netinfo ni;

Expand All @@ -127,19 +119,17 @@ void solo5_net_info(int index __attribute__((unused)), struct solo5_net_info *in

void net_init(void)
{
volatile struct hvt_net_shm_info ni = { 0 };
hvt_do_hypercall(HVT_HYPERCALL_NET_SHMINFO, &ni);
int xon_enabled = 0;
volatile struct hvt_shm_info ni;
hvt_do_hypercall(HVT_HYPERCALL_SHMINFO, &ni);

shm_poll_enabled = ni.shm_poll_enabled;
shm_event_enabled = (xon_enabled = ni.shm_event_enabled);
shm_enabled = ni.shm_enabled;

if (shm_poll_enabled || shm_event_enabled) {
if (shm_enabled) {
tx_channel = (struct muchannel *)ni.tx_channel_addr;
rx_channel = (struct muchannel *)ni.rx_channel_addr;

muen_channel_init_writer(tx_channel, MUENNET_PROTO, sizeof(struct net_msg),
ni.tx_channel_addr_size, 10, xon_enabled);
ni.tx_channel_addr_size, 10, 1);
muen_channel_init_reader(&net_rdr, MUENNET_PROTO);
}
}
2 changes: 1 addition & 1 deletion bindings/hvt/yield.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#include "bindings.h"

bool solo5_yield(uint64_t deadline, void *nothing __attribute__((unused)))
bool solo5_yield(solo5_time_t deadline)
{
struct hvt_poll t;
uint64_t now;
Expand Down
6 changes: 3 additions & 3 deletions bindings/muen/muen-net.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ struct muchannel *net_out;
struct muchannel_reader net_rdr;
static uint8_t mac_addr[6];

solo5_result_t solo5_net_write(int index __attribute__((unused)), const uint8_t *buf, size_t size)
solo5_result_t solo5_net_write(const uint8_t *buf, size_t size)
{
return shm_net_write(net_out, buf, size);
}

solo5_result_t solo5_net_read(int index __attribute__((unused)), uint8_t *buf, size_t size, size_t *read_size)
solo5_result_t solo5_net_read(uint8_t *buf, size_t size, size_t *read_size)
{
return shm_net_read(net_in, &net_rdr, buf, size, read_size);
}
Expand All @@ -45,7 +45,7 @@ bool muen_net_pending_data()
}

/* TODO: Support configured MAC address */
void solo5_net_info(int index __attribute__((unused)), struct solo5_net_info *info)
void solo5_net_info(struct solo5_net_info *info)
{
memcpy(info->mac_address, mac_addr, sizeof info->mac_address);
info->mtu = 1500;
Expand Down
2 changes: 1 addition & 1 deletion bindings/muen/muen-yield.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "../bindings.h"
#include "muen-net.h"

bool solo5_yield(uint64_t deadline, void *nothing __attribute__((unused)))
bool solo5_yield(solo5_time_t deadline)
{
bool rc = false;
do {
Expand Down
1 change: 0 additions & 1 deletion bindings/muen/shm_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,5 @@ shm_net_result_t shm_net_read(struct muchannel *channel,
} else if (result == MUCHANNEL_EPOCH_CHANGED) {
return SHM_NET_EPOCH_CHANGED;
}
assert(0);
return SHM_NET_EINVAL;
}
2 changes: 1 addition & 1 deletion bindings/virtio/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ void time_init(void)
assert(tscclock_init() == 0);
}

bool solo5_yield(uint64_t deadline, void *nothing __attribute__((unused)))
bool solo5_yield(solo5_time_t deadline)
{
bool rc = false;

Expand Down
10 changes: 5 additions & 5 deletions bindings/virtio/virtio_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ void virtio_config_network(struct pci_config_info *pci)

/*
* 2. Set the ACKNOWLEDGE status bit: the guest OS has notice the device.
* 3. Set the DRIVER status bit: the guest OS knows how to drive the device.
* 3. Set the DRIVER status bit: the guest OS knows how to drive the device.
*/

outb(pci->base + VIRTIO_PCI_STATUS, VIRTIO_PCI_STATUS_ACK);
Expand All @@ -149,7 +149,7 @@ void virtio_config_network(struct pci_config_info *pci)
* 4. Read device feature bits, and write the subset of feature bits
* understood by the OS and driver to the device. During this step the
* driver MAY read (but MUST NOT write) the device-specific configuration
* fields to check that it can support the device before accepting it.
* fields to check that it can support the device before accepting it.
*/

host_features = inl(pci->base + VIRTIO_PCI_HOST_FEATURES);
Expand Down Expand Up @@ -269,15 +269,15 @@ void virtio_net_recv_pkt_put(void)
outw(virtio_net_pci_base + VIRTIO_PCI_QUEUE_NOTIFY, VIRTQ_RECV);
}

solo5_result_t solo5_net_write(int index __attribute__((unused)), const uint8_t *buf, size_t size)
solo5_result_t solo5_net_write(const uint8_t *buf, size_t size)
{
assert(net_configured);

int rv = virtio_net_xmit_packet(buf, size);
return (rv == 0) ? SOLO5_R_OK : SOLO5_R_EUNSPEC;
}

solo5_result_t solo5_net_read(int index __attribute__((unused)), uint8_t *buf, size_t size, size_t *read_size)
solo5_result_t solo5_net_read(uint8_t *buf, size_t size, size_t *read_size)
{
uint8_t *pkt;
size_t len = size;
Expand Down Expand Up @@ -313,7 +313,7 @@ solo5_result_t solo5_net_read(int index __attribute__((unused)), uint8_t *buf, s
return SOLO5_R_OK;
}

void solo5_net_info(int index __attribute__((unused)), struct solo5_net_info *info)
void solo5_net_info(struct solo5_net_info *info)
{
assert(net_configured);

Expand Down
20 changes: 5 additions & 15 deletions include/solo5/hvt_abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ enum hvt_hypercall {
HVT_HYPERCALL_NETWRITE,
HVT_HYPERCALL_NETREAD,
HVT_HYPERCALL_HALT,
HVT_HYPERCALL_NET_SHMINFO,
HVT_HYPERCALL_NETXON,
HVT_HYPERCALL_NETNOTIFY,
HVT_HYPERCALL_SHMINFO,
HVT_HYPERCALL_NET_XON,
HVT_HYPERCALL_NET_NOTIFY,
HVT_HYPERCALL_MAX
};

Expand Down Expand Up @@ -232,10 +232,9 @@ struct hvt_netinfo {
};

/* HVT_HYPERCALL_NET_SHM_INFO */
struct hvt_net_shm_info {
struct hvt_shm_info {
/* IN */
int shm_poll_enabled;
int shm_event_enabled;
int shm_enabled;
uint64_t tx_channel_addr;
uint64_t tx_channel_addr_size;
uint64_t rx_channel_addr;
Expand Down Expand Up @@ -301,13 +300,4 @@ struct hvt_halt {
int exit_status;
};

/*
* Canonical list of host memory regions mapped as the guest memory
*/
enum hvt_memregion {
HVT_MEMCORE_REGION,
HVT_SHMSTREAM_RXRING_BUF_REGION,
HVT_SHMSTREAM_TXRING_BUF_REGION,
};

#endif /* HVT_GUEST_H */
26 changes: 19 additions & 7 deletions include/solo5/solo5.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ solo5_time_t solo5_clock_wall(void);
* This interface may be extended in the future to allow for selection of I/O
* events of interest to the application.
*/
bool solo5_yield(uint64_t deadline, void *nothing __attribute__((unused)));
bool solo5_yield(solo5_time_t deadline);

/*
* Console I/O.
Expand Down Expand Up @@ -197,7 +197,7 @@ struct solo5_net_info {
* Retrieves information about the network device. Caller must supply space for
* struct solo5_net_info in (info).
*/
void solo5_net_info(int nic_index, struct solo5_net_info *info);
void solo5_net_info(struct solo5_net_info *info);

/*
* Sends a single network packet from the buffer (*buf), without blocking. If
Expand All @@ -207,7 +207,7 @@ void solo5_net_info(int nic_index, struct solo5_net_info *info);
* The maximum allowed value for (size) is (solo5_net_info.mtu +
* SOLO5_NET_HLEN). The packet must include the ethernet frame header.
*/
solo5_result_t solo5_net_write(int index, const uint8_t *buf, size_t size);
solo5_result_t solo5_net_write(const uint8_t *buf, size_t size);

/*
* Receives a single network packet into the buffer (*buf), without blocking.
Expand All @@ -218,8 +218,22 @@ solo5_result_t solo5_net_write(int index, const uint8_t *buf, size_t size);
* SOLO5_R_OK and the size of the received packet including the ethernet frame
* header in (*read_size).
*/
solo5_result_t solo5_net_read(int index, uint8_t *buf, size_t size, size_t *read_size);
solo5_result_t solo5_net_read(uint8_t *buf, size_t size, size_t *read_size);

/*
* Can be used only when shared memory is enabled.
* Queues a single network packet from buffer (*buf) to the net device.
* If the queue is full, SOLO5_R_AGAIN is returned, which implies the packets
* need to be sent out. This can be done using solo5_net_flush().
* On successful queueing SOLO5_R_OK is returned.
*/
solo5_result_t solo5_net_queue(const uint8_t *buf, size_t size);

/*
* Can be used only when shared memory is enabled.
* Sends the packets which are queued onto the network.
*/
void solo5_net_flush();
/*
* Block I/O.
*
Expand Down Expand Up @@ -252,7 +266,7 @@ void solo5_block_info(struct solo5_block_info *info);

/*
* Writes data of (size) bytes from the buffer (*buf) to the block device,
* starting at byte (offset). Data is either written in it's entirety or not at
* starting at byte (offset). Data is either written in its entirety or not at
* all ("short writes" are not possible).
*
* Both (size) and (offset) must be a multiple of the block size, otherwise
Expand All @@ -276,7 +290,5 @@ solo5_result_t solo5_block_write(solo5_off_t offset, const uint8_t *buf,
* single block.
*/
solo5_result_t solo5_block_read(solo5_off_t offset, uint8_t *buf, size_t size);
solo5_result_t solo5_net_queue(const uint8_t *buf, size_t size);
void solo5_net_flush();

#endif
9 changes: 9 additions & 0 deletions tenders/hvt/hvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,4 +239,13 @@ int hvt_gdb_add_breakpoint(struct hvt *hvt, gdb_breakpoint_type type,
int hvt_gdb_remove_breakpoint(struct hvt *hvt, gdb_breakpoint_type type,
hvt_gpa_t addr, size_t len);

/*
* Canonical list of host memory regions mapped as the guest memory
*/
enum hvt_memregion {
HVT_MEMCORE_REGION,
HVT_SHMSTREAM_RXRING_BUF_REGION,
HVT_SHMSTREAM_TXRING_BUF_REGION,
};

#endif /* HVT_H */
17 changes: 17 additions & 0 deletions tenders/hvt/hvt_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ static void hypercall_puts(struct hvt *hvt, hvt_gpa_t gpa)
assert(rc >= 0);
}

#ifndef HVT_MODULE_NET
static void hypercall_noop(struct hvt *hvt, hvt_gpa_t gpa)
{
}
#endif

static struct pollfd pollfds[NUM_MODULES];
static poll_fn_cb_t poll_fn_cb[NUM_MODULES];
static int npollfds = 0;
Expand Down Expand Up @@ -198,6 +204,17 @@ static int setup(struct hvt *hvt)
assert(hvt_core_register_hypercall(HVT_HYPERCALL_POLL,
hypercall_poll) == 0);

/* HACK!: I need to to register this only in the net module for now.
* This will be called by net_init() to setup the kernel's view of shared memory.
* However net_init() is called every time the kernel is booted, even when net module is
* not compiled in. This will result in unknown hyercall number error.
* I would prefer if there is a way to net init only when net module is required.
* I guess that's not happening so this is least ugliest hack I could think of */
#ifndef HVT_MODULE_NET
assert(hvt_core_register_hypercall(HVT_HYPERCALL_SHMINFO,
hypercall_noop) == 0);
#endif

/*
* XXX: This needs documenting / coordination with the top-level caller.
*/
Expand Down
Loading

0 comments on commit c024e57

Please sign in to comment.