xref: /illumos-gate/usr/src/uts/common/sys/strft.h (revision a45f3f93)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*a45f3f93Smeem  * Common Development and Distribution License (the "License").
6*a45f3f93Smeem  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*a45f3f93Smeem  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef _SYS_STRFT_H
277c478bd9Sstevel@tonic-gate #define	_SYS_STRFT_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
307c478bd9Sstevel@tonic-gate extern "C" {
317c478bd9Sstevel@tonic-gate #endif
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate /*
347c478bd9Sstevel@tonic-gate  * The flow trace subsystem is used to trace the flow of STREAMS messages
357c478bd9Sstevel@tonic-gate  * through a stream.
367c478bd9Sstevel@tonic-gate  *
377c478bd9Sstevel@tonic-gate  * WARNING: this is a private subsystem and subject to change at any time!
387c478bd9Sstevel@tonic-gate  */
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate #include <sys/time.h>
417c478bd9Sstevel@tonic-gate #include <sys/types.h>
427c478bd9Sstevel@tonic-gate #include <sys/stream.h>
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate /*
457c478bd9Sstevel@tonic-gate  * Some evnt defines, values 0..N are reserved for internal use,
467c478bd9Sstevel@tonic-gate  * (N+1)..0x1FFF are available for arbitrary module/drvier use,
477c478bd9Sstevel@tonic-gate  * 0x8000 (RD/WR q marker) and 0x4000 (thread cs marker) are or'ed
487c478bd9Sstevel@tonic-gate  * flag bits reserved for internal use.
497c478bd9Sstevel@tonic-gate  */
507c478bd9Sstevel@tonic-gate #define	FTEV_MASK	0x1FFF
517c478bd9Sstevel@tonic-gate #define	FTEV_ISWR	0x8000
527c478bd9Sstevel@tonic-gate #define	FTEV_CS		0x4000
537c478bd9Sstevel@tonic-gate #define	FTEV_PS		0x2000
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate #define	FTEV_QMASK	0x1F00
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate #define	FTEV_ALLOCMASK	0x1FF8
587c478bd9Sstevel@tonic-gate #define	FTEV_ALLOCB	0x0000
597c478bd9Sstevel@tonic-gate #define	FTEV_ESBALLOC	0x0001
607c478bd9Sstevel@tonic-gate #define	FTEV_DESBALLOC	0x0002
617c478bd9Sstevel@tonic-gate #define	FTEV_ESBALLOCA	0x0003
627c478bd9Sstevel@tonic-gate #define	FTEV_DESBALLOCA	0x0004
637c478bd9Sstevel@tonic-gate #define	FTEV_ALLOCBIG	0x0005
647c478bd9Sstevel@tonic-gate #define	FTEV_ALLOCBW	0x0006
657c478bd9Sstevel@tonic-gate #define	FTEV_BCALLOCB	0x0007
667c478bd9Sstevel@tonic-gate #define	FTEV_FREEB	0x0008
677c478bd9Sstevel@tonic-gate #define	FTEV_DUPB	0x0009
687c478bd9Sstevel@tonic-gate #define	FTEV_COPYB	0x000A
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate #define	FTEV_CALLER	0x000F
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate #define	FTEV_PUT	0x0100
737c478bd9Sstevel@tonic-gate #define	FTEV_PUTQ	0x0105
747c478bd9Sstevel@tonic-gate #define	FTEV_GETQ	0x0106
757c478bd9Sstevel@tonic-gate #define	FTEV_RMVQ	0x0107
767c478bd9Sstevel@tonic-gate #define	FTEV_INSQ	0x0108
777c478bd9Sstevel@tonic-gate #define	FTEV_PUTBQ	0x0109
787c478bd9Sstevel@tonic-gate #define	FTEV_FLUSHQ	0x010A
797c478bd9Sstevel@tonic-gate #define	FTEV_PUTNEXT	0x010D
807c478bd9Sstevel@tonic-gate #define	FTEV_RWNEXT	0x010E
817c478bd9Sstevel@tonic-gate 
82*a45f3f93Smeem #define	FTBLK_EVNTS	9
83*a45f3f93Smeem #define	FTSTK_DEPTH	15
84*a45f3f93Smeem 
85*a45f3f93Smeem /*
86*a45f3f93Smeem  * Stack information for each flow trace event; recorded when str_ftstack
87*a45f3f93Smeem  * is non-zero.
88*a45f3f93Smeem  */
89*a45f3f93Smeem typedef struct ftstk {
90*a45f3f93Smeem 	uint_t		fs_depth;
91*a45f3f93Smeem 	pc_t		fs_stk[FTSTK_DEPTH];
92*a45f3f93Smeem } ftstk_t;
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate /*
95*a45f3f93Smeem  * Data structure that contains the timestamp, module/driver name, next
96*a45f3f93Smeem  * module/driver name, optional callstack, event and event data (not certain
97*a45f3f93Smeem  * as to its use yet: RSF).  There is one per event.  Every time str_ftevent()
98*a45f3f93Smeem  * is called, one of the indices is filled in with this data.
997c478bd9Sstevel@tonic-gate  */
1007c478bd9Sstevel@tonic-gate typedef struct ftevnt {
101*a45f3f93Smeem 	hrtime_t	ts;		/* event timestamp, per gethrtime() */
102*a45f3f93Smeem 	char 		*mid;		/* module/driver name */
103*a45f3f93Smeem 	char		*midnext; 	/* next module/driver name */
104*a45f3f93Smeem 	ushort_t 	evnt;		/* FTEV_* value above */
105*a45f3f93Smeem 	ushort_t 	data;		/* event data */
106*a45f3f93Smeem 	ftstk_t		*stk;		/* optional event callstack */
1077c478bd9Sstevel@tonic-gate } ftevnt_t;
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate /*
110*a45f3f93Smeem  * A linked list of ftevnt arrays.
1117c478bd9Sstevel@tonic-gate  */
1127c478bd9Sstevel@tonic-gate typedef struct ftblk {
1137c478bd9Sstevel@tonic-gate 	struct ftblk *nxt;	/* next ftblk (or NULL if none) */
1147c478bd9Sstevel@tonic-gate 	int ix;			/* index of next free ev[] */
1157c478bd9Sstevel@tonic-gate 	struct ftevnt ev[FTBLK_EVNTS];
1167c478bd9Sstevel@tonic-gate } ftblk_t;
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate /*
1197c478bd9Sstevel@tonic-gate  * The flow trace header (start of event list).  It consists of the
1207c478bd9Sstevel@tonic-gate  *      current writable block (tail)
1217c478bd9Sstevel@tonic-gate  *      a hash value (for recovering trace information)
1227c478bd9Sstevel@tonic-gate  *      The last thread to process an event
1237c478bd9Sstevel@tonic-gate  *      The last cpu to process an event
1247c478bd9Sstevel@tonic-gate  *      The start of the list
1257c478bd9Sstevel@tonic-gate  * This structure is attached to a dblk, and traces a message through
1267c478bd9Sstevel@tonic-gate  * a flow.
1277c478bd9Sstevel@tonic-gate  */
1287c478bd9Sstevel@tonic-gate typedef struct fthdr {
1297c478bd9Sstevel@tonic-gate 	struct ftblk *tail;
1307c478bd9Sstevel@tonic-gate 	uint_t hash;		/* accumulated hash value (sum of mid's) */
1317c478bd9Sstevel@tonic-gate 	void *thread;
1327c478bd9Sstevel@tonic-gate 	int cpu_seqid;
1337c478bd9Sstevel@tonic-gate 	struct ftblk first;
1347c478bd9Sstevel@tonic-gate } fthdr_t;
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate #ifdef _KERNEL
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate struct datab;
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate extern void str_ftevent(fthdr_t *, void *, ushort_t, ushort_t);
1417c478bd9Sstevel@tonic-gate extern void str_ftfree(struct datab *);
142*a45f3f93Smeem extern int str_ftnever, str_ftstack;
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate /*
1457c478bd9Sstevel@tonic-gate  * Allocate flow-trace information and record an allocation event.
1467c478bd9Sstevel@tonic-gate  */
1477c478bd9Sstevel@tonic-gate #define	STR_FTALLOC(hpp, e, d) {					\
1487c478bd9Sstevel@tonic-gate 	if (str_ftnever == 0) {						\
1497c478bd9Sstevel@tonic-gate 		fthdr_t *_hp = *(hpp);					\
1507c478bd9Sstevel@tonic-gate 									\
1517c478bd9Sstevel@tonic-gate 		ASSERT(_hp == NULL);					\
1527c478bd9Sstevel@tonic-gate 		_hp = kmem_cache_alloc(fthdr_cache, KM_NOSLEEP);	\
1537c478bd9Sstevel@tonic-gate 		if ((*hpp = _hp) != NULL) {				\
1547c478bd9Sstevel@tonic-gate 			_hp->tail = &_hp->first;			\
1557c478bd9Sstevel@tonic-gate 			_hp->hash = 0;					\
1567c478bd9Sstevel@tonic-gate 			_hp->thread = curthread;			\
1577c478bd9Sstevel@tonic-gate 			_hp->cpu_seqid = CPU->cpu_seqid;		\
1587c478bd9Sstevel@tonic-gate 			_hp->first.nxt = NULL;				\
1597c478bd9Sstevel@tonic-gate 			_hp->first.ix = 0;				\
1607c478bd9Sstevel@tonic-gate 			str_ftevent(_hp, caller(), (e), (d));		\
1617c478bd9Sstevel@tonic-gate 		}							\
1627c478bd9Sstevel@tonic-gate 	}								\
1637c478bd9Sstevel@tonic-gate }
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate /*
1667c478bd9Sstevel@tonic-gate  * Add a flow-trace event to the passed-in mblk_t and any other mblk_t's
1677c478bd9Sstevel@tonic-gate  * chained off of b_cont.
1687c478bd9Sstevel@tonic-gate  */
1697c478bd9Sstevel@tonic-gate #define	STR_FTEVENT_MSG(mp, p, e, d) {					\
1707c478bd9Sstevel@tonic-gate 	if (str_ftnever == 0) {						\
1717c478bd9Sstevel@tonic-gate 		mblk_t *_mp;						\
1727c478bd9Sstevel@tonic-gate 		fthdr_t *_hp;						\
1737c478bd9Sstevel@tonic-gate 									\
1747c478bd9Sstevel@tonic-gate 		for (_mp = (mp); _mp != NULL; _mp = _mp->b_cont) {	\
1757c478bd9Sstevel@tonic-gate 			if ((_hp = DB_FTHDR(_mp)) != NULL)		\
1767c478bd9Sstevel@tonic-gate 				str_ftevent(_hp, (p), (e), (d));	\
1777c478bd9Sstevel@tonic-gate 		}							\
1787c478bd9Sstevel@tonic-gate 	}								\
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate /*
1827c478bd9Sstevel@tonic-gate  * Add a flow-trace event to *just* the passed-in mblk_t.
1837c478bd9Sstevel@tonic-gate  */
1847c478bd9Sstevel@tonic-gate #define	STR_FTEVENT_MBLK(mp, p, e, d) {					\
1857c478bd9Sstevel@tonic-gate 	if (str_ftnever == 0) {						\
1867c478bd9Sstevel@tonic-gate 		fthdr_t *_hp;						\
1877c478bd9Sstevel@tonic-gate 									\
1887c478bd9Sstevel@tonic-gate 		if ((mp) != NULL && ((_hp = DB_FTHDR(mp)) != NULL)) 	\
1897c478bd9Sstevel@tonic-gate 			str_ftevent(_hp, (p), (e), (d));		\
1907c478bd9Sstevel@tonic-gate 	}								\
1917c478bd9Sstevel@tonic-gate }
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
1967c478bd9Sstevel@tonic-gate }
1977c478bd9Sstevel@tonic-gate #endif
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate #endif	/* _SYS_STRFT_H */
200