diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2007-11-24 13:28:54 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2007-11-24 13:28:54 +0000 |
commit | cf64298141ead63b0b72fdee091d62f1148e89e1 (patch) | |
tree | eccd171e631effb71d2cf688c74503d747d600d7 /extras/mini-os/netfront.c | |
parent | 051f29b827971f9633a1b78ab6d7fe5101bd4005 (diff) | |
download | xen-cf64298141ead63b0b72fdee091d62f1148e89e1.tar.gz xen-cf64298141ead63b0b72fdee091d62f1148e89e1.tar.bz2 xen-cf64298141ead63b0b72fdee091d62f1148e89e1.zip |
[Mini-OS] Fix netfront xmit overflow
Fix xmit overflow by making netfront_xmit sleep until
network_tx_buf_gc() frees an xmit request.
Signed-off-by: Samuel Thibault <samuel.thibault@citrix.com>
Diffstat (limited to 'extras/mini-os/netfront.c')
-rw-r--r-- | extras/mini-os/netfront.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/extras/mini-os/netfront.c b/extras/mini-os/netfront.c index d952a02491..fc1e9ab357 100644 --- a/extras/mini-os/netfront.c +++ b/extras/mini-os/netfront.c @@ -13,6 +13,7 @@ #include <gnttab.h> #include <xmalloc.h> #include <time.h> +#include <semaphore.h> void init_rx_buffers(void); @@ -48,6 +49,7 @@ char* xenbus_printf(xenbus_transaction_t xbt, unsigned short rx_freelist[NET_RX_RING_SIZE]; unsigned short tx_freelist[NET_TX_RING_SIZE]; +__DECLARE_SEMAPHORE_GENERIC(tx_sem, NET_TX_RING_SIZE); struct net_buffer { void* page; @@ -188,6 +190,7 @@ void network_tx_buf_gc(void) buf->gref=GRANT_INVALID_REF; add_id_to_freelist(id,tx_freelist); + up(&tx_sem); } np->tx.rsp_cons = prod; @@ -422,16 +425,23 @@ void init_rx_buffers(void) void netfront_xmit(unsigned char* data,int len) { int flags; - local_irq_save(flags); - struct net_info* info = &net_info; struct netif_tx_request *tx; - RING_IDX i = info->tx.req_prod_pvt; + RING_IDX i; int notify; - int id = get_id_from_freelist(tx_freelist); - struct net_buffer* buf = &tx_buffers[id]; - void* page = buf->page; + int id; + struct net_buffer* buf; + void* page; + + down(&tx_sem); + + local_irq_save(flags); + + id = get_id_from_freelist(tx_freelist); + buf = &tx_buffers[id]; + page = buf->page; + i = info->tx.req_prod_pvt; tx = RING_GET_REQUEST(&info->tx, i); memcpy(page,data,len); |