L4LX: Network interface fixes

Make calls using IPCs IRQ safe, handle packet exhaustion, removed
'Packet_pool', tweak TCP rmem and wmem buffer sizes to show better performance
results, use 'Net::Packet_allocator, fix 'update-patch' Makefile command
This commit is contained in:
Sebastian Sumpf 2012-07-27 17:22:38 +02:00 committed by Norman Feske
parent 18d005264e
commit 8734eab6ac
6 changed files with 368 additions and 314 deletions

View File

@ -8,7 +8,7 @@ VERBOSE ?= @
ECHO = @echo
TARGET ?= l4linux
PATCH-l4linux = patches/l4lx_genode.patch patches/icmp_align.patch
PATCH-l4linux = $(addprefix patches/,l4lx_genode.patch icmp_align.patch tcp_mem.patch)
REV-l4linux = 23
REPO-l4linux = http://svn.tudos.org/repos/oc/l4linux/trunk
@ -16,6 +16,8 @@ PATCH-l4android = patches/l4android_genode.patch
REV-l4android = 90ca43bd629452ffd38d85fe8c976f069b5bb3d9
REPO-l4android = git://git.l4android.org/kernel.git
UPDATE_PATCH = $(word 1, $(PATCH-$(TARGET)))
#
# Utility to check if a tool is installed
#
@ -30,11 +32,14 @@ UPDATE = cd $(REAL_CONTRIB_DIR)/l4android; git fetch; git reset --hard $(REV-l4a
PATCH = patch -p1
else
$(call check_tool,svn)
DIFF = svn diff
UPDATE = svn up -r $(REV-l4linux) $(REAL_CONTRIB_DIR)/l4linux
PATCH = patch -p0
FILTER_DIR = net
DIFF_PATH = $(filter-out $(FILTER_DIR),$(shell ls $(REAL_CONTRIB_DIR)/l4linux))
DIFF = svn diff $(DIFF_PATH)
UPDATE = svn up -r $(REV-l4linux)
PATCH = patch -p0
endif
# realpath is there to follow symlink; if contrib dir does not exists yet,
# create new directory
REAL_CONTRIB_DIR := $(realpath $(CONTRIB_DIR))
@ -81,8 +86,8 @@ $(REAL_CONTRIB_DIR)/l4android:
$(VERBOSE)git clone $(REPO-l4android) $@
update-patch:
$(ECHO) "Save changes to original code in $(PATCH-$(TARGET))"
$(VERBOSE)(cd $(REAL_CONTRIB_DIR)/$(TARGET); LC_COLLATE=C $(DIFF)) > $(PATCH-$(TARGET)) || true
$(ECHO) "Save changes to original code in $(UPDATE_PATCH)"
$(VERBOSE)(cd $(REAL_CONTRIB_DIR)/$(TARGET); LC_COLLATE=C $(DIFF)) > $(UPDATE_PATCH) || true
clean: clean-$(TARGET)
$(VERBOSE)rm -f $(CONTRIB_DIR)/$(TARGET)/arch/l4/drivers

View File

@ -28,10 +28,11 @@ L4_CV int genode_net_ready (void);
L4_CV void genode_net_start (void *dev, FASTCALL void (*func)(void*, void*, unsigned long));
L4_CV void genode_net_stop (void);
L4_CV void genode_net_mac (void* mac_addr, unsigned long size);
L4_CV int genode_net_tx (void* addr, unsigned long len, void *skb);
L4_CV int genode_net_tx (void* addr, unsigned long len);
L4_CV int genode_net_tx_ack_avail(void);
L4_CV void* genode_net_tx_ack (void);
L4_CV void genode_net_tx_ack (void);
L4_CV void genode_net_rx_receive (void);
L4_CV void *genode_net_memcpy (void *dst, void const *src, unsigned long size);
#ifdef __cplusplus
}

View File

