[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XenPPC] [rfc] [patch] grant_entry.flags accessors
These patches are similar to changeset 10747 (which added vcpu_mark_events_pending), in that they allow PPC to work around some unusually-sized atomic operations, this time in the grant table driver. Keir, do you think it's a good idea to make a wiki page to list where the current ABI is causing problems? That way, when the ABI opens up again (Xen 4?), we'll have a list of places to fix? Anyways, I expect you'll have alternate name/interface suggestions in the patches, so they're just RFC for now. Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx> diff -r b3dfb02fc2c2 xen/common/grant_table.c --- a/xen/common/grant_table.c Thu Jun 22 10:58:41 2006 -0500 +++ b/xen/common/grant_table.c Fri Jun 23 16:13:48 2006 -0500 @@ -287,10 +287,10 @@ __gnttab_map_grant_ref( if ( !(op->flags & GNTMAP_readonly) && !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) ) - clear_bit(_GTF_writing, &sha->flags); + clear_entry_flag(_GTF_writing, &sha->flags); if ( !act->pin ) - clear_bit(_GTF_reading, &sha->flags); + clear_entry_flag(_GTF_reading, &sha->flags); unlock_out: spin_unlock(&rd->grant_table->lock); @@ -425,10 +425,10 @@ __gnttab_unmap_grant_ref( if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) && !(flags & GNTMAP_readonly) ) - clear_bit(_GTF_writing, &sha->flags); + clear_entry_flag(_GTF_writing, &sha->flags); if ( act->pin == 0 ) - clear_bit(_GTF_reading, &sha->flags); + clear_entry_flag(_GTF_reading, &sha->flags); unmap_out: op->status = rc; @@ -889,11 +889,11 @@ gnttab_release_mappings( } if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 ) - clear_bit(_GTF_writing, &sha->flags); + clear_entry_flag(_GTF_writing, &sha->flags); } if ( act->pin == 0 ) - clear_bit(_GTF_reading, &sha->flags); + clear_entry_flag(_GTF_reading, &sha->flags); spin_unlock(&rd->grant_table->lock); diff -r b3dfb02fc2c2 xen/include/asm-ia64/grant_table.h --- a/xen/include/asm-ia64/grant_table.h Thu Jun 22 10:58:41 2006 -0500 +++ b/xen/include/asm-ia64/grant_table.h Fri Jun 23 16:13:48 2006 -0500 @@ -55,4 +55,9 @@ void guest_physmap_add_page(struct domai #define gnttab_log_dirty(d, f) ((void)0) +static inline void clear_entry_flag(unsigned long nr, uint16_t *addr) +{ + clear_bit(nr, addr); +} + #endif /* __ASM_GRANT_TABLE_H__ */ diff -r b3dfb02fc2c2 xen/include/asm-x86/grant_table.h --- a/xen/include/asm-x86/grant_table.h Thu Jun 22 10:58:41 2006 -0500 +++ b/xen/include/asm-x86/grant_table.h Fri Jun 23 16:13:48 2006 -0500 @@ -33,4 +33,9 @@ int destroy_grant_host_mapping( #define gnttab_log_dirty(d, f) mark_dirty((d), (f)) +static inline void clear_entry_flag(unsigned long nr, uint16_t *addr) +{ + clear_bit(nr, addr); +} + #endif /* __ASM_GRANT_TABLE_H__ */ For reference, here's the Xen PPC hack: diff -r b3dfb02fc2c2 xen/include/asm-ppc/grant_table.h --- a/xen/include/asm-ppc/grant_table.h Thu Jun 22 10:58:41 2006 -0500 +++ b/xen/include/asm-ppc/grant_table.h Fri Jun 23 16:13:48 2006 -0500 @@ -26,4 +26,16 @@ #define mark_dirty(d, f) ((void )0) #include "../asm-x86/grant_table.h" +static inline void clear_entry_flag(unsigned long nr, uint16_t *addr) +{ + unsigned long *laddr; + unsigned long lnr; + + BUG_ON((ulong)addr % sizeof(ulong)); + + lnr = (BITS_PER_LONG - (sizeof(*addr) * 8)) + nr; + laddr = (unsigned long *)addr; + clear_bit(lnr, laddr); +} + #endif /* __ASM_PPC_GRANT_TABLE_H__ */ The Linux patch applies to the current sparse tree with slight offsets: diff -r 6f3d44537b76 drivers/xen/core/gnttab.c --- a/drivers/xen/core/gnttab.c Fri Jun 16 16:07:38 2006 -0500 +++ b/drivers/xen/core/gnttab.c Fri Jun 23 16:14:27 2006 -0500 @@ -201,7 +201,7 @@ gnttab_end_foreign_access_ref(grant_ref_ printk(KERN_ALERT "WARNING: g.e. still in use!\n"); return 0; } - } while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) != + } while ((nflags = gnttab_cmpxchg_flags(&shared[ref].flags, flags, 0)) != flags); return 1; @@ -256,7 +256,7 @@ gnttab_end_foreign_transfer_ref(grant_re * reference and return failure (== 0). */ while (!((flags = shared[ref].flags) & GTF_transfer_committed)) { - if (synch_cmpxchg(&shared[ref].flags, flags, 0) == flags) + if (gnttab_cmpxchg_flags(&shared[ref].flags, flags, 0) == flags) return 0; cpu_relax(); } diff -r 6f3d44537b76 include/asm-i386/mach-xen/asm/synch_bitops.h --- a/include/asm-i386/mach-xen/asm/synch_bitops.h Fri Jun 16 16:07:38 2006 -0500 +++ b/include/asm-i386/mach-xen/asm/synch_bitops.h Fri Jun 23 16:14:27 2006 -0500 @@ -138,4 +138,6 @@ static __inline__ int synch_var_test_bit synch_const_test_bit((nr),(addr)) : \ synch_var_test_bit((nr),(addr))) +#define gnttab_cmpxchg_flags synch_cmpxchg + #endif /* __XEN_SYNCH_BITOPS_H__ */ diff -r 6f3d44537b76 include/asm-ia64/synch_bitops.h --- a/include/asm-ia64/synch_bitops.h Fri Jun 16 16:07:38 2006 -0500 +++ b/include/asm-ia64/synch_bitops.h Fri Jun 23 16:14:27 2006 -0500 @@ -58,4 +58,6 @@ static __inline__ int synch_var_test_bit synch_const_test_bit((nr),(addr)) : \ synch_var_test_bit((nr),(addr))) +#define gnttab_cmpxchg_flags synch_cmpxchg + #endif /* __XEN_SYNCH_BITOPS_H__ */ For reference, the Linux PPC hack: diff -r 6f3d44537b76 include/asm-powerpc/xen/asm/synch_bitops.h --- a/include/asm-powerpc/xen/asm/synch_bitops.h Fri Jun 16 16:07:38 2006 -0500 +++ b/include/asm-powerpc/xen/asm/synch_bitops.h Fri Jun 23 16:14:27 2006 -0500 @@ -21,4 +21,28 @@ #error "this only works for CONFIG_SMP" #endif +/* HACK: grant_entry.flags is two bytes, but our atomic instructions + * only store in 4/8 byte quantities. However, because it's part of the guest + * ABI, we can't change its size without breaking backwards compatibility. In + * this particular case, struct grant_entry is big enough that we can safely + * store 4 bytes into it. However, some munging is needed... + */ +static inline __u16 gnttab_cmpxchg_flags(__u16 *ptr, __u16 o, __u16 n) +{ + volatile __u32 *laddr; + unsigned long shift = (sizeof(*laddr) - sizeof(*ptr)) * 8; + __u32 orig; + __u32 old; + __u32 new; + + BUG_ON((long)ptr % sizeof(*laddr)); + + laddr = (volatile __u32 *)ptr; + orig = *laddr; + old = ((unsigned long)o << shift) | (orig & ((1UL<<shift)-1)); + new = ((unsigned long)n << shift) | (orig & ((1UL<<shift)-1)); + + return synch_cmpxchg(laddr, old, new); +} + #endif /* __SYNCH_BITOPS_H__ */ -- Hollis Blanchard IBM Linux Technology Center _______________________________________________ Xen-ppc-devel mailing list Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ppc-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |