# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1196253657 0
# Node ID 8d406e2813c8b32790d63a727a9185e97f3eaf75
# Parent f173cd885ffb3dc530ae082429ce75da978af867
[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@xxxxxxxxxx>
---
extras/mini-os/gnttab.c | 14 ++++++++++++--
extras/mini-os/netfront.c | 6 ++++--
2 files changed, 16 insertions(+), 4 deletions(-)
diff -r f173cd885ffb -r 8d406e2813c8 extras/mini-os/gnttab.c
--- a/extras/mini-os/gnttab.c Wed Nov 28 12:34:11 2007 +0000
+++ b/extras/mini-os/gnttab.c Wed Nov 28 12:40:57 2007 +0000
@@ -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;
}
diff -r f173cd885ffb -r 8d406e2813c8 extras/mini-os/netfront.c
--- a/extras/mini-os/netfront.c Wed Nov 28 12:34:11 2007 +0000
+++ b/extras/mini-os/netfront.c Wed Nov 28 12:40:57 2007 +0000
@@ -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,i
down(&tx_sem);
local_irq_save(flags);
-
id = get_id_from_freelist(tx_freelist);
+ local_irq_restore(flags);
+
buf = &tx_buffers[id];
page = buf->page;
@@ -461,7 +463,7 @@ void netfront_xmit(unsigned char* data,i
if(notify) notify_remote_via_evtchn(info->evtchn);
+ local_irq_save(flags);
network_tx_buf_gc();
-
local_irq_restore(flags);
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|