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:
parent
5c36639031
commit
7ca7b4417d
|
@ -28,12 +28,16 @@ requires_installation_of lynx
|
||||||
# Build
|
# Build
|
||||||
#
|
#
|
||||||
|
|
||||||
build {
|
set build_components {
|
||||||
core init
|
core init
|
||||||
drivers/pci drivers/timer drivers/nic
|
drivers/pci drivers/timer drivers/nic
|
||||||
test/lwip/http_srv
|
test/lwip/http_srv
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lappend_if [have_spec omap4] build_components drivers/usb
|
||||||
|
|
||||||
|
build $build_components
|
||||||
|
|
||||||
create_boot_directory
|
create_boot_directory
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -62,14 +66,27 @@ set config {
|
||||||
<resource name="RAM" quantum="1M"/>
|
<resource name="RAM" quantum="1M"/>
|
||||||
<provides> <service name="Timer"/> </provides>
|
<provides> <service name="Timer"/> </provides>
|
||||||
</start>
|
</start>
|
||||||
<start name="nic_drv">
|
|
||||||
<resource name="RAM" quantum="2M"/>
|
|
||||||
<provides> <service name="Nic"/> </provides>
|
|
||||||
</start>
|
|
||||||
<start name="test-lwip_httpsrv">
|
<start name="test-lwip_httpsrv">
|
||||||
<resource name="RAM" quantum="2M"/>
|
<resource name="RAM" quantum="2M"/>
|
||||||
</start> }
|
</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 {
|
append_if [have_spec pci] config {
|
||||||
<start name="pci_drv">
|
<start name="pci_drv">
|
||||||
<resource name="RAM" quantum="1M"/>
|
<resource name="RAM" quantum="1M"/>
|
||||||
|
@ -89,12 +106,13 @@ install_config $config
|
||||||
# generic modules
|
# generic modules
|
||||||
set boot_modules {
|
set boot_modules {
|
||||||
core init timer
|
core init timer
|
||||||
nic_drv
|
|
||||||
ld.lib.so libc.lib.so libc_log.lib.so lwip.lib.so test-lwip_httpsrv
|
ld.lib.so libc.lib.so libc_log.lib.so lwip.lib.so test-lwip_httpsrv
|
||||||
}
|
}
|
||||||
|
|
||||||
# platform-specific modules
|
# 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
|
build_boot_image $boot_modules
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/thread.h>
|
#include <base/thread.h>
|
||||||
#include <base/printf.h>
|
#include <base/printf.h>
|
||||||
#include <base/allocator_avl.h>
|
#include <nic/packet_allocator.h>
|
||||||
#include <nic_session/connection.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 */
|
Packet_descriptor _rx_packet; /* actual packet received */
|
||||||
struct netif *_netif; /* LwIP network interface structure */
|
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:
|
public:
|
||||||
|
|
||||||
Nic_receiver_thread(Nic::Connection *nic, struct netif *netif)
|
Nic_receiver_thread(Nic::Connection *nic, struct netif *netif)
|
||||||
|
@ -51,6 +61,29 @@ class Nic_receiver_thread : public Genode::Thread<8192>
|
||||||
void entry();
|
void entry();
|
||||||
Nic::Connection *nic() { return _nic; };
|
Nic::Connection *nic() { return _nic; };
|
||||||
Packet_descriptor rx_packet() { return _rx_packet; };
|
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)
|
low_level_output(struct netif *netif, struct pbuf *p)
|
||||||
{
|
{
|
||||||
Nic_receiver_thread *th = reinterpret_cast<Nic_receiver_thread*>(netif->state);
|
Nic_receiver_thread *th = reinterpret_cast<Nic_receiver_thread*>(netif->state);
|
||||||
Nic::Connection *nic = th->nic();
|
|
||||||
|
|
||||||
#if ETH_PAD_SIZE
|
#if ETH_PAD_SIZE
|
||||||
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
||||||
#endif
|
#endif
|
||||||
try {
|
Packet_descriptor tx_packet = th->alloc_tx_packet(p->tot_len);
|
||||||
Packet_descriptor tx_packet = nic->tx()->alloc_packet(p->tot_len);
|
char *tx_content = th->content(tx_packet);
|
||||||
char *tx_content = nic->tx()->packet_content(tx_packet);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iterate through all pbufs and
|
* Iterate through all pbufs and
|
||||||
* copy payload into packet's payload
|
* copy payload into packet's payload
|
||||||
*/
|
*/
|
||||||
for(struct pbuf *q = p; q != NULL; q = q->next) {
|
for(struct pbuf *q = p; q != NULL; q = q->next) {
|
||||||
char *src = (char*) q->payload;
|
char *src = (char*) q->payload;
|
||||||
for (unsigned i = 0; i < q->len; i++)
|
Genode::memcpy(tx_content, src, q->len);
|
||||||
tx_content[i] = src[i];
|
tx_content += q->len;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for acknowledgements */
|
/* Submit packet */
|
||||||
while (nic->tx()->ack_avail()) {
|
th->submit_tx_packet(tx_packet);
|
||||||
Packet_descriptor acked_packet = nic->tx()->get_acked_packet();
|
|
||||||
nic->tx()->release_packet(acked_packet);
|
|
||||||
}
|
|
||||||
#if ETH_PAD_SIZE
|
#if ETH_PAD_SIZE
|
||||||
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
||||||
#endif
|
#endif
|
||||||
|
@ -156,10 +176,10 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
for(struct pbuf *q = p; q != 0; q = q->next) {
|
for(struct pbuf *q = p; q != 0; q = q->next) {
|
||||||
char *dst = (char*)q->payload;
|
char *dst = (char*)q->payload;
|
||||||
for(unsigned i=0; i < q->len; ++i)
|
Genode::memcpy(dst, rx_content, q->len);
|
||||||
dst[i] = rx_content[i];
|
|
||||||
rx_content += q->len;
|
rx_content += q->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ETH_PAD_SIZE
|
#if ETH_PAD_SIZE
|
||||||
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
||||||
#endif
|
#endif
|
||||||
|
@ -222,12 +242,18 @@ extern "C" {
|
||||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||||
|
|
||||||
/* Initialize nic-session */
|
/* Initialize nic-session */
|
||||||
Allocator_avl *tx_block_alloc = new (env()->heap())
|
enum {
|
||||||
Allocator_avl(env()->heap());
|
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;
|
Nic::Connection *nic = 0;
|
||||||
try {
|
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) {
|
} catch (Parent::Service_denied) {
|
||||||
destroy(env()->heap(), tx_block_alloc);
|
destroy(env()->heap(), tx_block_alloc);
|
||||||
return ERR_IF;
|
return ERR_IF;
|
||||||
|
|
|
@ -18,6 +18,8 @@ set build_components {
|
||||||
app/lighttpd
|
app/lighttpd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lappend_if [have_spec omap4] build_components drivers/usb
|
||||||
|
|
||||||
build $build_components
|
build $build_components
|
||||||
|
|
||||||
create_boot_directory
|
create_boot_directory
|
||||||
|
|
Loading…
Reference in New Issue