lwIP: Rewrite NIC packet allocation

Use 'Nic::Packet_allocator', wait for acknowledgements if packet allocation
fails. Updated 'lwip.run' and 'genode_org.run' to support OMAP4 correctly. Use
memcpy to copy PBUFs

May resolve issue #347
This commit is contained in:
Sebastian Sumpf 2012-09-05 12:04:00 +02:00 committed by Norman Feske
parent 5c36639031
commit 7ca7b4417d
3 changed files with 85 additions and 39 deletions

View File

@ -28,12 +28,16 @@ requires_installation_of lynx
# Build
#
build {
set build_components {
core init
drivers/pci drivers/timer drivers/nic
test/lwip/http_srv
}
lappend_if [have_spec omap4] build_components drivers/usb
build $build_components
create_boot_directory
#
@ -62,14 +66,27 @@ set config {
<resource name="RAM" quantum="1M"/>
<provides> <service name="Timer"/> </provides>
</start>
<start name="nic_drv">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Nic"/> </provides>
</start>
<start name="test-lwip_httpsrv">
<resource name="RAM" quantum="2M"/>
</start> }
append_if [have_spec omap4] config {
<start name="usb_drv" priority="-1">
<resource name="RAM" quantum="12M"/>
<provides>
<service name="Nic"/>
</provides>
<config>
<nic mac="2e:60:90:0c:4e:01" />
</config>
</start>}
append_if [expr ![have_spec omap4]] config {
<start name="nic_drv">
<resource name="RAM" quantum="4M"/>
<provides><service name="Nic"/></provides>
</start>}
append_if [have_spec pci] config {
<start name="pci_drv">
<resource name="RAM" quantum="1M"/>
@ -89,12 +106,13 @@ install_config $config
# generic modules
set boot_modules {
core init timer
nic_drv
ld.lib.so libc.lib.so libc_log.lib.so lwip.lib.so test-lwip_httpsrv
}
# platform-specific modules
lappend_if [have_spec pci] boot_modules pci_drv
lappend_if [have_spec pci] boot_modules pci_drv
lappend_if [have_spec omap4] boot_modules usb_drv
lappend_if [expr ![have_spec omap4]] boot_modules nic_drv
build_boot_image $boot_modules

View File

@ -28,7 +28,7 @@ extern "C" {
/* Genode includes */
#include <base/thread.h>
#include <base/printf.h>
#include <base/allocator_avl.h>
#include <nic/packet_allocator.h>
#include <nic_session/connection.h>
@ -43,6 +43,16 @@ class Nic_receiver_thread : public Genode::Thread<8192>
Packet_descriptor _rx_packet; /* actual packet received */
struct netif *_netif; /* LwIP network interface structure */
void _tx_ack(bool block = false)
{
/* check for acknowledgements */
while (nic()->tx()->ack_avail() || block) {
Packet_descriptor acked_packet = nic()->tx()->get_acked_packet();
nic()->tx()->release_packet(acked_packet);
block = false;
}
}
public:
Nic_receiver_thread(Nic::Connection *nic, struct netif *netif)
@ -51,6 +61,29 @@ class Nic_receiver_thread : public Genode::Thread<8192>
void entry();
Nic::Connection *nic() { return _nic; };
Packet_descriptor rx_packet() { return _rx_packet; };
Packet_descriptor alloc_tx_packet(Genode::size_t size)
{
while (true) {
try {
Packet_descriptor packet = nic()->tx()->alloc_packet(size);
return packet;
} catch(Nic::Session::Tx::Source::Packet_alloc_failed) {
/* packet allocator exhausted, wait for acknowledgements */
_tx_ack(true);
}
}
}
void submit_tx_packet(Packet_descriptor packet)
{
nic()->tx()->submit_packet(packet);
/* check for acknowledgements */
_tx_ack();
}
char *content(Packet_descriptor packet) {
return nic()->tx()->packet_content(packet); }
};
@ -81,39 +114,26 @@ extern "C" {
low_level_output(struct netif *netif, struct pbuf *p)
{
Nic_receiver_thread *th = reinterpret_cast<Nic_receiver_thread*>(netif->state);
Nic::Connection *nic = th->nic();
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
try {
Packet_descriptor tx_packet = nic->tx()->alloc_packet(p->tot_len);
char *tx_content = nic->tx()->packet_content(tx_packet);
Packet_descriptor tx_packet = th->alloc_tx_packet(p->tot_len);
char *tx_content = th->content(tx_packet);
/*
* Iterate through all pbufs and
* copy payload into packet's payload
*/
for(struct pbuf *q = p; q != NULL; q = q->next) {
char *src = (char*) q->payload;
for (unsigned i = 0; i < q->len; i++)
tx_content[i] = src[i];
tx_content += q->len;
}
/* Submit packet */
nic->tx()->submit_packet(tx_packet);
} catch(Nic::Session::Tx::Source::Packet_alloc_failed)
{
PWRN("Packets to NIC were dropped!");
return ERR_MEM;
/*
* Iterate through all pbufs and
* copy payload into packet's payload
*/
for(struct pbuf *q = p; q != NULL; q = q->next) {
char *src = (char*) q->payload;
Genode::memcpy(tx_content, src, q->len);
tx_content += q->len;
}
/* Check for acknowledgements */
while (nic->tx()->ack_avail()) {
Packet_descriptor acked_packet = nic->tx()->get_acked_packet();
nic->tx()->release_packet(acked_packet);
}
/* Submit packet */
th->submit_tx_packet(tx_packet);
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
@ -156,10 +176,10 @@ extern "C" {
*/
for(struct pbuf *q = p; q != 0; q = q->next) {
char *dst = (char*)q->payload;
for(unsigned i=0; i < q->len; ++i)
dst[i] = rx_content[i];
Genode::memcpy(dst, rx_content, q->len);
rx_content += q->len;
}
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
@ -222,12 +242,18 @@ extern "C" {
LWIP_ASSERT("netif != NULL", (netif != NULL));
/* Initialize nic-session */
Allocator_avl *tx_block_alloc = new (env()->heap())
Allocator_avl(env()->heap());
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,
};
Nic::Packet_allocator *tx_block_alloc = new (env()->heap())
Nic::Packet_allocator(env()->heap());
Nic::Connection *nic = 0;
try {
nic = new (env()->heap()) Nic::Connection(tx_block_alloc);
nic = new (env()->heap()) Nic::Connection(tx_block_alloc, TX_BUF_SIZE, RX_BUF_SIZE);
} catch (Parent::Service_denied) {
destroy(env()->heap(), tx_block_alloc);
return ERR_IF;

View File

@ -18,6 +18,8 @@ set build_components {
app/lighttpd
}
lappend_if [have_spec omap4] build_components drivers/usb
build $build_components
create_boot_directory