Skip to content

Commit

Permalink
Merge pull request torvalds#202 from opurdila/lkl-virtio-net-fd
Browse files Browse the repository at this point in the history
lkl tools: virtio net fd: make it posix compatible
  • Loading branch information
Octavian Purdila authored Aug 16, 2016
2 parents 1e6059f + 743fbe8 commit e145a5a
Show file tree
Hide file tree
Showing 17 changed files with 424 additions and 477 deletions.
8 changes: 2 additions & 6 deletions arch/lkl/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,6 @@ void machine_restart(char *unused)
machine_halt();
}

extern int lkl_netdevs_remove(void);

long lkl_sys_halt(void)
{
long err;
Expand All @@ -141,10 +139,8 @@ long lkl_sys_halt(void)
lkl_ops->sem_free(init_sem);

free_initial_syscall_thread();
if (lkl_netdevs_remove() == 0)
/* We know that there is nothing else touching our
* memory. */
free_mem();

free_mem();

return 0;
}
Expand Down
9 changes: 4 additions & 5 deletions tools/lkl/include/lkl.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,15 +270,14 @@ struct lkl_netdev_args {
int lkl_netdev_add(struct lkl_netdev *nd, struct lkl_netdev_args* args);

/**
* lkl_netdevs_remove - destroy all network devices
* lkl_netdev_remove - remove a previously added network device
*
* Attempts to release all resources held by network devices created
* Attempts to release all resources held by a network device created
* via lkl_netdev_add.
*
* @returns 0 if all devices are successfully removed, -1 if at least
* one fails.
* @id - the network device id, as return by @lkl_netdev_add
*/
int lkl_netdevs_remove(void);
void lkl_netdev_remove(int id);

/**
* lkl_netdev_get_ifindex - retrieve the interface index for a given network
Expand Down
55 changes: 23 additions & 32 deletions tools/lkl/include/lkl_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,24 @@ struct lkl_dev_blk_ops {

struct lkl_netdev {
struct lkl_dev_net_ops *ops;
lkl_thread_t rx_tid, tx_tid;
uint8_t has_vnet_hdr: 1;
};

struct lkl_dev_net_ops {
/* Writes a L2 packet into the net device.
/*
* Writes a L2 packet into the net device.
*
* The data buffer can only hold 0 or 1 complete packets.
*
* @nd - pointer to the network device
* @iov - pointer to the buffer vector
* @cnt - # of vectors in iov.
* @returns number of bytes transmitted
*/
*/
int (*tx)(struct lkl_netdev *nd, struct lkl_dev_buf *iov, int cnt);
/* Reads a packet from the net device.

/*
* Reads a packet from the net device.
*
* It must only read one complete packet if present.
*
Expand All @@ -75,43 +77,32 @@ struct lkl_dev_net_ops {
* @iov - pointer to the buffer vector to store the packet
* @cnt - # of vectors in iov.
* @returns number of bytes read for success or < 0 if error
*/
*/
int (*rx)(struct lkl_netdev *nd, struct lkl_dev_buf *iov, int cnt);

#define LKL_DEV_NET_POLL_RX 1
#define LKL_DEV_NET_POLL_TX 2
/* Polls a net device.
*
* Supports only one of two events: LKL_DEV_NET_POLL_RX (readable) and
* LKL_DEV_NET_POLL_TX (writable). Blocks until one event is available.
*
* Implementation can assume only one of LKL_DEV_NET_POLL_RX or
* LKL_DEV_NET_POLL_TX is set in @events.
#define LKL_DEV_NET_POLL_HUP 4

/*
* Polls a net device.
*
* Both LKL_DEV_NET_POLL_RX and LKL_DEV_NET_POLL_TX can be
* level-triggered or edge-triggered. When it's level-triggered,
* rx/tx thread can become a busy waiting loop which burns out CPU.
* This is more of a problem for tx, because LKL_DEV_NET_POLL_TX event
* is present most of the time.
* Supports the following events: LKL_DEV_NET_POLL_RX (readable),
* LKL_DEV_NET_POLL_TX (writable) or LKL_DEV_NET_POLL_HUP (the close
* operations has been issued and we need to clean up). Blocks until one
* event is available.
*
* @nd - pointer to the network device
* @events - a bit mask specifying the events to poll on. Only one of
* LKL_DEV_NET_POLL_RX or LKL_DEV_NET_POLL_TX is set.
* @returns the events triggered for success. -1 for failure.
*/
int (*poll)(struct lkl_netdev *nd, int events);
/* Closes a net device.
*
* Implementation can choose to release any resources releated to it. In
* particular, the polling threads are to be killed in this function.
*
* Implemenation must guarantee it's safe to call free_mem() after this
* function call.
*
* Not implemented by all netdev types.
int (*poll)(struct lkl_netdev *nd);

/*
* Closes a net device.
*
* @returns 0 for success. -1 for failure.
* Implementation must release its resources and poll must wakeup and
* return LKL_DEV_NET_POLL_HUP.
*/
int (*close)(struct lkl_netdev *nd);
void (*close)(struct lkl_netdev *nd);
};

#ifdef __cplusplus
Expand Down
2 changes: 1 addition & 1 deletion tools/lkl/lib/Build
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ lkl-y += virtio.o
lkl-y += dbg.o
lkl-y += dbg_handler.o
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net.o
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_linux_fdnet.o
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_fd.o
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_tap.o
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_raw.o
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_macvtap.o
Expand Down
34 changes: 32 additions & 2 deletions tools/lkl/lib/hijack/hijack.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <lkl_host.h>

