X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=fs%2Fxfs%2Fsupport%2Fktrace.c;h=a34ef05489b1c323369c7b22cf40400febaa28dd;hb=f0e2d93c29dc39ffd24cac180a19d48f700c0706;hp=addf5a7ea06c40f879d40d1e8117c15cf01e21c5;hpb=95d465fd750897ab32462a6702fbfe1b122cbbc0;p=deliverable%2Flinux.git diff --git a/fs/xfs/support/ktrace.c b/fs/xfs/support/ktrace.c index addf5a7ea06c..a34ef05489b1 100644 --- a/fs/xfs/support/ktrace.c +++ b/fs/xfs/support/ktrace.c @@ -21,10 +21,10 @@ static kmem_zone_t *ktrace_hdr_zone; static kmem_zone_t *ktrace_ent_zone; static int ktrace_zentries; -void +void __init ktrace_init(int zentries) { - ktrace_zentries = zentries; + ktrace_zentries = roundup_pow_of_two(zentries); ktrace_hdr_zone = kmem_zone_init(sizeof(ktrace_t), "ktrace_hdr"); @@ -36,7 +36,7 @@ ktrace_init(int zentries) ASSERT(ktrace_ent_zone); } -void +void __exit ktrace_uninit(void) { kmem_zone_destroy(ktrace_hdr_zone); @@ -47,13 +47,16 @@ ktrace_uninit(void) * ktrace_alloc() * * Allocate a ktrace header and enough buffering for the given - * number of entries. + * number of entries. Round the number of entries up to a + * power of 2 so we can do fast masking to get the index from + * the atomic index counter. */ ktrace_t * ktrace_alloc(int nentries, unsigned int __nocast sleep) { ktrace_t *ktp; ktrace_entry_t *ktep; + int entries; ktp = (ktrace_t*)kmem_zone_alloc(ktrace_hdr_zone, sleep); @@ -70,12 +73,13 @@ ktrace_alloc(int nentries, unsigned int __nocast sleep) /* * Special treatment for buffers with the ktrace_zentries entries */ - if (nentries == ktrace_zentries) { + entries = roundup_pow_of_two(nentries); + if (entries == ktrace_zentries) { ktep = (ktrace_entry_t*)kmem_zone_zalloc(ktrace_ent_zone, sleep); } else { - ktep = (ktrace_entry_t*)kmem_zalloc((nentries * sizeof(*ktep)), - sleep); + ktep = (ktrace_entry_t*)kmem_zalloc((entries * sizeof(*ktep)), + sleep | KM_LARGE); } if (ktep == NULL) { @@ -85,16 +89,16 @@ ktrace_alloc(int nentries, unsigned int __nocast sleep) if (sleep & KM_SLEEP) panic("ktrace_alloc: NULL memory on KM_SLEEP request!"); - kmem_free(ktp, sizeof(*ktp)); + kmem_free(ktp); return NULL; } - spinlock_init(&(ktp->kt_lock), "kt_lock"); - ktp->kt_entries = ktep; - ktp->kt_nentries = nentries; - ktp->kt_index = 0; + ktp->kt_nentries = entries; + ASSERT(is_power_of_2(entries)); + ktp->kt_index_mask = entries - 1; + atomic_set(&ktp->kt_index, 0); ktp->kt_rollover = 0; return ktp; } @@ -114,8 +118,6 @@ ktrace_free(ktrace_t *ktp) if (ktp == (ktrace_t *)NULL) return; - spinlock_destroy(&ktp->kt_lock); - /* * Special treatment for the Vnode trace buffer. */ @@ -124,7 +126,7 @@ ktrace_free(ktrace_t *ktp) } else { entries_size = (int)(ktp->kt_nentries * sizeof(ktrace_entry_t)); - kmem_free(ktp->kt_entries, entries_size); + kmem_free(ktp->kt_entries); } kmem_zone_free(ktrace_hdr_zone, ktp); @@ -155,8 +157,6 @@ ktrace_enter( void *val14, void *val15) { - static DEFINE_SPINLOCK(wrap_lock); - unsigned long flags; int index; ktrace_entry_t *ktep; @@ -165,12 +165,8 @@ ktrace_enter( /* * Grab an entry by pushing the index up to the next one. */ - spin_lock_irqsave(&wrap_lock, flags); - index = ktp->kt_index; - if (++ktp->kt_index == ktp->kt_nentries) - ktp->kt_index = 0; - spin_unlock_irqrestore(&wrap_lock, flags); - + index = atomic_add_return(1, &ktp->kt_index); + index = (index - 1) & ktp->kt_index_mask; if (!ktp->kt_rollover && index == ktp->kt_nentries - 1) ktp->kt_rollover = 1; @@ -203,11 +199,12 @@ int ktrace_nentries( ktrace_t *ktp) { - if (ktp == NULL) { + int index; + if (ktp == NULL) return 0; - } - return (ktp->kt_rollover ? ktp->kt_nentries : ktp->kt_index); + index = atomic_read(&ktp->kt_index) & ktp->kt_index_mask; + return (ktp->kt_rollover ? ktp->kt_nentries : index); } /* @@ -232,7 +229,7 @@ ktrace_first(ktrace_t *ktp, ktrace_snap_t *ktsp) int nentries; if (ktp->kt_rollover) - index = ktp->kt_index; + index = atomic_read(&ktp->kt_index) & ktp->kt_index_mask; else index = 0;