ia64/xen-unstable

changeset 16446:7eea09b18839

[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>
author Keir Fraser <keir.fraser@citrix.com>
date Sat Nov 24 13:28:54 2007 +0000 (2007-11-24)
parents eac7ef8ba544
children ee519207734f
files extras/mini-os/netfront.c
line diff
     1.1 --- a/extras/mini-os/netfront.c	Sat Nov 24 13:28:27 2007 +0000
     1.2 +++ b/extras/mini-os/netfront.c	Sat Nov 24 13:28:54 2007 +0000
     1.3 @@ -13,6 +13,7 @@
     1.4  #include <gnttab.h>
     1.5  #include <xmalloc.h>
     1.6  #include <time.h>
     1.7 +#include <semaphore.h>
     1.8  
     1.9  void init_rx_buffers(void);
    1.10  
    1.11 @@ -48,6 +49,7 @@ char* xenbus_printf(xenbus_transaction_t
    1.12  
    1.13  unsigned short rx_freelist[NET_RX_RING_SIZE];
    1.14  unsigned short tx_freelist[NET_TX_RING_SIZE];
    1.15 +__DECLARE_SEMAPHORE_GENERIC(tx_sem, NET_TX_RING_SIZE);
    1.16  
    1.17  struct net_buffer {
    1.18      void* page;
    1.19 @@ -188,6 +190,7 @@ void network_tx_buf_gc(void)
    1.20              buf->gref=GRANT_INVALID_REF;
    1.21  
    1.22              add_id_to_freelist(id,tx_freelist);
    1.23 +            up(&tx_sem);
    1.24          }
    1.25  
    1.26          np->tx.rsp_cons = prod;
    1.27 @@ -422,16 +425,23 @@ void init_rx_buffers(void)
    1.28  void netfront_xmit(unsigned char* data,int len)
    1.29  {
    1.30      int flags;
    1.31 -    local_irq_save(flags);
    1.32 -
    1.33      struct net_info* info = &net_info;
    1.34      struct netif_tx_request *tx;
    1.35 -    RING_IDX i = info->tx.req_prod_pvt;
    1.36 +    RING_IDX i;
    1.37      int notify;
    1.38 -    int id = get_id_from_freelist(tx_freelist);
    1.39 -    struct net_buffer* buf = &tx_buffers[id];
    1.40 -    void* page = buf->page;
    1.41 +    int id;
    1.42 +    struct net_buffer* buf;
    1.43 +    void* page;
    1.44  
    1.45 +    down(&tx_sem);
    1.46 +
    1.47 +    local_irq_save(flags);
    1.48 +
    1.49 +    id = get_id_from_freelist(tx_freelist);
    1.50 +    buf = &tx_buffers[id];
    1.51 +    page = buf->page;
    1.52 +
    1.53 +    i = info->tx.req_prod_pvt;
    1.54      tx = RING_GET_REQUEST(&info->tx, i);
    1.55  
    1.56      memcpy(page,data,len);