#include "xlate.h"
#include "init.h"

static int is_lklfd(int fd)
{
Expand Down Expand Up @@ -75,6 +76,29 @@ static host_call host_calls[__lkl__NR_syscalls];
asm(".global " #name); \
asm(".set " #name "," #name "_hook"); \

#define HOOK_CALL_USE_HOST_BEFORE_START(name) \
static void __attribute__((constructor(101))) \
init_host_##name(void) \
{ \
host_calls[__lkl__NR_##name] = resolve_sym(#name); \
} \
\
long name##_hook(long p1, long p2, long p3, long p4, long p5, \
long p6) \
{ \
long p[6] = {p1, p2, p3, p4, p5, p6 }; \
\
if (!host_calls[__lkl__NR_##name]) \
host_calls[__lkl__NR_##name] = resolve_sym(#name); \
if (!lkl_running) \
return host_calls[__lkl__NR_##name](p1, p2, p3, \
p4, p5, p6); \
\
return lkl_set_errno(lkl_syscall(__lkl__NR_##name, p)); \
} \
asm(".global " #name); \
asm(".set " #name "," #name "_hook")

#define HOST_CALL(name) \
static long (*host_##name)(); \
static void __attribute__((constructor(101))) \
Expand Down Expand Up @@ -131,7 +155,7 @@ HOOK_FD_CALL(read)
HOOK_FD_CALL(recvfrom)
HOOK_FD_CALL(recv)
HOOK_FD_CALL(epoll_wait)
HOOK_CALL(pipe);
HOOK_CALL_USE_HOST_BEFORE_START(pipe);

HOST_CALL(setsockopt);
int setsockopt(int fd, int level, int optname, const void *optval,
Expand Down Expand Up @@ -264,7 +288,7 @@ int select(int nfds, fd_set *r, fd_set *w, fd_set *e, struct timeval *t)
return lkl_call(__lkl__NR_select, 5, nfds, r, w, e, t);
}

HOOK_CALL(epoll_create)
HOOK_CALL_USE_HOST_BEFORE_START(epoll_create);

HOST_CALL(epoll_ctl);
int epoll_ctl(int epollfd, int op, int fd, struct epoll_event *event)
Expand All @@ -282,6 +306,12 @@ int epoll_ctl(int epollfd, int op, int fd, struct epoll_event *event)

int eventfd(unsigned int count, int flags)
{
if (!lkl_running) {
int (*f)(unsigned int, int) = resolve_sym("eventfd");

return f(count, flags);
}

return lkl_sys_eventfd2(count, flags);
}

Expand Down
21 changes: 8 additions & 13 deletions tools/lkl/lib/hijack/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include <lkl_host.h>

#include "xlate.h"
#include "../virtio_net_linux_fdnet.h"

#define __USE_GNU
#include <dlfcn.h>
Expand Down Expand Up @@ -155,13 +154,6 @@ static void mount_cmds_exec(char *_cmds, int (*callback)(char*))
free(cmds);
}

void fixup_netdev_linux_fdnet_ops(void)
{
/* It's okay if this is NULL, because then netdev close will
* fall back onto an uncloseable implementation. */
lkl_netdev_linux_fdnet_ops.eventfd = dlsym(RTLD_NEXT, "eventfd");
}

static void PinToCpus(const cpu_set_t* cpus)
{
if (sched_setaffinity(0, sizeof(cpu_set_t), cpus)) {
Expand All @@ -184,12 +176,14 @@ static void PinToFirstCpu(const cpu_set_t* cpus)
}
}

int lkl_debug;
int lkl_debug, lkl_running;

static int nd_id = -1;

void __attribute__((constructor(102)))
hijack_init(void)
{
int ret, i, dev_null, nd_id = -1, nd_ifindex = -1;
int ret, i, dev_null, nd_ifindex = -1;
/* OBSOLETE: should use IFTYPE and IFPARAMS */
char *tap = getenv("LKL_HIJACK_NET_TAP");
char *iftype = getenv("LKL_HIJACK_NET_IFTYPE");
Expand Down Expand Up @@ -261,9 +255,6 @@ hijack_init(void)
if (single_cpu_mode == 2)
PinToFirstCpu(&ori_cpu);

/* Must be run before lkl_netdev_tap_create */
fixup_netdev_linux_fdnet_ops();

if (tap) {
fprintf(stderr,
"WARN: variable LKL_HIJACK_NET_TAP is now obsoleted.\n"
Expand Down Expand Up @@ -329,6 +320,8 @@ hijack_init(void)
return;
}

lkl_running = 1;

/* restore cpu affinity */
if (single_cpu_mode)
PinToCpus(&ori_cpu);
Expand Down Expand Up @@ -440,6 +433,8 @@ hijack_fini(void)
for (i = 0; i < LKL_FD_OFFSET; i++)
lkl_sys_close(i);

if (nd_id >= 0)
lkl_netdev_remove(nd_id);

lkl_sys_halt();
}
6 changes: 6 additions & 0 deletions tools/lkl/lib/hijack/init.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef _LKL_HIJACK_INIT_H
#define _LKL_HIJACK_INIT_H

extern int lkl_running;

#endif /*_LKL_HIJACK_INIT_H */
Loading

0 comments on commit e145a5a

Please sign in to comment.