Skip to content

Commit e145a5a

Browse files
author
Octavian Purdila
authored
Merge pull request torvalds#202 from opurdila/lkl-virtio-net-fd
lkl tools: virtio net fd: make it posix compatible
2 parents 1e6059f + 743fbe8 commit e145a5a

File tree

17 files changed

+424
-477
lines changed

17 files changed

+424
-477
lines changed

arch/lkl/kernel/setup.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,6 @@ void machine_restart(char *unused)
117117
machine_halt();
118118
}
119119

120-
extern int lkl_netdevs_remove(void);
121-
122120
long lkl_sys_halt(void)
123121
{
124122
long err;
@@ -141,10 +139,8 @@ long lkl_sys_halt(void)
141139
lkl_ops->sem_free(init_sem);
142140

143141
free_initial_syscall_thread();
144-
if (lkl_netdevs_remove() == 0)
145-
/* We know that there is nothing else touching our
146-
* memory. */
147-
free_mem();
142+
143+
free_mem();
148144

149145
return 0;
150146
}

tools/lkl/include/lkl.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,15 +270,14 @@ struct lkl_netdev_args {
270270
int lkl_netdev_add(struct lkl_netdev *nd, struct lkl_netdev_args* args);
271271

272272
/**
273-
* lkl_netdevs_remove - destroy all network devices
273+
* lkl_netdev_remove - remove a previously added network device
274274
*
275-
* Attempts to release all resources held by network devices created
275+
* Attempts to release all resources held by a network device created
276276
* via lkl_netdev_add.
277277
*
278-
* @returns 0 if all devices are successfully removed, -1 if at least
279-
* one fails.
278+
* @id - the network device id, as return by @lkl_netdev_add
280279
*/
281-
int lkl_netdevs_remove(void);
280+
void lkl_netdev_remove(int id);
282281

283282
/**
284283
* lkl_netdev_get_ifindex - retrieve the interface index for a given network

tools/lkl/include/lkl_host.h

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,24 @@ struct lkl_dev_blk_ops {
4949

5050
struct lkl_netdev {
5151
struct lkl_dev_net_ops *ops;
52-
lkl_thread_t rx_tid, tx_tid;
5352
uint8_t has_vnet_hdr: 1;
5453
};
5554

5655
struct lkl_dev_net_ops {
57-
/* Writes a L2 packet into the net device.
56+
/*
57+
* Writes a L2 packet into the net device.
5858
*
5959
* The data buffer can only hold 0 or 1 complete packets.
6060
*
6161
* @nd - pointer to the network device
6262
* @iov - pointer to the buffer vector
6363
* @cnt - # of vectors in iov.
6464
* @returns number of bytes transmitted
65-
*/
65+
*/
6666
int (*tx)(struct lkl_netdev *nd, struct lkl_dev_buf *iov, int cnt);
67-
/* Reads a packet from the net device.
67+
68+
/*
69+
* Reads a packet from the net device.
6870
*
6971
* It must only read one complete packet if present.
7072
*
@@ -75,43 +77,32 @@ struct lkl_dev_net_ops {
7577
* @iov - pointer to the buffer vector to store the packet
7678
* @cnt - # of vectors in iov.
7779
* @returns number of bytes read for success or < 0 if error
78-
*/
80+
*/
7981
int (*rx)(struct lkl_netdev *nd, struct lkl_dev_buf *iov, int cnt);
82+
8083
#define LKL_DEV_NET_POLL_RX 1
8184
#define LKL_DEV_NET_POLL_TX 2
82-
/* Polls a net device.
83-
*
84-
* Supports only one of two events: LKL_DEV_NET_POLL_RX (readable) and
85-
* LKL_DEV_NET_POLL_TX (writable). Blocks until one event is available.
86-
*
87-
* Implementation can assume only one of LKL_DEV_NET_POLL_RX or
88-
* LKL_DEV_NET_POLL_TX is set in @events.
85+
#define LKL_DEV_NET_POLL_HUP 4
86+
87+
/*
88+
* Polls a net device.
8989
*
90-
* Both LKL_DEV_NET_POLL_RX and LKL_DEV_NET_POLL_TX can be
91-
* level-triggered or edge-triggered. When it's level-triggered,
92-
* rx/tx thread can become a busy waiting loop which burns out CPU.
93-
* This is more of a problem for tx, because LKL_DEV_NET_POLL_TX event
94-
* is present most of the time.
90+
* Supports the following events: LKL_DEV_NET_POLL_RX (readable),
91+
* LKL_DEV_NET_POLL_TX (writable) or LKL_DEV_NET_POLL_HUP (the close
92+
* operations has been issued and we need to clean up). Blocks until one
93+
* event is available.
9594
*
9695
* @nd - pointer to the network device
97-
* @events - a bit mask specifying the events to poll on. Only one of
98-
* LKL_DEV_NET_POLL_RX or LKL_DEV_NET_POLL_TX is set.
99-
* @returns the events triggered for success. -1 for failure.
10096
*/
101-
int (*poll)(struct lkl_netdev *nd, int events);
102-
/* Closes a net device.
103-
*
104-
* Implementation can choose to release any resources releated to it. In
105-
* particular, the polling threads are to be killed in this function.
106-
*
107-
* Implemenation must guarantee it's safe to call free_mem() after this
108-
* function call.
109-
*
110-
* Not implemented by all netdev types.
97+
int (*poll)(struct lkl_netdev *nd);
98+
99+
/*
100+
* Closes a net device.
111101
*
112-
* @returns 0 for success. -1 for failure.
102+
* Implementation must release its resources and poll must wakeup and
103+
* return LKL_DEV_NET_POLL_HUP.
113104
*/
114-
int (*close)(struct lkl_netdev *nd);
105+
void (*close)(struct lkl_netdev *nd);
115106
};
116107

