From cf64298141ead63b0b72fdee091d62f1148e89e1 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Sat, 24 Nov 2007 13:28:54 +0000 Subject: [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 --- extras/mini-os/netfront.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'extras/mini-os/netfront.c') 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 #include #include +#include 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); -- cgit v1.2.3