@ -1,3 +1,27 @@
Index: arch/l4/Kconfig
===================================================================
--- arch/l4/Kconfig (revision 23)
+++ arch/l4/Kconfig (working copy)
@@ -394,7 +394,19 @@
config L4_USE_L4SHMC
bool
+config SCREEN_GENODE
+ bool
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ default y
+config SERIAL_GENODE
+ bool
+ default y
+ select SERIAL_CORE
+ select SERIAL_CORE_CONSOLE
+
# some delimiter (for .config)
comment ""
source "arch/l4/Kconfig.arch"
Index: arch/l4/kernel/dispatch.c
===================================================================
--- arch/l4/kernel/dispatch.c (revision 23)
@ -20,6 +44,181 @@ Index: arch/l4/kernel/dispatch.c
}
}
}
Index: arch/l4/kernel/arch-x86/vmlinux.lds.S
===================================================================
--- arch/l4/kernel/arch-x86/vmlinux.lds.S (revision 23)
+++ arch/l4/kernel/arch-x86/vmlinux.lds.S (working copy)
@@ -33,7 +33,7 @@
#ifdef CONFIG_X86_32
OUTPUT_ARCH(i386)
-ENTRY(phys_startup_32)
+ENTRY(_start)
jiffies = jiffies_64;
#else
OUTPUT_ARCH(i386:x86-64)
@@ -67,17 +67,10 @@
#endif
-PHDRS {
- text PT_LOAD FLAGS(5); /* R_E */
- data PT_LOAD FLAGS(6); /* RW_ */
-#ifdef CONFIG_X86_64
- user PT_LOAD FLAGS(5); /* R_E */
-#ifdef CONFIG_SMP
- percpu PT_LOAD FLAGS(6); /* RW_ */
-#endif
- init PT_LOAD FLAGS(7); /* RWE */
-#endif
- note PT_NOTE FLAGS(0); /* ___ */
+PHDRS
+{
+ ro PT_LOAD;
+ rw PT_LOAD;
}
SECTIONS
@@ -97,6 +90,29 @@
/*_stext = .;*/
.text : AT(ADDR(.text) - LOAD_OFFSET) {
_text = .;
+ _prog_img_beg = .;
+
+ /*
+ * Leave space for parent capability parameters at start of data
+ * section. The protection domain creator is reponsible for storing
+ * sane values here.
+ */
+ _parent_cap = .;
+ _parent_cap_thread_id = .;
+ LONG(0xffffffff);
+ _parent_cap_local_name = .;
+ LONG(0xffffffff);
+
+ /*
+ * Platform-specific entry for Fiasco.OC.
+ *
+ * PIC-code compiled for Fiasco.OC, needs some PIC-compatible
+ * way to enter the kernel, the fixed address of the kernel
+ * entry code address needs to be found here.
+ */
+ __l4sys_invoke_indirect = .;
+ LONG(0xeacff000);
+
/* bootstrapping code */
HEAD_TEXT
#ifdef CONFIG_X86_32
@@ -112,14 +128,28 @@
ENTRY_TEXT
IRQENTRY_TEXT
*(.fixup)
+ *(.text.*) /* put all Genode .text entries in here */
*(.gnu.warning)
+
+ . = ALIGN(0x08);
+
+ _ctors_start = .;
+ KEEP (*(.ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.init_array)) /* list of constructors specific for ARM eabi */
+ _ctors_end = .;
+ _dtors_start = .;
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ _dtors_end = .;
+
/* End of text section */
_etext = .;
- } :text = 0x9090
+ } : rw
- NOTES :text :note
+ NOTES :rw
- EXCEPTION_TABLE(16) :text = 0x9090
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
#if defined(CONFIG_DEBUG_RODATA)
/* .text should occupy whole number of pages */
@@ -152,10 +182,34 @@
/* rarely changed data like cpu maps */
READ_MOSTLY_DATA(INTERNODE_CACHE_BYTES)
+ *(.data.*) /* put all Genode .data entries in here */
+
+
/* End of data section */
_edata = .;
- } :data
+ } : rw
+ EXCEPTION_TABLE(16) : rw
+
+ /* exception frames for C++ */
+ .eh_frame : {
+ __eh_frame_start__ = .;
+ KEEP (*(.eh_frame))
+ LONG(0)
+ } : rw
+
+ .init_array : {
+ __init_array_start = .;
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ __init_array_end = .;
+ }
+
+ .gcc_except_table : {
+ KEEP(*(.gcc_except_table))
+ KEEP(*(.gcc_except_table.*))
+ }
+
#ifdef CONFIG_X86_64
#ifdef CONFIG_L4
@@ -366,6 +420,7 @@
__bss_start = .;
*(.bss..page_aligned)
*(.bss)
+ *(.bss.*) /* put all Genode .bss entries in here */
. = ALIGN(PAGE_SIZE);
__bss_stop = .;
}
@@ -378,6 +433,7 @@
__brk_limit = .;
}
+ _prog_img_end = .;
_end = .;
STABS_DEBUG
Index: arch/l4/kernel/arch-x86/x86_init.c
===================================================================
--- arch/l4/kernel/arch-x86/x86_init.c (revision 23)
+++ arch/l4/kernel/arch-x86/x86_init.c (working copy)
@@ -38,7 +38,7 @@
struct x86_init_ops x86_init __initdata = {
.resources = {
- .probe_roms = probe_roms,
+ .probe_roms = x86_init_noop,
.reserve_resources = reserve_standard_io_resources,
.memory_setup = l4x_memory_setup,
},
Index: arch/l4/kernel/arch-arm/dispatch.c
===================================================================
--- arch/l4/kernel/arch-arm/dispatch.c (revision 23)
+++ arch/l4/kernel/arch-arm/dispatch.c (working copy)
@@ -66,7 +66,7 @@
};
-#if 1
+#if 0
#define TBUF_LOG_IDLE(x) TBUF_DO_IT(x)
#define TBUF_LOG_WAKEUP_IDLE(x) TBUF_DO_IT(x)
#define TBUF_LOG_USER_PF(x) TBUF_DO_IT(x)
Index: arch/l4/kernel/arch-arm/vmlinux.lds.S
===================================================================
--- arch/l4/kernel/arch-arm/vmlinux.lds.S (revision 23)
@ -198,168 +397,6 @@ Index: arch/l4/kernel/arch-arm/traps.c
}
#endif
Index: arch/l4/kernel/arch-x86/x86_init.c
===================================================================
--- arch/l4/kernel/arch-x86/x86_init.c (revision 23)
+++ arch/l4/kernel/arch-x86/x86_init.c (working copy)
@@ -38,7 +38,7 @@
struct x86_init_ops x86_init __initdata = {
.resources = {
- .probe_roms = probe_roms,
+ .probe_roms = x86_init_noop,
.reserve_resources = reserve_standard_io_resources,
.memory_setup = l4x_memory_setup,
},
Index: arch/l4/kernel/arch-x86/vmlinux.lds.S
===================================================================
--- arch/l4/kernel/arch-x86/vmlinux.lds.S (revision 23)
+++ arch/l4/kernel/arch-x86/vmlinux.lds.S (working copy)
@@ -33,7 +33,7 @@
#ifdef CONFIG_X86_32
OUTPUT_ARCH(i386)
-ENTRY(phys_startup_32)
+ENTRY(_start)
jiffies = jiffies_64;
#else
OUTPUT_ARCH(i386:x86-64)
@@ -67,17 +67,10 @@
#endif
-PHDRS {
- text PT_LOAD FLAGS(5); /* R_E */
- data PT_LOAD FLAGS(6); /* RW_ */
-#ifdef CONFIG_X86_64
- user PT_LOAD FLAGS(5); /* R_E */
-#ifdef CONFIG_SMP
- percpu PT_LOAD FLAGS(6); /* RW_ */
-#endif
- init PT_LOAD FLAGS(7); /* RWE */
-#endif
- note PT_NOTE FLAGS(0); /* ___ */
+PHDRS
+{
+ ro PT_LOAD;
+ rw PT_LOAD;
}
SECTIONS
@@ -97,6 +90,29 @@
/*_stext = .;*/
.text : AT(ADDR(.text) - LOAD_OFFSET) {
_text = .;
+ _prog_img_beg = .;
+
+ /*
+ * Leave space for parent capability parameters at start of data
+ * section. The protection domain creator is reponsible for storing
+ * sane values here.
+ */
+ _parent_cap = .;
+ _parent_cap_thread_id = .;
+ LONG(0xffffffff);
+ _parent_cap_local_name = .;
+ LONG(0xffffffff);
+
+ /*
+ * Platform-specific entry for Fiasco.OC.
+ *
+ * PIC-code compiled for Fiasco.OC, needs some PIC-compatible
+ * way to enter the kernel, the fixed address of the kernel
+ * entry code address needs to be found here.
+ */
+ __l4sys_invoke_indirect = .;
+ LONG(0xeacff000);
+
/* bootstrapping code */
HEAD_TEXT
#ifdef CONFIG_X86_32
@@ -112,14 +128,28 @@
ENTRY_TEXT
IRQENTRY_TEXT
*(.fixup)
+ *(.text.*) /* put all Genode .text entries in here */
*(.gnu.warning)
+
+ . = ALIGN(0x08);
+
+ _ctors_start = .;
+ KEEP (*(.ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.init_array)) /* list of constructors specific for ARM eabi */
+ _ctors_end = .;
+ _dtors_start = .;
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ _dtors_end = .;
+
/* End of text section */
_etext = .;
- } :text = 0x9090
+ } : rw
- NOTES :text :note
+ NOTES :rw
- EXCEPTION_TABLE(16) :text = 0x9090
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
#if defined(CONFIG_DEBUG_RODATA)
/* .text should occupy whole number of pages */
@@ -152,10 +182,34 @@
/* rarely changed data like cpu maps */
READ_MOSTLY_DATA(INTERNODE_CACHE_BYTES)
+ *(.data.*) /* put all Genode .data entries in here */
+
+
/* End of data section */
_edata = .;
- } :data
+ } : rw
+ EXCEPTION_TABLE(16) : rw
+
+ /* exception frames for C++ */
+ .eh_frame : {
+ __eh_frame_start__ = .;
+ KEEP (*(.eh_frame))
+ LONG(0)
+ } : rw
+
+ .init_array : {
+ __init_array_start = .;
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ __init_array_end = .;
+ }
+
+ .gcc_except_table : {
+ KEEP(*(.gcc_except_table))
+ KEEP(*(.gcc_except_table.*))
+ }
+
#ifdef CONFIG_X86_64
#ifdef CONFIG_L4
@@ -366,6 +420,7 @@
__bss_start = .;
*(.bss..page_aligned)
*(.bss)
+ *(.bss.*) /* put all Genode .bss entries in here */
. = ALIGN(PAGE_SIZE);
__bss_stop = .;
}
@@ -378,6 +433,7 @@
__brk_limit = .;
}
+ _prog_img_end = .;
_end = .;
STABS_DEBUG
Index: arch/l4/kernel/head.S
===================================================================
--- arch/l4/kernel/head.S (revision 23)
@ -623,51 +660,6 @@ Index: arch/l4/kernel/main.c
LOG_printf("Still alive, going zombie???\n");
l4_sleep_forever();
}
Index: arch/l4/Kconfig
===================================================================
--- arch/l4/Kconfig (revision 23)
+++ arch/l4/Kconfig (working copy)
@@ -394,7 +394,19 @@
config L4_USE_L4SHMC
bool
+config SCREEN_GENODE
+ bool
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ default y
+config SERIAL_GENODE
+ bool
+ default y
+ select SERIAL_CORE
+ select SERIAL_CORE_CONSOLE
+
# some delimiter (for .config)
comment ""
source "arch/l4/Kconfig.arch"
Index: arch/l4/include/asm/generic/l4lib.h
===================================================================
--- arch/l4/include/asm/generic/l4lib.h (revision 23)
+++ arch/l4/include/asm/generic/l4lib.h (working copy)
@@ -3,6 +3,7 @@
#include <linux/stringify.h>
+#if 0
#ifdef ARCH_arm
#define L4_EXTERNAL_FUNC(func) \
asm(".section \".data.l4externals.str\" \n" \
@@ -58,5 +59,8 @@
".previous \n" \
)
#endif
+#endif
+#define L4_EXTERNAL_FUNC(func) ;
+
#endif /* __INCLUDE__ASM_L4__GENERIC__L4LIB_H__ */
Index: arch/l4/boot/Makefile
===================================================================
--- arch/l4/boot/Makefile (revision 23)
@ -834,18 +826,27 @@ Index: arch/l4/Makefile
server:
$(Q)$(MAKE) $(build)=arch/l4/server
Index: include/asm-generic/vmlinux.lds.h
Index: arch/l4/include/asm/generic/l4lib.h
===================================================================
--- include/asm-generic/vmlinux.lds.h (revision 23)
+++ include/asm-generic/vmlinux.lds.h (working copy)
@@ -371,6 +371,7 @@
VMLINUX_SYMBOL(__start___modver) = .; \
*(__modver) \
VMLINUX_SYMBOL(__stop___modver) = .; \
+ LONG(0) /* enforce non-zero section size */ \
. = ALIGN((align)); \
VMLINUX_SYMBOL(__end_rodata) = .; \
} \
--- arch/l4/include/asm/generic/l4lib.h (revision 23)
+++ arch/l4/include/asm/generic/l4lib.h (working copy)
@@ -3,6 +3,7 @@
#include <linux/stringify.h>
+#if 0
#ifdef ARCH_arm
#define L4_EXTERNAL_FUNC(func) \
asm(".section \".data.l4externals.str\" \n" \
@@ -58,5 +59,8 @@
".previous \n" \
)
#endif
+#endif
+#define L4_EXTERNAL_FUNC(func) ;
+
#endif /* __INCLUDE__ASM_L4__GENERIC__L4LIB_H__ */
Index: drivers/tty/serial/l4ser.c
===================================================================
--- drivers/tty/serial/l4ser.c (revision 23)
@ -936,3 +937,15 @@ Index: drivers/tty/serial/l4ser.c
if (l4ser_init_port(0, PORT0_NAME))
return -ENODEV;
Index: include/asm-generic/vmlinux.lds.h
===================================================================
--- include/asm-generic/vmlinux.lds.h (revision 23)
+++ include/asm-generic/vmlinux.lds.h (working copy)
@@ -371,6 +371,7 @@
VMLINUX_SYMBOL(__start___modver) = .; \
*(__modver) \
VMLINUX_SYMBOL(__stop___modver) = .; \
+ LONG(0) /* enforce non-zero section size */ \
. = ALIGN((align)); \
VMLINUX_SYMBOL(__end_rodata) = .; \
} \

