ia64/xen-unstable

changeset 16488:8d406e2813c8

[Mini-OS] Make gnttab allocation/free safe

Add a semaphore to protect gnttab_list from exhaustion, and disable
callbacks during allocation/free. Fix the network frontend accordingly.

Signed-off-by: Samuel Thibault <samuel.thibault@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Nov 28 12:40:57 2007 +0000 (2007-11-28)
parents f173cd885ffb
children 74bd94747ca3
files extras/mini-os/gnttab.c extras/mini-os/netfront.c
line diff
     1.1 --- a/extras/mini-os/gnttab.c	Wed Nov 28 12:34:11 2007 +0000
     1.2 +++ b/extras/mini-os/gnttab.c	Wed Nov 28 12:40:57 2007 +0000
     1.3 @@ -18,6 +18,7 @@
     1.4  #include <os.h>
     1.5  #include <mm.h>
     1.6  #include <gnttab.h>
     1.7 +#include <semaphore.h>
     1.8  
     1.9  #define NR_RESERVED_ENTRIES 8
    1.10  
    1.11 @@ -31,20 +32,29 @@
    1.12  
    1.13  static grant_entry_t *gnttab_table;
    1.14  static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
    1.15 +static __DECLARE_SEMAPHORE_GENERIC(gnttab_sem, NR_GRANT_ENTRIES);
    1.16  
    1.17  static void
    1.18  put_free_entry(grant_ref_t ref)
    1.19  {
    1.20 +    unsigned long flags;
    1.21 +    local_irq_save(flags);
    1.22      gnttab_list[ref] = gnttab_list[0];
    1.23      gnttab_list[0]  = ref;
    1.24 -
    1.25 +    local_irq_restore(flags);
    1.26 +    up(&gnttab_sem);
    1.27  }
    1.28  
    1.29  static grant_ref_t
    1.30  get_free_entry(void)
    1.31  {
    1.32 -    unsigned int ref = gnttab_list[0];
    1.33 +    unsigned int ref;
    1.34 +    unsigned long flags;
    1.35 +    down(&gnttab_sem);
    1.36 +    local_irq_save(flags);
    1.37 +    ref = gnttab_list[0];
    1.38      gnttab_list[0] = gnttab_list[ref];
    1.39 +    local_irq_restore(flags);
    1.40      return ref;
    1.41  }
    1.42  
     2.1 --- a/extras/mini-os/netfront.c	Wed Nov 28 12:34:11 2007 +0000
     2.2 +++ b/extras/mini-os/netfront.c	Wed Nov 28 12:40:57 2007 +0000
     2.3 @@ -147,6 +147,7 @@ moretodo:
     2.4          struct net_buffer* buf = &rx_buffers[id];
     2.5          void* page = buf->page;
     2.6  
     2.7 +        /* We are sure to have free gnttab entries since they got released above */
     2.8          buf->gref = req->gref = 
     2.9              gnttab_grant_access(0,virt_to_mfn(page),0);
    2.10  
    2.11 @@ -436,8 +437,9 @@ void netfront_xmit(unsigned char* data,i
    2.12      down(&tx_sem);
    2.13  
    2.14      local_irq_save(flags);
    2.15 +    id = get_id_from_freelist(tx_freelist);
    2.16 +    local_irq_restore(flags);
    2.17  
    2.18 -    id = get_id_from_freelist(tx_freelist);
    2.19      buf = &tx_buffers[id];
    2.20      page = buf->page;
    2.21  
    2.22 @@ -461,7 +463,7 @@ void netfront_xmit(unsigned char* data,i
    2.23  
    2.24      if(notify) notify_remote_via_evtchn(info->evtchn);
    2.25  
    2.26 +    local_irq_save(flags);
    2.27      network_tx_buf_gc();
    2.28 -
    2.29      local_irq_restore(flags);
    2.30  }