aboutsummaryrefslogtreecommitdiffstats
path: root/linux-2.6.8.1-xen-sparse/arch
diff options
context:
space:
mode:
authorkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>2004-10-07 16:30:38 +0000
committerkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>2004-10-07 16:30:38 +0000
commit6213b696ba656fbc262f00e9846bf4f10a5967cf (patch)
tree44ebdb55480f39eda6140e5968db6182f338fcd3 /linux-2.6.8.1-xen-sparse/arch
parent37d9a01369c898598ba844b19888d06d569b2829 (diff)
downloadxen-6213b696ba656fbc262f00e9846bf4f10a5967cf.tar.gz
xen-6213b696ba656fbc262f00e9846bf4f10a5967cf.tar.bz2
xen-6213b696ba656fbc262f00e9846bf4f10a5967cf.zip
bitkeeper revision 1.1159.1.216 (41656f2ek7HkbBXpAt8AAbtJEyjlTg)
Grant-table interface redone.
Diffstat (limited to 'linux-2.6.8.1-xen-sparse/arch')
-rw-r--r--linux-2.6.8.1-xen-sparse/arch/xen/kernel/gnttab.c135
1 files changed, 32 insertions, 103 deletions
diff --git a/linux-2.6.8.1-xen-sparse/arch/xen/kernel/gnttab.c b/linux-2.6.8.1-xen-sparse/arch/xen/kernel/gnttab.c
index c76df4b1e4..af892aeb2a 100644
--- a/linux-2.6.8.1-xen-sparse/arch/xen/kernel/gnttab.c
+++ b/linux-2.6.8.1-xen-sparse/arch/xen/kernel/gnttab.c
@@ -33,22 +33,9 @@ EXPORT_SYMBOL(gnttab_end_foreign_access);
EXPORT_SYMBOL(gnttab_grant_foreign_transfer);
EXPORT_SYMBOL(gnttab_end_foreign_transfer);
-struct gntent_auxinfo {
- u16 write_pin, read_pin; /* reference counts */
- u16 inuse;
- grant_ref_t next; /* hash chain */
-};
-
#define NR_GRANT_REFS 512
-
-static struct gntent_auxinfo auxtab[NR_GRANT_REFS];
+static grant_ref_t gnttab_free_list[NR_GRANT_REFS];
static grant_ref_t gnttab_free_head;
-static spinlock_t gnttab_lock;
-
-#define HASH_INVALID (0xFFFFU)
-#define GNTTAB_HASH_SZ 512
-#define GNTTAB_HASH(_f) ((_f) & (GNTTAB_HASH_SZ-1))
-static grant_ref_t gnttab_hash[GNTTAB_HASH_SZ];
static grant_entry_t *shared;
@@ -56,14 +43,14 @@ static grant_entry_t *shared;
* Lock-free grant-entry allocator
*/
-static inline grant_ref_t
+static inline int
get_free_entry(
void)
{
grant_ref_t fh, nfh = gnttab_free_head;
- do { fh = nfh; }
+ do { if ( unlikely((fh = nfh) == NR_GRANT_REFS) ) return -1; }
while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh,
- auxtab[fh].next)) != fh) );
+ gnttab_free_list[fh])) != fh) );
return fh;
}
@@ -72,109 +59,55 @@ put_free_entry(
grant_ref_t ref)
{
grant_ref_t fh, nfh = gnttab_free_head;
- do { auxtab[ref].next = fh = nfh; wmb(); }
+ do { gnttab_free_list[ref] = fh = nfh; wmb(); }
while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh, ref)) != fh) );
}
/*
- * Public interface functions
+ * Public grant-issuing interface functions
*/
-grant_ref_t
+int
gnttab_grant_foreign_access(
domid_t domid, unsigned long frame, int readonly)
{
- unsigned long flags;
- grant_ref_t ref;
-
- spin_lock_irqsave(&gnttab_lock, flags);
-
- for ( ref = gnttab_hash[GNTTAB_HASH(frame)];
- ref != HASH_INVALID;
- ref = auxtab[ref].next )
- {
- if ( auxtab[ref].inuse && (shared[ref].frame == frame) )
- {
- if ( readonly )
- auxtab[ref].read_pin++;
- else if ( auxtab[ref].write_pin++ == 0 )
- clear_bit(_GTF_readonly, (unsigned long *)&shared[ref].flags);
- goto done;
- }
- }
-
- ref = get_free_entry();
- auxtab[ref].inuse = 1;
- auxtab[ref].read_pin = !!readonly;
- auxtab[ref].write_pin = !readonly;
- auxtab[ref].next = gnttab_hash[GNTTAB_HASH(frame)];
- gnttab_hash[GNTTAB_HASH(frame)] = ref;
+ int ref;
+
+ if ( unlikely((ref = get_free_entry()) == -1) )
+ return -ENOSPC;
shared[ref].frame = frame;
shared[ref].domid = domid;
wmb();
shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
- done:
- spin_unlock_irqrestore(&gnttab_lock, flags);
- return 0;
+ return ref;
}
void
gnttab_end_foreign_access(
grant_ref_t ref, int readonly)
{
- unsigned long flags, frame = shared[ref].frame;
- grant_ref_t *pref;
- u16 sflags, nsflags;
-
- spin_lock_irqsave(&gnttab_lock, flags);
+ u16 flags, nflags;
- if ( readonly )
- {
- if ( (auxtab[ref].read_pin-- == 0) && (auxtab[ref].write_pin == 0) )
- goto delete;
- }
- else if ( auxtab[ref].write_pin-- == 0 )
- {
- if ( auxtab[ref].read_pin == 0 )
- goto delete;
- nsflags = shared[ref].flags;
- do {
- if ( (sflags = nsflags) & GTF_writing )
- printk(KERN_ALERT "WARNING: g.e. still in use for writing!\n");
- }
- while ( (nsflags = cmpxchg(&shared[ref].flags, sflags,
- sflags | GTF_readonly)) != sflags );
- }
-
- goto out;
-
- delete:
- nsflags = shared[ref].flags;
+ nflags = shared[ref].flags;
do {
- if ( (sflags = nsflags) & (GTF_reading|GTF_writing) )
+ if ( (flags = nflags) & (GTF_reading|GTF_writing) )
printk(KERN_ALERT "WARNING: g.e. still in use!\n");
}
- while ( (nsflags = cmpxchg(&shared[ref].flags, sflags, 0)) != sflags );
+ while ( (nflags = cmpxchg(&shared[ref].flags, flags, 0)) != flags );
- pref = &gnttab_hash[GNTTAB_HASH(frame)];
- while ( *pref != ref )
- pref = &auxtab[*pref].next;
- *pref = auxtab[ref].next;
-
- auxtab[ref].inuse = 0;
put_free_entry(ref);
-
- out:
- spin_unlock_irqrestore(&gnttab_lock, flags);
}
-grant_ref_t
+int
gnttab_grant_foreign_transfer(
domid_t domid)
{
- grant_ref_t ref = get_free_entry();
+ int ref;
+
+ if ( unlikely((ref = get_free_entry()) == -1) )
+ return -ENOSPC;
shared[ref].frame = 0;
shared[ref].domid = domid;
@@ -210,23 +143,19 @@ gnttab_end_foreign_transfer(
void __init gnttab_init(void)
{
- int i;
- gnttab_op_t gntop;
- unsigned long frame;
-
- spin_lock_init(&gnttab_lock);
+ gnttab_setup_table_t setup;
+ unsigned long frame;
+ int i;
- for ( i = 0; i < GNTTAB_HASH_SZ; i++ )
- {
- gnttab_hash[i] = HASH_INVALID;
- auxtab[i].next = i+1;
- }
+ for ( i = 0; i < NR_GRANT_REFS; i++ )
+ gnttab_free_list[i] = i + 1;
- gntop.cmd = GNTTABOP_setup_table;
- gntop.u.setup_table.dom = DOMID_SELF;
- gntop.u.setup_table.nr_frames = 1;
- gntop.u.setup_table.frame_list = &frame;
- if ( HYPERVISOR_grant_table_op(&gntop) != 0 )
+ setup.dom = DOMID_SELF;
+ setup.nr_frames = 1;
+ setup.frame_list = &frame;
+ if ( HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1) != 0 )
+ BUG();
+ if ( setup.status != 0 )
BUG();
set_fixmap_ma(FIX_GNTTAB, frame << PAGE_SHIFT);