diff options
author | kaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk> | 2004-10-07 16:30:38 +0000 |
---|---|---|
committer | kaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk> | 2004-10-07 16:30:38 +0000 |
commit | 6213b696ba656fbc262f00e9846bf4f10a5967cf (patch) | |
tree | 44ebdb55480f39eda6140e5968db6182f338fcd3 /linux-2.6.8.1-xen-sparse/arch | |
parent | 37d9a01369c898598ba844b19888d06d569b2829 (diff) | |
download | xen-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.c | 135 |
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); |