117108
#ifdef __cplusplus

tools/lkl/lib/Build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ lkl-y += virtio.o
1212
lkl-y += dbg.o
1313
lkl-y += dbg_handler.o
1414
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net.o
15-
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_linux_fdnet.o
15+
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_fd.o
1616
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_tap.o
1717
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_raw.o
1818
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_macvtap.o

tools/lkl/lib/hijack/hijack.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <lkl_host.h>
2828

2929
#include "xlate.h"
30+
#include "init.h"
3031

3132
static int is_lklfd(int fd)
3233
{
@@ -75,6 +76,29 @@ static host_call host_calls[__lkl__NR_syscalls];
7576
asm(".global " #name); \
7677
asm(".set " #name "," #name "_hook"); \
7778

79+
#define HOOK_CALL_USE_HOST_BEFORE_START(name) \
80+
static void __attribute__((constructor(101))) \
81+
init_host_##name(void) \
82+
{ \
83+
host_calls[__lkl__NR_##name] = resolve_sym(#name); \
84+
} \
85+
\
86+
long name##_hook(long p1, long p2, long p3, long p4, long p5, \
87+
long p6) \
88+
{ \
89+
long p[6] = {p1, p2, p3, p4, p5, p6 }; \
90+
\
91+
if (!host_calls[__lkl__NR_##name]) \
92+
host_calls[__lkl__NR_##name] = resolve_sym(#name); \
93+
if (!lkl_running) \
94+
return host_calls[__lkl__NR_##name](p1, p2, p3, \
95+
p4, p5, p6); \
96+
\
97+
return lkl_set_errno(lkl_syscall(__lkl__NR_##name, p)); \
98+
} \
99+
asm(".global " #name); \
100+
asm(".set " #name "," #name "_hook")
101+
78102
#define HOST_CALL(name) \
79103
static long (*host_##name)(); \
80104
static void __attribute__((constructor(101))) \
@@ -131,7 +155,7 @@ HOOK_FD_CALL(read)
131155
HOOK_FD_CALL(recvfrom)
132156
HOOK_FD_CALL(recv)
133157
HOOK_FD_CALL(epoll_wait)
134-
HOOK_CALL(pipe);
158+
HOOK_CALL_USE_HOST_BEFORE_START(pipe);
135159

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

267-
HOOK_CALL(epoll_create)
291+
HOOK_CALL_USE_HOST_BEFORE_START(epoll_create);
268292

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

283307
int eventfd(unsigned int count, int flags)
284308
{
309+
if (!lkl_running) {
310+
int (*f)(unsigned int, int) = resolve_sym("eventfd");
311+
312+
return f(count, flags);
313+
}
314+
285315
return lkl_sys_eventfd2(count, flags);
286316
}
287317

tools/lkl/lib/hijack/init.c

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include <lkl_host.h>
2626

2727
#include "xlate.h"
28-
#include "../virtio_net_linux_fdnet.h"
2928

3029
#define __USE_GNU
3130
#include <dlfcn.h>
@@ -155,13 +154,6 @@ static void mount_cmds_exec(char *_cmds, int (*callback)(char*))
155154
free(cmds);
156155
}
157156

158-
void fixup_netdev_linux_fdnet_ops(void)
159-
{
160-
/* It's okay if this is NULL, because then netdev close will
161-
* fall back onto an uncloseable implementation. */
162-
lkl_netdev_linux_fdnet_ops.eventfd = dlsym(RTLD_NEXT, "eventfd");
163-
}
164-
165157
static void PinToCpus(const cpu_set_t* cpus)
166158
{
167159
if (sched_setaffinity(0, sizeof(cpu_set_t), cpus)) {
@@ -184,12 +176,14 @@ static void PinToFirstCpu(const cpu_set_t* cpus)
184176
}
185177
}
186178

187-
int lkl_debug;
179+
int lkl_debug, lkl_running;
180+
181+
static int nd_id = -1;
188182

189183
void __attribute__((constructor(102)))
190184
hijack_init(void)
191185
{
192-
int ret, i, dev_null, nd_id = -1, nd_ifindex = -1;
186+
int ret, i, dev_null, nd_ifindex = -1;
193187
/* OBSOLETE: should use IFTYPE and IFPARAMS */
194188
char *tap = getenv("LKL_HIJACK_NET_TAP");
195189
char *iftype = getenv("LKL_HIJACK_NET_IFTYPE");
@@ -261,9 +255,6 @@ hijack_init(void)
261255
if (single_cpu_mode == 2)
262256
PinToFirstCpu(&ori_cpu);
263257

264-
/* Must be run before lkl_netdev_tap_create */
265-
fixup_netdev_linux_fdnet_ops();
266-
267258
if (tap) {
268259
fprintf(stderr,
269260
"WARN: variable LKL_HIJACK_NET_TAP is now obsoleted.\n"
@@ -329,6 +320,8 @@ hijack_init(void)
329320
return;
330321
}
331322

323+
lkl_running = 1;
324+
332325
/* restore cpu affinity */
333326
if (single_cpu_mode)
334327
PinToCpus(&ori_cpu);
@@ -440,6 +433,8 @@ hijack_fini(void)
440433
for (i = 0; i < LKL_FD_OFFSET; i++)
441434
lkl_sys_close(i);
442435

436+
if (nd_id >= 0)
437+
lkl_netdev_remove(nd_id);
443438

444439
lkl_sys_halt();
445440
}

tools/lkl/lib/hijack/init.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef _LKL_HIJACK_INIT_H
2+
#define _LKL_HIJACK_INIT_H
3+
4+
extern int lkl_running;
5+
6+
#endif /*_LKL_HIJACK_INIT_H */

0 commit comments

Comments
 (0)