xref: /onnv-gate/usr/src/uts/common/io/ib/clients/rds/rdsib_debug.c (revision 6702:c62be08ca808)
13302Sagiri /*
23302Sagiri  * CDDL HEADER START
33302Sagiri  *
43302Sagiri  * The contents of this file are subject to the terms of the
53302Sagiri  * Common Development and Distribution License (the "License").
63302Sagiri  * You may not use this file except in compliance with the License.
73302Sagiri  *
83302Sagiri  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93302Sagiri  * or http://www.opensolaris.org/os/licensing.
103302Sagiri  * See the License for the specific language governing permissions
113302Sagiri  * and limitations under the License.
123302Sagiri  *
133302Sagiri  * When distributing Covered Code, include this CDDL HEADER in each
143302Sagiri  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153302Sagiri  * If applicable, add the following below this CDDL HEADER, with the
163302Sagiri  * fields enclosed by brackets "[]" replaced with your own identifying
173302Sagiri  * information: Portions Copyright [yyyy] [name of copyright owner]
183302Sagiri  *
193302Sagiri  * CDDL HEADER END
203302Sagiri  */
213302Sagiri /*
22*6702Sagiri  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
233302Sagiri  * Use is subject to license terms.
243302Sagiri  */
253302Sagiri 
263302Sagiri #pragma ident	"%Z%%M%	%I%	%E% SMI"
273302Sagiri 
283302Sagiri #include <sys/types.h>
293302Sagiri #include <sys/varargs.h>
303302Sagiri #include <sys/cmn_err.h>
313302Sagiri #include <sys/ddi.h>
323302Sagiri #include <sys/sunddi.h>
333302Sagiri #include <sys/ib/clients/rds/rdsib_debug.h>
343302Sagiri 
353302Sagiri /*
363302Sagiri  * This file contains the debug defines and routines.
373302Sagiri  * Debugging information is collected in a circular kernel buffer. Debug
383302Sagiri  * messages with level lower than rdsdbglvl are ignored. The size of the
393302Sagiri  * of the debug buffer can be changed by setting 'rds_debug_buf_size' in
403302Sagiri  * bytes in /etc/system.
413302Sagiri  *
423302Sagiri  * The debug buffer can be cleared by setting 'rds_clear_debug_buf_flag = 1'
433302Sagiri  * on a running system.
443302Sagiri  */
453302Sagiri 
463302Sagiri #define	RDS_DEBUG_SIZE_EXTRA_ALLOC	8
473302Sagiri #define	RDS_MIN_DEBUG_BUF_SIZE		0x1000
483302Sagiri #define	RDS_FUNCNAME_LEN		40
493302Sagiri #define	RDS_PRINTBUF_LEN		4096
503302Sagiri #ifdef	DEBUG
513302Sagiri #define	RDS_DEBUG_BUF_SIZE		0x10000
523302Sagiri #else
533302Sagiri #define	RDS_DEBUG_BUF_SIZE		0x2000
543302Sagiri #endif	/* DEBUG */
553302Sagiri 
563302Sagiri /* Max length of a debug statement */
573302Sagiri #define	RDS_PRINT_BUF_LEN	4096
583302Sagiri 
593302Sagiri int	rds_suppress_dprintf;		/* Suppress debug printing */
603302Sagiri int	rds_buffer_dprintf = 1;		/* Use debug buffer (0 == console) */
613302Sagiri int	rds_debug_buf_size = RDS_DEBUG_BUF_SIZE; /* Sz of Debug buf */
623302Sagiri int	rds_allow_intr_msgs = 0;	/* log "intr" messages */
633302Sagiri char	*rds_debug_buf = NULL;		/* The Debug Buf */
643302Sagiri char	*rds_buf_sptr, *rds_buf_eptr;	/* debug buffer temp pointer */
653302Sagiri int	rds_clear_debug_buf_flag = 0;	/* Clear debug buffer */
663302Sagiri extern uint_t	rdsdbglvl;
673302Sagiri 
683302Sagiri /*
693302Sagiri  * Print Buffer protected by mutex for debug stuff. The mutex also
703302Sagiri  * ensures serializing debug messages.
713302Sagiri  */
723302Sagiri static kmutex_t	rds_debug_mutex;
733302Sagiri static char	rds_print_buf[RDS_PRINT_BUF_LEN];
743302Sagiri 
753302Sagiri /* Function Prototypes */
763302Sagiri static void	rds_clear_print_buf();
773302Sagiri 
783302Sagiri /* RDS logging init */
793302Sagiri void
rds_logging_initialization()803302Sagiri rds_logging_initialization()
813302Sagiri {
823302Sagiri 	boolean_t flag = B_FALSE;
833302Sagiri 
843302Sagiri 	mutex_init(&rds_debug_mutex, NULL, MUTEX_DRIVER, NULL);
853302Sagiri 	mutex_enter(&rds_debug_mutex);
863302Sagiri 
873302Sagiri 	if (rds_debug_buf_size <= RDS_DEBUG_SIZE_EXTRA_ALLOC) {
883302Sagiri 		rds_debug_buf_size = RDS_MIN_DEBUG_BUF_SIZE;
893302Sagiri 		flag = B_TRUE;
903302Sagiri 	}
913302Sagiri 
923302Sagiri 	/* if it is less that RDS_MIN_DEBUG_BUF_SIZE, adjust it */
933302Sagiri 	rds_debug_buf_size = max(RDS_MIN_DEBUG_BUF_SIZE,
943302Sagiri 	    rds_debug_buf_size);
953302Sagiri 
963302Sagiri 	rds_debug_buf = (char *)kmem_alloc(rds_debug_buf_size, KM_SLEEP);
973302Sagiri 	rds_clear_print_buf();
983302Sagiri 	mutex_exit(&rds_debug_mutex);
993302Sagiri 
1003302Sagiri 	if (flag == B_TRUE) {
1013302Sagiri 		RDS_DPRINTF2("RDS", "rds_debug_buf_size was too small, "
1023302Sagiri 		    "adjusted to %x", rds_debug_buf_size);
1033302Sagiri 	}
1043302Sagiri }
1053302Sagiri 
1063302Sagiri 
1073302Sagiri /* RDS logging destroy */
1083302Sagiri void
rds_logging_destroy()1093302Sagiri rds_logging_destroy()
1103302Sagiri {
1113302Sagiri 	mutex_enter(&rds_debug_mutex);
1123302Sagiri 	if (rds_debug_buf) {
1133302Sagiri 		kmem_free(rds_debug_buf, rds_debug_buf_size);
1143302Sagiri 		rds_debug_buf = NULL;
1153302Sagiri 	}
1163302Sagiri 	mutex_exit(&rds_debug_mutex);
1173302Sagiri 	mutex_destroy(&rds_debug_mutex);
1183302Sagiri }
1193302Sagiri 
1203302Sagiri 
1213302Sagiri /*
1223302Sagiri  * debug, log, and console message handling
1233302Sagiri  */
1243302Sagiri 
1253302Sagiri /*
1263302Sagiri  * clear the RDS debug buffer
1273302Sagiri  */
1283302Sagiri static void
rds_clear_print_buf()1293302Sagiri rds_clear_print_buf()
1303302Sagiri {
1313302Sagiri 	ASSERT(MUTEX_HELD(&rds_debug_mutex));
1323302Sagiri 	if (rds_debug_buf) {
1333302Sagiri 		rds_buf_sptr = rds_debug_buf;
1343302Sagiri 		rds_buf_eptr = rds_debug_buf + rds_debug_buf_size -
1353302Sagiri 		    RDS_DEBUG_SIZE_EXTRA_ALLOC;
1363302Sagiri 
1373302Sagiri 		bzero(rds_debug_buf, rds_debug_buf_size);
1383302Sagiri 	}
1393302Sagiri }
1403302Sagiri 
1413302Sagiri 
1423302Sagiri static void
rds_vlog(char * name,uint_t level,char * fmt,va_list ap)1433302Sagiri rds_vlog(char *name, uint_t level, char *fmt, va_list ap)
1443302Sagiri {
1453302Sagiri 	char	*label = (name == NULL) ? "rds" : name;
1463302Sagiri 	char	*msg_ptr;
1473302Sagiri 	size_t	len;
1483302Sagiri 
1493302Sagiri 	mutex_enter(&rds_debug_mutex);
1503302Sagiri 
1513302Sagiri 	/* if not using logging scheme; quit */
1523302Sagiri 	if (rds_suppress_dprintf || (rds_debug_buf == NULL)) {
1533302Sagiri 		mutex_exit(&rds_debug_mutex);
1543302Sagiri 		return;
1553302Sagiri 	}
1563302Sagiri 
1573302Sagiri 	/* If user requests to clear debug buffer, go ahead */
1583302Sagiri 	if (rds_clear_debug_buf_flag != 0) {
1593302Sagiri 		rds_clear_print_buf();
1603302Sagiri 		rds_clear_debug_buf_flag = 0;
1613302Sagiri 	}
1623302Sagiri 
1633302Sagiri 	/*
1643302Sagiri 	 * put "label" into the buffer
1653302Sagiri 	 */
1663302Sagiri 	len = snprintf(rds_print_buf, RDS_FUNCNAME_LEN, "%s:\t", label);
1673302Sagiri 
1683302Sagiri 	msg_ptr = rds_print_buf + len;
1693302Sagiri 	len += vsnprintf(msg_ptr, RDS_PRINT_BUF_LEN - len - 2, fmt, ap);
1703302Sagiri 
1713302Sagiri 	len = min(len, RDS_PRINT_BUF_LEN - 2);
1723302Sagiri 	ASSERT(len == strlen(rds_print_buf));
1733302Sagiri 	rds_print_buf[len++] = '\n';
1743302Sagiri 	rds_print_buf[len] = '\0';
1753302Sagiri 
1763302Sagiri 	/*
1773302Sagiri 	 * stuff the message in the debug buf
1783302Sagiri 	 */
1793302Sagiri 	if (rds_buffer_dprintf) {
1803302Sagiri 
1813302Sagiri 		/*
1823302Sagiri 		 * overwrite >>>> that might be over the end of the
1833302Sagiri 		 * the buffer
1843302Sagiri 		 */
1853302Sagiri 		*rds_buf_sptr = '\0';
1863302Sagiri 
1873302Sagiri 		if (rds_buf_sptr + len > rds_buf_eptr) {
1883302Sagiri 			size_t left = (uintptr_t)rds_buf_eptr -
1893302Sagiri 			    (uintptr_t)rds_buf_sptr;
1903302Sagiri 
1913302Sagiri 			bcopy((caddr_t)rds_print_buf,
192*6702Sagiri 			    (caddr_t)rds_buf_sptr, left);
1933302Sagiri 			bcopy((caddr_t)rds_print_buf + left,
194*6702Sagiri 			    (caddr_t)rds_debug_buf, len - left);
1953302Sagiri 			rds_buf_sptr = rds_debug_buf + len - left;
1963302Sagiri 		} else {
1973302Sagiri 			bcopy((caddr_t)rds_print_buf, rds_buf_sptr, len);
1983302Sagiri 			rds_buf_sptr += len;
1993302Sagiri 		}
2003302Sagiri 
2013302Sagiri 		/* add marker */
2023302Sagiri 		(void) sprintf(rds_buf_sptr, ">>>>");
2033302Sagiri 	}
2043302Sagiri 
2053302Sagiri 	/*
2063302Sagiri 	 * LINTR, L5-L2 message may go to the rds_debug_buf
207*6702Sagiri 	 * L1 messages will go to the /var/adm/messages (debug & non-debug).
208*6702Sagiri 	 * L0 messages will go to console (debug & non-debug).
2093302Sagiri 	 */
2103302Sagiri 	switch (level) {
2113302Sagiri 	case RDS_LOG_LINTR:
2123302Sagiri 	case RDS_LOG_L5:
2133302Sagiri 	case RDS_LOG_L4:
2143302Sagiri 	case RDS_LOG_L3:
2153302Sagiri 	case RDS_LOG_L2:
2163302Sagiri 		if (!rds_buffer_dprintf) {
2173302Sagiri 			cmn_err(CE_CONT, "^%s", rds_print_buf);
2183302Sagiri 		}
2193302Sagiri 		break;
2203302Sagiri 	case RDS_LOG_L1:
2213302Sagiri 		if (!rds_buffer_dprintf) {
2223302Sagiri 			cmn_err(CE_CONT, "^%s", rds_print_buf);
223*6702Sagiri 		} else {
224*6702Sagiri 			/* go to messages file */
225*6702Sagiri 			cmn_err(CE_CONT, "!%s", rds_print_buf);
2263302Sagiri 		}
2273302Sagiri 		break;
2283302Sagiri 	case RDS_LOG_L0:
2293302Sagiri 		/* Strip the "\n" added earlier */
2303302Sagiri 		if (rds_print_buf[len - 1] == '\n') {
2313302Sagiri 			rds_print_buf[len - 1] = '\0';
2323302Sagiri 		}
2333302Sagiri 		if (msg_ptr[len - 1] == '\n') {
2343302Sagiri 			msg_ptr[len - 1] = '\0';
2353302Sagiri 		}
236*6702Sagiri 		/* go to console */
237*6702Sagiri 		cmn_err(CE_CONT, "^%s", rds_print_buf);
2383302Sagiri 		break;
2393302Sagiri 	}
2403302Sagiri 
2413302Sagiri 	mutex_exit(&rds_debug_mutex);
2423302Sagiri }
2433302Sagiri 
2443302Sagiri void
rds_dprintf_intr(char * name,char * fmt,...)2453302Sagiri rds_dprintf_intr(char *name, char *fmt, ...)
2463302Sagiri {
2473302Sagiri 	va_list ap;
2483302Sagiri 
2493302Sagiri 	va_start(ap, fmt);
2503302Sagiri 	rds_vlog(name, RDS_LOG_LINTR, fmt, ap);
2513302Sagiri 	va_end(ap);
2523302Sagiri }
2533302Sagiri 
2543302Sagiri /*
2553302Sagiri  * Check individual subsystem err levels
2563302Sagiri  */
2573302Sagiri #define	RDS_CHECK_ERR_LEVEL(level)		\
2583302Sagiri 	if (rdsdbglvl < level)			\
2593302Sagiri 		return;				\
2603302Sagiri 
2613302Sagiri void
rds_dprintf5(char * name,char * fmt,...)2623302Sagiri rds_dprintf5(char *name, char *fmt, ...)
2633302Sagiri {
2643302Sagiri 	va_list ap;
2653302Sagiri 
2663302Sagiri 	RDS_CHECK_ERR_LEVEL(RDS_LOG_L5);
2673302Sagiri 
2683302Sagiri 	va_start(ap, fmt);
2693302Sagiri 	rds_vlog(name, RDS_LOG_L5, fmt, ap);
2703302Sagiri 	va_end(ap);
2713302Sagiri }
2723302Sagiri 
2733302Sagiri void
rds_dprintf4(char * name,char * fmt,...)2743302Sagiri rds_dprintf4(char *name, char *fmt, ...)
2753302Sagiri {
2763302Sagiri 	va_list ap;
2773302Sagiri 
2783302Sagiri 	RDS_CHECK_ERR_LEVEL(RDS_LOG_L4);
2793302Sagiri 
2803302Sagiri 	va_start(ap, fmt);
2813302Sagiri 	rds_vlog(name, RDS_LOG_L4, fmt, ap);
2823302Sagiri 	va_end(ap);
2833302Sagiri }
2843302Sagiri 
2853302Sagiri void
rds_dprintf3(char * name,char * fmt,...)2863302Sagiri rds_dprintf3(char *name, char *fmt, ...)
2873302Sagiri {
2883302Sagiri 	va_list ap;
2893302Sagiri 
2903302Sagiri 	RDS_CHECK_ERR_LEVEL(RDS_LOG_L3);
2913302Sagiri 
2923302Sagiri 	va_start(ap, fmt);
2933302Sagiri 	rds_vlog(name, RDS_LOG_L3, fmt, ap);
2943302Sagiri 	va_end(ap);
2953302Sagiri }
2963302Sagiri 
2973302Sagiri void
rds_dprintf2(char * name,char * fmt,...)2983302Sagiri rds_dprintf2(char *name, char *fmt, ...)
2993302Sagiri {
3003302Sagiri 	va_list ap;
3013302Sagiri 
3023302Sagiri 	RDS_CHECK_ERR_LEVEL(RDS_LOG_L2);
3033302Sagiri 
3043302Sagiri 	va_start(ap, fmt);
3053302Sagiri 	rds_vlog(name, RDS_LOG_L2, fmt, ap);
3063302Sagiri 	va_end(ap);
3073302Sagiri }
3083302Sagiri 
3093302Sagiri void
rds_dprintf1(char * name,char * fmt,...)3103302Sagiri rds_dprintf1(char *name, char *fmt, ...)
3113302Sagiri {
3123302Sagiri 	va_list ap;
3133302Sagiri 
3143302Sagiri 	va_start(ap, fmt);
3153302Sagiri 	rds_vlog(name, RDS_LOG_L1, fmt, ap);
3163302Sagiri 	va_end(ap);
3173302Sagiri }
3183302Sagiri 
3193302Sagiri 
3203302Sagiri /*
3213302Sagiri  * Function:
3223302Sagiri  *      rds_dprintf0
3233302Sagiri  * Input:
3243302Sagiri  *      name	- Name of the function generating the debug message
3253302Sagiri  *  	fmt	- The message to be displayed.
3263302Sagiri  * Output:
3273302Sagiri  *      none
3283302Sagiri  * Returns:
3293302Sagiri  *      none
3303302Sagiri  * Description:
3313302Sagiri  *  	A generic log function to display RDS debug messages.
3323302Sagiri  */
3333302Sagiri void
rds_dprintf0(char * name,char * fmt,...)3343302Sagiri rds_dprintf0(char *name, char *fmt, ...)
3353302Sagiri {
3363302Sagiri 	va_list ap;
3373302Sagiri 
3383302Sagiri 	va_start(ap, fmt);
3393302Sagiri 	rds_vlog(name, RDS_LOG_L0, fmt, ap);
3403302Sagiri 	va_end(ap);
3413302Sagiri }
342