c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * CDDL HEADER START
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * The contents of this file are subject to the terms of the
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Common Development and Distribution License (the "License").
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * You may not use this file except in compliance with the License.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * or http://www.opensolaris.org/os/licensing.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * See the License for the specific language governing permissions
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * and limitations under the License.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * When distributing Covered Code, include this CDDL HEADER in each
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * If applicable, add the following below this CDDL HEADER, with the
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * fields enclosed by brackets "[]" replaced with your own identifying
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * information: Portions Copyright [yyyy] [name of copyright owner]
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * CDDL HEADER END
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/types.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/varargs.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/cmn_err.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/ddi.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/sunddi.h>
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#include <sys/time.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/ib/clients/rdsv3/rdsv3_debug.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * This file contains the debug defines and routines.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Debugging information is collected in a circular kernel buffer. Debug
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * messages with level lower than rdsv3dbglvl are ignored. The size of the
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * of the debug buffer can be changed by setting 'rdsv3_debug_buf_size' in
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * bytes in /etc/system.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * The debug buffer can be cleared by setting 'rdsv3_clear_debug_buf_flag = 1'
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * on a running system.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_DEBUG_SIZE_EXTRA_ALLOC 8
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_MIN_DEBUG_BUF_SIZE 0x1000
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_FUNCNAME_LEN 40
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_PRINTBUF_LEN 4096
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#ifdef DEBUG
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_DEBUG_BUF_SIZE 0x200000 /* 2M size */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#else
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_DEBUG_BUF_SIZE 0x2000
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#endif /* DEBUG */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* Max length of a debug statement */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_PRINT_BUF_LEN 4096
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic int rdsv3_suppress_dprintf; /* Suppress debug printing */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic int rdsv3_buffer_dprintf = 1; /* Use debug buffer (0 == console) */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic int rdsv3_debug_buf_size = RDSV3_DEBUG_BUF_SIZE; /* Sz of Debug buf */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic int rdsv3_allow_intr_msgs = 0; /* log "intr" messages */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otachar *rdsv3_debug_buf = NULL; /* The Debug Buf */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otachar *rdsv3_buf_sptr, *rdsv3_buf_eptr; /* debug buffer temp pointer */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaint rdsv3_clear_debug_buf_flag = 0; /* Clear debug buffer */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otauint_t rdsv3dbglvl = RDSV3_LOG_L4;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Print Buffer protected by mutex for debug stuff. The mutex also
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * ensures serializing debug messages.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic kmutex_t rdsv3_debug_mutex;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic char rdsv3_print_buf[RDSV3_PRINT_BUF_LEN];
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* Function Prototypes */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic void rdsv3_clear_print_buf();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* RDS logging init */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_logging_initialization()
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota boolean_t flag = B_FALSE;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_init(&rdsv3_debug_mutex, NULL, MUTEX_DRIVER, NULL);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_enter(&rdsv3_debug_mutex);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3_debug_buf_size <= RDSV3_DEBUG_SIZE_EXTRA_ALLOC) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_debug_buf_size = RDSV3_MIN_DEBUG_BUF_SIZE;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota flag = B_TRUE;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* if it is less that RDSV3_MIN_DEBUG_BUF_SIZE, adjust it */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_debug_buf_size = max(RDSV3_MIN_DEBUG_BUF_SIZE,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_debug_buf_size);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_debug_buf = (char *)kmem_alloc(rdsv3_debug_buf_size, KM_SLEEP);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_clear_print_buf();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_exit(&rdsv3_debug_mutex);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (flag == B_TRUE) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("RDS", "rdsv3_debug_buf_size was too small, "
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "adjusted to %x", rdsv3_debug_buf_size);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* RDS logging destroy */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_logging_destroy()
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_enter(&rdsv3_debug_mutex);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3_debug_buf) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota kmem_free(rdsv3_debug_buf, rdsv3_debug_buf_size);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_debug_buf = NULL;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_exit(&rdsv3_debug_mutex);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_destroy(&rdsv3_debug_mutex);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * debug, log, and console message handling
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * clear the RDS debug buffer
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic void
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_clear_print_buf()
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ASSERT(MUTEX_HELD(&rdsv3_debug_mutex));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3_debug_buf) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_buf_sptr = rdsv3_debug_buf;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_buf_eptr = rdsv3_debug_buf + rdsv3_debug_buf_size -
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DEBUG_SIZE_EXTRA_ALLOC;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota bzero(rdsv3_debug_buf, rdsv3_debug_buf_size);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic void
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_vlog(char *name, uint_t level, char *fmt, va_list ap)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota char *label = (name == NULL) ? "rds" : name;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota char *msg_ptr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota size_t len;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_enter(&rdsv3_debug_mutex);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* if not using logging scheme; quit */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3_suppress_dprintf || (rdsv3_debug_buf == NULL)) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_exit(&rdsv3_debug_mutex);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* If user requests to clear debug buffer, go ahead */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3_clear_debug_buf_flag != 0) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_clear_print_buf();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_clear_debug_buf_flag = 0;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * put "label" into the buffer
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota len = snprintf(rdsv3_print_buf, RDSV3_FUNCNAME_LEN, "%s:\t", label);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota msg_ptr = rdsv3_print_buf + len;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota len += vsnprintf(msg_ptr, RDSV3_PRINT_BUF_LEN - len - 2, fmt, ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota len = min(len, RDSV3_PRINT_BUF_LEN - 2);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ASSERT(len == strlen(rdsv3_print_buf));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_print_buf[len++] = '\n';
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_print_buf[len] = '\0';
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * stuff the message in the debug buf
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3_buffer_dprintf) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * overwrite >>>> that might be over the end of the
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * the buffer
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *rdsv3_buf_sptr = '\0';
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3_buf_sptr + len > rdsv3_buf_eptr) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota size_t left = (uintptr_t)rdsv3_buf_eptr -
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (uintptr_t)rdsv3_buf_sptr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota bcopy((caddr_t)rdsv3_print_buf,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (caddr_t)rdsv3_buf_sptr, left);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota bcopy((caddr_t)rdsv3_print_buf + left,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (caddr_t)rdsv3_debug_buf, len - left);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_buf_sptr = rdsv3_debug_buf + len - left;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota } else {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota bcopy((caddr_t)rdsv3_print_buf, rdsv3_buf_sptr, len);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_buf_sptr += len;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* add marker */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (void) sprintf(rdsv3_buf_sptr, ">>>>");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * LINTR, L5-L2 message may go to the rdsv3_debug_buf
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * L1 messages will go to the /var/adm/messages (debug & non-debug).
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * L0 messages will go to console (debug & non-debug).
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota switch (level) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDSV3_LOG_LINTR:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDSV3_LOG_L5:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDSV3_LOG_L4:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDSV3_LOG_L3:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDSV3_LOG_L2:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (!rdsv3_buffer_dprintf) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cmn_err(CE_CONT, "^%s", rdsv3_print_buf);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota break;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDSV3_LOG_L1:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (!rdsv3_buffer_dprintf) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cmn_err(CE_CONT, "^%s", rdsv3_print_buf);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota } else {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* go to messages file */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cmn_err(CE_CONT, "!%s", rdsv3_print_buf);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota break;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDSV3_LOG_L0:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* Strip the "\n" added earlier */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3_print_buf[len - 1] == '\n') {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_print_buf[len - 1] = '\0';
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (msg_ptr[len - 1] == '\n') {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota msg_ptr[len - 1] = '\0';
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* go to console */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cmn_err(CE_CONT, "^%s", rdsv3_print_buf);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota break;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_exit(&rdsv3_debug_mutex);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_dprintf_intr(char *name, char *fmt, ...)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_list ap;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_start(ap, fmt);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_vlog(name, RDSV3_LOG_LINTR, fmt, ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_end(ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Check individual subsystem err levels
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_CHECK_ERR_LEVEL(level) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3dbglvl < level) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return; \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_dprintf5(char *name, char *fmt, ...)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_list ap;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_CHECK_ERR_LEVEL(RDSV3_LOG_L5);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_start(ap, fmt);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_vlog(name, RDSV3_LOG_L5, fmt, ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_end(ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_dprintf4(char *name, char *fmt, ...)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_list ap;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_CHECK_ERR_LEVEL(RDSV3_LOG_L4);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_start(ap, fmt);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_vlog(name, RDSV3_LOG_L4, fmt, ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_end(ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_dprintf3(char *name, char *fmt, ...)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_list ap;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_CHECK_ERR_LEVEL(RDSV3_LOG_L3);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_start(ap, fmt);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_vlog(name, RDSV3_LOG_L3, fmt, ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_end(ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_dprintf2(char *name, char *fmt, ...)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_list ap;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_CHECK_ERR_LEVEL(RDSV3_LOG_L2);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_start(ap, fmt);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_vlog(name, RDSV3_LOG_L2, fmt, ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_end(ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_dprintf1(char *name, char *fmt, ...)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_list ap;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_start(ap, fmt);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_vlog(name, RDSV3_LOG_L1, fmt, ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_end(ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Function:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * rdsv3_dprintf0
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Input:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * name - Name of the function generating the debug message
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * fmt - The message to be displayed.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Output:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * none
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Returns:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * none
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Description:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * A generic log function to display RDS debug messages.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_dprintf0(char *name, char *fmt, ...)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_list ap;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_start(ap, fmt);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_vlog(name, RDSV3_LOG_L0, fmt, ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_end(ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* For ofed rdstrace */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_trace(char *name, uint8_t lvl, char *fmt, ...)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_list ap;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_start(ap, fmt);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_vlog(name, lvl, fmt, ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota va_end(ap);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#define DEFAULT_RATELIMIT_INTERVAL 5
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#define DEFAULT_RATELIMIT_BURST 10
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Otastruct ratelimit_state {
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota clock_t interval;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota int burst;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota int printed;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota int missed;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota hrtime_t begin;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota kmutex_t lock;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota};
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#define DEFINE_RATELIMIT_STATE(name, interval, burst) \
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota static struct ratelimit_state name = {interval, burst, }
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji OtaDEFINE_RATELIMIT_STATE(rdsv3_printk_ratelimit_state,
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota DEFAULT_RATELIMIT_INTERVAL,
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota DEFAULT_RATELIMIT_BURST);
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Otaint
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Otardsv3_printk_ratelimit(void)
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota{
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota struct ratelimit_state *rs = &rdsv3_printk_ratelimit_state;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota hrtime_t current = gethrtime();
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota int rtn = 0;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota if (rs->interval) {
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota return (1);
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota }
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota mutex_enter(&rs->lock);
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota if (!rs->begin) {
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota rs->begin = current;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota }
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota if (current < rs->begin + TICK_TO_NSEC(rs->interval)) {
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota if (rs->missed) {
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota RDSV3_DPRINTF0("rdsv3_printk_ratelimit: ",
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota "%d callbacks suppressed\n", rs->missed);
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota rs->begin = 0;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota rs->printed = 0;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota rs->missed = 0;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota }
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota }
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota if (rs->burst && rs->burst > rs->printed) {
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota rs->printed++;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota rtn = 1;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota } else {
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota rs->missed++;
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota }
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota mutex_exit(&rs->lock);
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota return (rtn);
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota}