⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ktrace.c

📁 linux-2.6.15.6
💻 C
字号:
/* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */#include <xfs.h>static kmem_zone_t *ktrace_hdr_zone;static kmem_zone_t *ktrace_ent_zone;static int          ktrace_zentries;voidktrace_init(int zentries){	ktrace_zentries = zentries;	ktrace_hdr_zone = kmem_zone_init(sizeof(ktrace_t),					"ktrace_hdr");	ASSERT(ktrace_hdr_zone);	ktrace_ent_zone = kmem_zone_init(ktrace_zentries					* sizeof(ktrace_entry_t),					"ktrace_ent");	ASSERT(ktrace_ent_zone);}voidktrace_uninit(void){	kmem_cache_destroy(ktrace_hdr_zone);	kmem_cache_destroy(ktrace_ent_zone);}/* * ktrace_alloc() * * Allocate a ktrace header and enough buffering for the given * number of entries. */ktrace_t *ktrace_alloc(int nentries, unsigned int __nocast sleep){	ktrace_t        *ktp;	ktrace_entry_t  *ktep;	ktp = (ktrace_t*)kmem_zone_alloc(ktrace_hdr_zone, sleep);	if (ktp == (ktrace_t*)NULL) {		/*		 * KM_SLEEP callers don't expect failure.		 */		if (sleep & KM_SLEEP)			panic("ktrace_alloc: NULL memory on KM_SLEEP request!");		return NULL;	}	/*	 * Special treatment for buffers with the ktrace_zentries entries	 */	if (nentries == ktrace_zentries) {		ktep = (ktrace_entry_t*)kmem_zone_zalloc(ktrace_ent_zone,							    sleep);	} else {		ktep = (ktrace_entry_t*)kmem_zalloc((nentries * sizeof(*ktep)),							    sleep);	}	if (ktep == NULL) {		/*		 * KM_SLEEP callers don't expect failure.		 */		if (sleep & KM_SLEEP)			panic("ktrace_alloc: NULL memory on KM_SLEEP request!");		kmem_free(ktp, sizeof(*ktp));		return NULL;	}	spinlock_init(&(ktp->kt_lock), "kt_lock");	ktp->kt_entries  = ktep;	ktp->kt_nentries = nentries;	ktp->kt_index    = 0;	ktp->kt_rollover = 0;	return ktp;}/* * ktrace_free() * * Free up the ktrace header and buffer.  It is up to the caller * to ensure that no-one is referencing it. */voidktrace_free(ktrace_t *ktp){	int     entries_size;	if (ktp == (ktrace_t *)NULL)		return;	spinlock_destroy(&ktp->kt_lock);	/*	 * Special treatment for the Vnode trace buffer.	 */	if (ktp->kt_nentries == ktrace_zentries) {		kmem_zone_free(ktrace_ent_zone, ktp->kt_entries);	} else {		entries_size = (int)(ktp->kt_nentries * sizeof(ktrace_entry_t));		kmem_free(ktp->kt_entries, entries_size);	}	kmem_zone_free(ktrace_hdr_zone, ktp);}/* * Enter the given values into the "next" entry in the trace buffer. * kt_index is always the index of the next entry to be filled. */voidktrace_enter(	ktrace_t        *ktp,	void            *val0,	void            *val1,	void            *val2,	void            *val3,	void            *val4,	void            *val5,	void            *val6,	void            *val7,	void            *val8,	void            *val9,	void            *val10,	void            *val11,	void            *val12,	void            *val13,	void            *val14,	void            *val15){	static DEFINE_SPINLOCK(wrap_lock);	unsigned long	flags;	int             index;	ktrace_entry_t  *ktep;	ASSERT(ktp != NULL);	/*	 * 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);	if (!ktp->kt_rollover && index == ktp->kt_nentries - 1)		ktp->kt_rollover = 1;	ASSERT((index >= 0) && (index < ktp->kt_nentries));	ktep = &(ktp->kt_entries[index]);	ktep->val[0]  = val0;	ktep->val[1]  = val1;	ktep->val[2]  = val2;	ktep->val[3]  = val3;	ktep->val[4]  = val4;	ktep->val[5]  = val5;	ktep->val[6]  = val6;	ktep->val[7]  = val7;	ktep->val[8]  = val8;	ktep->val[9]  = val9;	ktep->val[10] = val10;	ktep->val[11] = val11;	ktep->val[12] = val12;	ktep->val[13] = val13;	ktep->val[14] = val14;	ktep->val[15] = val15;}/* * Return the number of entries in the trace buffer. */intktrace_nentries(	ktrace_t        *ktp){	if (ktp == NULL) {		return 0;	}	return (ktp->kt_rollover ? ktp->kt_nentries : ktp->kt_index);}/* * ktrace_first() * * This is used to find the start of the trace buffer. * In conjunction with ktrace_next() it can be used to * iterate through the entire trace buffer.  This code does * not do any locking because it is assumed that it is called * from the debugger. * * The caller must pass in a pointer to a ktrace_snap * structure in which we will keep some state used to * iterate through the buffer.  This state must not touched * by any code outside of this module. */ktrace_entry_t *ktrace_first(ktrace_t   *ktp, ktrace_snap_t     *ktsp){	ktrace_entry_t  *ktep;	int             index;	int             nentries;	if (ktp->kt_rollover)		index = ktp->kt_index;	else		index = 0;	ktsp->ks_start = index;	ktep = &(ktp->kt_entries[index]);	nentries = ktrace_nentries(ktp);	index++;	if (index < nentries) {		ktsp->ks_index = index;	} else {		ktsp->ks_index = 0;		if (index > nentries)			ktep = NULL;	}	return ktep;}/* * ktrace_next() * * This is used to iterate through the entries of the given * trace buffer.  The caller must pass in the ktrace_snap_t * structure initialized by ktrace_first().  The return value * will be either a pointer to the next ktrace_entry or NULL * if all of the entries have been traversed. */ktrace_entry_t *ktrace_next(	ktrace_t        *ktp,	ktrace_snap_t   *ktsp){	int             index;	ktrace_entry_t  *ktep;	index = ktsp->ks_index;	if (index == ktsp->ks_start) {		ktep = NULL;	} else {		ktep = &ktp->kt_entries[index];	}	index++;	if (index == ktrace_nentries(ktp)) {		ktsp->ks_index = 0;	} else {		ktsp->ks_index = index;	}	return ktep;}/* * ktrace_skip() * * Skip the next "count" entries and return the entry after that. * Return NULL if this causes us to iterate past the beginning again. */ktrace_entry_t *ktrace_skip(	ktrace_t        *ktp,	int             count,	ktrace_snap_t   *ktsp){	int             index;	int             new_index;	ktrace_entry_t  *ktep;	int             nentries = ktrace_nentries(ktp);	index = ktsp->ks_index;	new_index = index + count;	while (new_index >= nentries) {		new_index -= nentries;	}	if (index == ktsp->ks_start) {		/*		 * We've iterated around to the start, so we're done.		 */		ktep = NULL;	} else if ((new_index < index) && (index < ktsp->ks_index)) {		/*		 * We've skipped past the start again, so we're done.		 */		ktep = NULL;		ktsp->ks_index = ktsp->ks_start;	} else {		ktep = &(ktp->kt_entries[new_index]);		new_index++;		if (new_index == nentries) {			ktsp->ks_index = 0;		} else {			ktsp->ks_index = new_index;		}	}	return ktep;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -