Make NIC RX/TX buffer sizes configureable in libc

* Remove far too low default values from Nic::Connection constructor
* Extend lwip initialization function with desired TX/RX buffer sizes
* Add configuration possibility to libc_lwip_dhcp plugin to define
  buffer sizes, like the following:

  '<libc tx_buf_size="1M" tx_buf_size="1M"/>'

Fixes #892
This commit is contained in:
Stefan Kalkowski 2013-09-23 15:58:45 +02:00 committed by Christian Helmuth
parent c56927b76e
commit 8f0c789ed4
15 changed files with 81 additions and 26 deletions

View File

@ -15,6 +15,7 @@
#include <base/printf.h> #include <base/printf.h>
#include <base/sleep.h> #include <base/sleep.h>
#include <lwip/genode.h> #include <lwip/genode.h>
#include <nic/packet_allocator.h>
extern "C" { extern "C" {
#include <lwip/netdb.h> #include <lwip/netdb.h>
@ -295,9 +296,11 @@ void Http::cmd_get(size_t file_offset, size_t size, off_t offset)
void __attribute__((constructor)) init() void __attribute__((constructor)) init()
{ {
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
lwip_tcpip_init(); lwip_tcpip_init();
if (lwip_nic_init(0, 0, 0)) { if (lwip_nic_init(0, 0, 0, BUF_SIZE, BUF_SIZE)) {
PERR("DHCP failed"); PERR("DHCP failed");
throw -1; throw -1;
} }

View File

@ -33,6 +33,8 @@ void lwip_tcpip_init(void);
* DHCP * DHCP
* \param netmask IPv4 network mask in network byte order * \param netmask IPv4 network mask in network byte order
* \param gateway IPv4 network-gateway address in network byte order * \param gateway IPv4 network-gateway address in network byte order
* \param tx_buf_size packet stream buffer size for TX direction
* \param rx_buf_size packet stream buffer size for RX direction
* *
* \return 0 on success, or 1 if DHCP failed. * \return 0 on success, or 1 if DHCP failed.
* *
@ -40,7 +42,10 @@ void lwip_tcpip_init(void);
* requests. * requests.
*/ */
int lwip_nic_init(genode_int32_t ip_addr, int lwip_nic_init(genode_int32_t ip_addr,
genode_int32_t netmask, genode_int32_t gateway); genode_int32_t netmask,
genode_int32_t gateway,
__SIZE_TYPE__ tx_buf_size,
__SIZE_TYPE__ rx_buf_size);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -16,6 +16,7 @@
#include <parent/parent.h> #include <parent/parent.h>
#include <os/config.h> #include <os/config.h>
#include <nic/packet_allocator.h>
#include <util/string.h> #include <util/string.h>
#include <lwip/genode.h> #include <lwip/genode.h>
@ -32,6 +33,8 @@ extern void create_etc_resolv_conf_plugin();
void __attribute__((constructor)) init_nic_dhcp(void) void __attribute__((constructor)) init_nic_dhcp(void)
{ {
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
PDBG("init_nic_dhcp()\n"); PDBG("init_nic_dhcp()\n");
bool provide_etc_resolv_conf = true; bool provide_etc_resolv_conf = true;
@ -43,6 +46,8 @@ void __attribute__((constructor)) init_nic_dhcp(void)
genode_int32_t ip_addr = 0; genode_int32_t ip_addr = 0;
genode_int32_t netmask = 0; genode_int32_t netmask = 0;
genode_int32_t gateway = 0; genode_int32_t gateway = 0;
Genode::Number_of_bytes tx_buf_size(BUF_SIZE);
Genode::Number_of_bytes rx_buf_size(BUF_SIZE);
try { try {
Genode::Xml_node libc_node = Genode::config()->xml_node().sub_node("libc"); Genode::Xml_node libc_node = Genode::config()->xml_node().sub_node("libc");
@ -64,6 +69,14 @@ void __attribute__((constructor)) init_nic_dhcp(void)
libc_node.attribute("gateway").value(gateway_str, sizeof(gateway_str)); libc_node.attribute("gateway").value(gateway_str, sizeof(gateway_str));
} catch(...) { } } catch(...) { }
try {
libc_node.attribute("tx_buf_size").value(&tx_buf_size);
} catch(...) { }
try {
libc_node.attribute("rx_buf_size").value(&rx_buf_size);
} catch(...) { }
/* either none or all 3 interface attributes must exist */ /* either none or all 3 interface attributes must exist */
if ((strlen(ip_addr_str) != 0) || if ((strlen(ip_addr_str) != 0) ||
(strlen(netmask_str) != 0) || (strlen(netmask_str) != 0) ||
@ -108,7 +121,8 @@ void __attribute__((constructor)) init_nic_dhcp(void)
create_lwip_plugin(); create_lwip_plugin();
try { try {
lwip_nic_init(ip_addr, netmask, gateway); lwip_nic_init(ip_addr, netmask, gateway,
(Genode::size_t)tx_buf_size, (Genode::size_t)rx_buf_size);
} catch (Genode::Parent::Service_denied) { } catch (Genode::Parent::Service_denied) {
/* ignore for now */ /* ignore for now */
} }

View File

@ -14,6 +14,12 @@
#ifndef _LWIP__NIC_H_ #ifndef _LWIP__NIC_H_
#define _LWIP__NIC_H_ #define _LWIP__NIC_H_
struct netif_buf_sizes {
__SIZE_TYPE__ tx_buf_size;
__SIZE_TYPE__ rx_buf_size;
};
/** /**
* Initializes the genode nic backend. * Initializes the genode nic backend.
* *

View File

@ -244,17 +244,15 @@ extern "C" {
LWIP_ASSERT("netif != NULL", (netif != NULL)); LWIP_ASSERT("netif != NULL", (netif != NULL));
/* Initialize nic-session */ /* Initialize nic-session */
enum {
PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
BUF_SIZE = Nic::Session::QUEUE_SIZE * PACKET_SIZE,
};
Nic::Packet_allocator *tx_block_alloc = new (env()->heap()) Nic::Packet_allocator *tx_block_alloc = new (env()->heap())
Nic::Packet_allocator(env()->heap()); Nic::Packet_allocator(env()->heap());
struct netif_buf_sizes *nbs = (struct netif_buf_sizes *) netif->state;
Nic::Connection *nic = 0; Nic::Connection *nic = 0;
try { try {
nic = new (env()->heap()) Nic::Connection(tx_block_alloc, BUF_SIZE, BUF_SIZE); nic = new (env()->heap()) Nic::Connection(tx_block_alloc,
nbs->tx_buf_size,
nbs->rx_buf_size);
} catch (Parent::Service_denied) { } catch (Parent::Service_denied) {
destroy(env()->heap(), tx_block_alloc); destroy(env()->heap(), tx_block_alloc);
return ERR_IF; return ERR_IF;

View File

@ -135,11 +135,17 @@ extern "C" {
/* in lwip/genode.h */ /* in lwip/genode.h */
int lwip_nic_init(genode_int32_t ip_addr, int lwip_nic_init(Genode::int32_t ip_addr,
genode_int32_t netmask, genode_int32_t gateway) Genode::int32_t netmask,
Genode::int32_t gateway,
Genode::size_t tx_buf_size,
Genode::size_t rx_buf_size)
{ {
static struct netif netif; static struct netif netif;
struct ip_addr ip, nm, gw; struct ip_addr ip, nm, gw;
static struct netif_buf_sizes nbs;
nbs.tx_buf_size = tx_buf_size;
nbs.rx_buf_size = rx_buf_size;
ip.addr = ip_addr; ip.addr = ip_addr;
nm.addr = netmask; nm.addr = netmask;
gw.addr = gateway; gw.addr = gateway;
@ -157,7 +163,8 @@ extern "C" {
* *
* See: http://lwip.wikia.com/wiki/Writing_a_device_driver * See: http://lwip.wikia.com/wiki/Writing_a_device_driver
*/ */
struct netif *ret = netif_add(&netif, &ip, &nm, &gw, NULL, genode_netif_init, tcpip_input); struct netif *ret = netif_add(&netif, &ip, &nm, &gw, &nbs,
genode_netif_init, tcpip_input);
if (!ret) if (!ret)
throw Nic_not_availble(); throw Nic_not_availble();

View File

@ -17,6 +17,7 @@
#include <base/thread.h> #include <base/thread.h>
#include <util/string.h> #include <util/string.h>
#include <timer_session/connection.h> #include <timer_session/connection.h>
#include <nic/packet_allocator.h>
extern "C" { extern "C" {
#include <lwip/sockets.h> #include <lwip/sockets.h>
@ -38,12 +39,14 @@ static const char *http_get_request =
*/ */
int main() int main()
{ {
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
static Timer::Connection _timer; static Timer::Connection _timer;
lwip_tcpip_init(); lwip_tcpip_init();
char serv_addr[] = "10.0.2.55"; char serv_addr[] = "10.0.2.55";
if( lwip_nic_init(0, 0, 0)) if( lwip_nic_init(0, 0, 0, BUF_SIZE, BUF_SIZE))
{ {
PERR("We got no IP address!"); PERR("We got no IP address!");
return 0; return 0;

View File

@ -21,6 +21,7 @@
#include <base/printf.h> #include <base/printf.h>
#include <base/thread.h> #include <base/thread.h>
#include <util/string.h> #include <util/string.h>
#include <nic/packet_allocator.h>
/* LwIP includes */ /* LwIP includes */
extern "C" { extern "C" {
@ -78,12 +79,14 @@ void http_server_serve(int conn) {
int main() int main()
{ {
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
int s; int s;
lwip_tcpip_init(); lwip_tcpip_init();
/* Initialize network stack and do DHCP */ /* Initialize network stack and do DHCP */
if (lwip_nic_init(0, 0, 0)) { if (lwip_nic_init(0, 0, 0, BUF_SIZE, BUF_SIZE)) {
PERR("We got no IP address!"); PERR("We got no IP address!");
return -1; return -1;
} }

View File

@ -21,6 +21,7 @@
#include <base/printf.h> #include <base/printf.h>
#include <base/thread.h> #include <base/thread.h>
#include <util/string.h> #include <util/string.h>
#include <nic/packet_allocator.h>
/* LwIP includes */ /* LwIP includes */
extern "C" { extern "C" {
@ -78,12 +79,15 @@ void http_server_serve(int conn) {
int main() int main()
{ {
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
int s; int s;
lwip_tcpip_init(); lwip_tcpip_init();
/* Initialize network stack */ /* Initialize network stack */
if (lwip_nic_init(inet_addr("10.0.2.55"), inet_addr("255.255.255.0"), inet_addr("10.0.2.1"))) { if (lwip_nic_init(inet_addr("10.0.2.55"), inet_addr("255.255.255.0"),
inet_addr("10.0.2.1"), BUF_SIZE, BUF_SIZE)) {
PERR("We got no IP address!"); PERR("We got no IP address!");
return -1; return -1;
} }

View File

@ -21,6 +21,7 @@
#include <base/printf.h> #include <base/printf.h>
#include <base/thread.h> #include <base/thread.h>
#include <util/string.h> #include <util/string.h>
#include <nic/packet_allocator.h>
/* LwIP includes */ /* LwIP includes */
extern "C" { extern "C" {
@ -98,12 +99,14 @@ void http_server_serve(int conn) {
int main() int main()
{ {
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
int s; int s;
lwip_tcpip_init(); lwip_tcpip_init();
/* Initialize network stack and do DHCP */ /* Initialize network stack and do DHCP */
if (lwip_nic_init(0, 0, 0)) { if (lwip_nic_init(0, 0, 0, BUF_SIZE, BUF_SIZE)) {
PERR("We got no IP address!"); PERR("We got no IP address!");
return -1; return -1;
} }

View File

@ -21,6 +21,7 @@
#include <base/printf.h> #include <base/printf.h>
#include <base/thread.h> #include <base/thread.h>
#include <util/string.h> #include <util/string.h>
#include <nic/packet_allocator.h>
/* LwIP includes */ /* LwIP includes */
extern "C" { extern "C" {
@ -92,6 +93,8 @@ void http_server_serve(int conn) {
int main() int main()
{ {
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
int s, c_num; int s, c_num;
fd_set rs, ws, es; fd_set rs, ws, es;
@ -99,7 +102,7 @@ int main()
lwip_tcpip_init(); lwip_tcpip_init();
/* Initialize network stack and do DHCP */ /* Initialize network stack and do DHCP */
if (lwip_nic_init(0, 0, 0)) { if (lwip_nic_init(0, 0, 0, BUF_SIZE, BUF_SIZE)) {
PERR("We got no IP address!"); PERR("We got no IP address!");
return -1; return -1;
} }

View File

@ -16,6 +16,7 @@
#include <stdio.h> #include <stdio.h>
#ifdef LWIP_NATIVE #ifdef LWIP_NATIVE
#include <nic/packet_allocator.h>
#include <lwip/genode.h> #include <lwip/genode.h>
#endif #endif
@ -139,9 +140,11 @@ main(int argc, char *argv[])
char listenip[16] = "0.0.0.0"; char listenip[16] = "0.0.0.0";
#ifdef LWIP_NATIVE #ifdef LWIP_NATIVE
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
lwip_tcpip_init(); lwip_tcpip_init();
/* DHCP */ /* DHCP */
if (lwip_nic_init(0, 0, 0)) { if (lwip_nic_init(0, 0, 0, BUF_SIZE, BUF_SIZE)) {
printf("ERROR: We got no IP address!\n"); printf("ERROR: We got no IP address!\n");
return 1; return 1;
} }

View File

@ -31,8 +31,8 @@ namespace Nic {
* \param rx_buf_size size of reception buffer in bytes * \param rx_buf_size size of reception buffer in bytes
*/ */
Connection(Genode::Range_allocator *tx_block_alloc, Connection(Genode::Range_allocator *tx_block_alloc,
Genode::size_t tx_buf_size = 64*1024, Genode::size_t tx_buf_size,
Genode::size_t rx_buf_size = 64*1024) Genode::size_t rx_buf_size)
: :
Genode::Connection<Session>( Genode::Connection<Session>(
session("ram_quota=%zd, tx_buf_size=%zd, rx_buf_size=%zd", session("ram_quota=%zd, tx_buf_size=%zd, rx_buf_size=%zd",

View File

@ -14,6 +14,7 @@
#include <base/printf.h> #include <base/printf.h>
#include <base/allocator_avl.h> #include <base/allocator_avl.h>
#include <nic_session/connection.h> #include <nic_session/connection.h>
#include <nic/packet_allocator.h>
#include <timer_session/connection.h> #include <timer_session/connection.h>
using namespace Genode; using namespace Genode;
@ -162,13 +163,15 @@ int main(int, char **)
{ {
printf("--- NIC loop-back test ---\n"); printf("--- NIC loop-back test ---\n");
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
bool config_test_roundtrip = true; bool config_test_roundtrip = true;
bool config_test_batch = true; bool config_test_batch = true;
if (config_test_roundtrip) { if (config_test_roundtrip) {
printf("-- test roundtrip two times (packet offsets should be the same) --\n"); printf("-- test roundtrip two times (packet offsets should be the same) --\n");
Allocator_avl tx_block_alloc(env()->heap()); Allocator_avl tx_block_alloc(env()->heap());
Nic::Connection nic(&tx_block_alloc); Nic::Connection nic(&tx_block_alloc, BUF_SIZE, BUF_SIZE);
single_packet_roundtrip(&nic, 'a', 100); single_packet_roundtrip(&nic, 'a', 100);
single_packet_roundtrip(&nic, 'b', 100); single_packet_roundtrip(&nic, 'b', 100);
} }
@ -176,7 +179,7 @@ int main(int, char **)
if (config_test_batch) { if (config_test_batch) {
printf("-- test submitting and receiving batches of packets --\n"); printf("-- test submitting and receiving batches of packets --\n");
Allocator_avl tx_block_alloc(env()->heap()); Allocator_avl tx_block_alloc(env()->heap());
Nic::Connection nic(&tx_block_alloc); Nic::Connection nic(&tx_block_alloc, BUF_SIZE, BUF_SIZE);
enum { NUM_PACKETS = 1000 }; enum { NUM_PACKETS = 1000 };
batch_packets(&nic, NUM_PACKETS); batch_packets(&nic, NUM_PACKETS);
} }

View File

@ -161,10 +161,10 @@ append config {
<arg value="netserver"/> <arg value="netserver"/>
<arg value="-D"/> <arg value="-D"/>
<arg value="-4"/> <arg value="-4"/>
<arg value="-f"/>} <arg value="-f"/>
append_if [have_spec linux] config " <libc tx_buf_size="2M" rx_buf_size="2M"}
<libc ip_addr=\"$lx_ip_addr\" netmask=\"255.255.255.0\" gateway=\"10.0.2.1\"/>" append_if [have_spec linux] config "ip_addr=\"$lx_ip_addr\" netmask=\"255.255.255.0\" gateway=\"10.0.2.1\""
append config { append config {/>
</config>} </config>}
append_if $use_nic_bridge config { append_if $use_nic_bridge config {
<route> <route>