Make gnttab allocation/free safe
PATCH 1/1 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 <[email protected]>
extras/mini-os/gnttab.c +12 -2
@@ -18,6 +18,7 @@#include <os.h> #include <mm.h> #include <gnttab.h> +#include <semaphore.h> #define NR_RESERVED_ENTRIES 8
@@ -31,20 +32,29 @@static grant_entry_t *gnttab_table;static grant_ref_t gnttab_list[NR_GRANT_ENTRIES ]; +static __DECLARE_SEMAPHORE_GENERIC(gnttab_sem, NR_GRANT_ENTRIES);static void put_free_entry (grant_ref_t ref) { +unsigned long flags; +local_irq_save (flags); gnttab_list[ref] = gnttab_list[0 ]; gnttab_list[0 ] = ref; - +local_irq_restore (flags); +up (&gnttab_sem); }static grant_ref_t get_free_entry (void ) { -unsigned int ref = gnttab_list[0 ]; +unsigned int ref; +unsigned long flags; +down (&gnttab_sem); +local_irq_save (flags); + ref = gnttab_list[0 ]; gnttab_list[0 ] = gnttab_list[ref]; +local_irq_restore (flags);return ref; }
extras/mini-os/netfront.c +4 -2
@@ -147,6 +147,7 @@ moretodo:struct net_buffer * buf = &rx_buffers[id];void * page = buf->page; +/* We are sure to have free gnttab entries since they got released above */ buf->gref = req->gref =gnttab_grant_access (0 ,virt_to_mfn (page),0 );
@@ -436,8 +437,9 @@ void netfront_xmit(unsigned char* data,idown (&tx_sem);local_irq_save (flags); + id =get_id_from_freelist (tx_freelist); +local_irq_restore (flags); - id =get_id_from_freelist (tx_freelist); buf = &tx_buffers[id]; page = buf->page;
@@ -461,7 +463,7 @@ void netfront_xmit(unsigned char* data,iif (notify)notify_remote_via_evtchn (info->evtchn); +local_irq_save (flags);network_tx_buf_gc (); -local_irq_restore (flags); }