aboutsummaryrefslogtreecommitdiffstats
path: root/extras/mini-os/netfront.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2007-11-24 13:28:54 +0000
committerKeir Fraser <keir.fraser@citrix.com>2007-11-24 13:28:54 +0000
commitcf64298141ead63b0b72fdee091d62f1148e89e1 (patch)
treeeccd171e631effb71d2cf688c74503d747d600d7 /extras/mini-os/netfront.c
parent051f29b827971f9633a1b78ab6d7fe5101bd4005 (diff)
downloadxen-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.c22
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);