View File

@ -0,0 +1,19 @@
Index: net/ipv4/tcp.c
===================================================================
--- net/ipv4/tcp.c (revision 23)
+++ net/ipv4/tcp.c (working copy)
@@ -3285,8 +3285,13 @@
/* Set per-socket limits to no more than 1/128 the pressure threshold */
limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7);
- max_share = min(4UL*1024*1024, limit);
+ /*
+ * Adjust limit so it performs well on systems with little memory. If
+ * this causes errors increase L4Linux main memory
+ */
+ max_share = min(4UL*1024*1024, limit < 768U * 1024 ? 768U * 1024 : limit);
+
sysctl_tcp_wmem[0] = SK_MEM_QUANTUM;
sysctl_tcp_wmem[1] = 16*1024;
sysctl_tcp_wmem[2] = max(64*1024, max_share);

View File

@ -35,7 +35,7 @@ static void genode_net_receive_packet(void* dev_addr, void *addr,
struct net_device_stats *stats = (struct net_device_stats*) netdev_priv(dev);
/* allocate skb */
struct sk_buff *skb = dev_alloc_skb(size + 2);
struct sk_buff *skb = dev_alloc_skb(size + 4);
if (!skb) {
if (printk_ratelimit())
printk(KERN_NOTICE "genode_net_rx: low on mem - packet dropped!\n");
@ -44,11 +44,12 @@ static void genode_net_receive_packet(void* dev_addr, void *addr,
}
/* copy packet */
memcpy(skb_put(skb, size), addr, size);
genode_net_memcpy(skb_put(skb, size), addr, size);
skb->dev = dev;
skb->protocol = eth_type_trans(skb, dev);
skb->ip_summed = CHECKSUM_NONE;
netif_rx(skb);
stats->rx_packets++;
@ -84,20 +85,21 @@ int genode_net_xmit_frame(struct sk_buff *skb, struct net_device *dev)
/* collect acknowledgements of old packets */
while (genode_net_tx_ack_avail())
dev_kfree_skb((struct sk_buff *)genode_net_tx_ack());
genode_net_tx_ack();
/* transmit to nic-session */
if (genode_net_tx(addr, len, skb)) {
/* tx queue is full, could not enqueue packet */
netif_stop_queue(dev);
return 1;
while (genode_net_tx(addr, len)) {
/* tx queue is full, could not enqueue packet */
genode_net_tx_ack();
}
dev_kfree_skb(skb);
/* save timestamp */
dev->trans_start = jiffies;
stats->tx_packets++;
stats->tx_bytes += len;
return 0;
}

View File

@ -18,7 +18,9 @@
#include <base/printf.h>
#include <util/misc_math.h>
#include <util/string.h>
#include <nic/packet_allocator.h>
#include <nic_session/connection.h>
#include <timer_session/connection.h>
#include <vcpu.h>
#include <linux.h>
@ -27,87 +29,77 @@ namespace Fiasco {
#include <genode/net.h>
#include <l4/sys/irq.h>
#include <l4/sys/kdebug.h>
#include <l4/sys/ktrace.h>
}
static Nic::Connection *nic() {
static Nic::Connection *n = 0;
static bool initialized = false;
#define TX_BENCH 0
#define RX_BENCH 0
if (!initialized) {
try {
static Genode::Allocator_avl tx_block_alloc(Genode::env()->heap());
static Nic::Connection nic(&tx_block_alloc);
n = &nic;
} catch(...) { }
initialized = true;
/**
* Debugging/Tracing
*/
#if TX_BENCH | RX_BENCH
struct Counter : public Genode::Thread<8192>
{
int cnt;
Genode::size_t size;
void entry()
{
Timer::Connection _timer;
int interval = 5;
while(1) {
_timer.msleep(interval * 1000);
PDBG("LX Packets %d/s bytes/s: %d", cnt / interval, size / interval);
cnt = 0;
size = 0;
}
}
void inc(Genode::size_t s) { cnt++; size += s; }
Counter() : cnt(0), size(0) { start(); }
};
#else
struct Counter { inline void inc(Genode::size_t s) { } };
#endif
static Nic::Connection *nic() {
enum {
PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
RX_BUF_SIZE = Nic::Session::RX_QUEUE_SIZE * PACKET_SIZE,
TX_BUF_SIZE = Nic::Session::TX_QUEUE_SIZE * PACKET_SIZE,
};
static Nic::Connection *n = 0;
static bool initialized = false;
if (initialized)
return n;
try {
Linux::Irq_guard guard;
static Nic::Packet_allocator tx_block_alloc(Genode::env()->heap());
static Nic::Connection nic(&tx_block_alloc, TX_BUF_SIZE, RX_BUF_SIZE);
n = &nic;
} catch(...) { }
initialized = true;
return n;
}
namespace {
class Packet_pool
{
private:
class Entry
{
public:
Packet_descriptor packet;
void *addr;
Entry() : addr(0) {}
};
enum { MAX_ENTRIES = 100 };
Entry _entries[MAX_ENTRIES];
public:
class Pool_full : Genode::Exception {};
void add(Packet_descriptor p, void* addr)
{
for (unsigned i=0; i < MAX_ENTRIES; i++) {
if (!_entries[i].addr) {
_entries[i].addr = addr;
_entries[i].packet = p;
return;
}
}
throw Pool_full();
}
void* get(Packet_descriptor _packet)
{
for (unsigned i=0; i < MAX_ENTRIES; i++)
if (nic()->tx()->packet_content(_packet)
== nic()->tx()->packet_content(_entries[i].packet)) {
void *ret = _entries[i].addr;
_entries[i].addr = 0;
return ret;
}
return 0;
}
};
static Packet_pool *packet_pool()
{
static Packet_pool pool;
return &pool;
}
class Signal_thread : public Genode::Thread<8192>
{
private:
Fiasco::l4_cap_idx_t _cap;
Genode::Lock *_sync;
protected:
@ -122,8 +114,11 @@ namespace {
nic()->rx_channel()->sigh_ready_to_ack(cap);
nic()->rx_channel()->sigh_packet_avail(cap);
_sync->unlock();
while (true) {
receiver.wait_for_signal();
if (l4_error(l4_irq_trigger(_cap)) != -1)
PWRN("IRQ net trigger failed\n");
}
@ -131,8 +126,9 @@ namespace {
public:
Signal_thread(Fiasco::l4_cap_idx_t cap)
: Genode::Thread<8192>("net-signal-thread"), _cap(cap) { start(); }
Signal_thread(Fiasco::l4_cap_idx_t cap, Genode::Lock *sync)
: Genode::Thread<8192>("net-signal-thread"), _cap(cap), _sync(sync) {
start(); }
};
}
@ -141,7 +137,7 @@ using namespace Fiasco;
extern "C" {
static FASTCALL void (*receive_packet)(void*, void*, unsigned long) = 0;
static void *net_device = 0;
static void *net_device = 0;
void genode_net_start(void *dev, FASTCALL void (*func)(void*, void*, unsigned long))
@ -153,8 +149,11 @@ extern "C" {
l4_cap_idx_t genode_net_irq_cap()
{
Linux::Irq_guard guard;
static Genode::Native_capability cap = L4lx::vcpu_connection()->alloc_irq();
static Signal_thread th(cap.dst());
static Genode::Lock lock(Genode::Lock::LOCKED);
static Signal_thread th(cap.dst(), &lock);
lock.lock();
return cap.dst();
}
@ -168,6 +167,7 @@ extern "C" {
void genode_net_mac(void* mac, unsigned long size)
{
Linux::Irq_guard guard;
using namespace Genode;
Nic::Mac_address m = nic()->mac_address();
@ -175,21 +175,25 @@ extern "C" {
}
int genode_net_tx(void* addr, unsigned long len, void *skb)
int genode_net_tx(void* addr, unsigned long len)
{
Linux::Irq_guard guard;
static Counter counter;
try {
Packet_descriptor packet = nic()->tx()->alloc_packet(len);
void* content = nic()->tx()->packet_content(packet);
packet_pool()->add(packet, skb);
Genode::memcpy(content, addr, len);
Genode::memcpy((char *)content, addr, len);
nic()->tx()->submit_packet(packet);
counter.inc(len);
return 0;
} catch(Packet_pool::Pool_full) {
PWRN("skb_buff/packet pool full!");
/* 'Packet_alloc_failed' */
} catch(...) {
PWRN("Send failed!");
return 1;
}
return 1;
}
@ -197,22 +201,28 @@ extern "C" {
return nic()->tx()->ack_avail(); }
void* genode_net_tx_ack()
void genode_net_tx_ack()
{
Linux::Irq_guard guard;
Packet_descriptor packet = nic()->tx()->get_acked_packet();
void *skb = packet_pool()->get(packet);
nic()->tx()->release_packet(packet);
return skb;
}
void genode_net_rx_receive()
{
Linux::Irq_guard guard;
static Counter counter;
if (nic()) {
while(nic()->rx()->packet_avail()) {
Packet_descriptor p = nic()->rx()->get_packet();
if (receive_packet && net_device)
receive_packet(net_device, nic()->rx()->packet_content(p), p.size());
counter.inc(p.size());
nic()->rx()->acknowledge_packet(p);
}
}
@ -223,4 +233,8 @@ extern "C" {
{
return nic() ? 1 : 0;
}
void *genode_net_memcpy(void *dst, void const *src, unsigned long size) {
return Genode::memcpy(dst, src, size); }
}