fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ksynch.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cmn_err.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/nsc_thread.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_bcache.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_trace.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_misc.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef _SD_NOTRACE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef SM_SDTRSEMA
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define SM_SDTRSEMA 1
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define SM_SDTRLCK 1
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint _sd_trace_mask = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sdbd_trace_t _sd_trace_table[-1, 0 .. sdbc_max_devs - 1]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allocate memory, shift pointer up by one.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic _sdbc_trace_t *_sd_trace_table;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic kcondvar_t _sd_adump_cv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _sd_trace_configed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic kmutex_t _sd_adump_lk;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _alert_cd = SDT_ANY_CD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _last_cd = SDT_ANY_CD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define XMEM(x, y) (void)(x = y, y = (SDT_ANY_CD), x)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Forward declare all statics that are used before defined to enforce
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * parameter checking.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Some (if not all) of these could be removed if the code were reordered
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _sd_set_adump(int cd, int flag, _sdtr_table_t *table);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sdbc_tr_unload - cache is being unloaded. Release any memory/lock/sv's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * created by _sdbc_tr_unload and null the stale pointers.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_tr_unload(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_sd_trace_table)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free((_sd_trace_table - 1),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (_sdbc_trace_t) * (sdbc_max_devs + 1));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&_sd_adump_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&_sd_adump_lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_trace_table = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sdbc_tr_load - cache is being loaded. Allocate the memory/lock/sv's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which need to be present regardless of state of cache configuration.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_tr_load(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdbc_trace_t *m;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&_sd_adump_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&_sd_adump_lk, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this maybe ought to wait to see if traces are configured, but it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is only 4k
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte m = (_sdbc_trace_t *)nsc_kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (_sdbc_trace_t) * (sdbc_max_devs + 1),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP, sdbc_stats_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (m == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "sdbc(_sdbc_tr_load) cannot allocate trace table");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_trace_table = m + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sdbc_tr_configure - configure a trace area for the descriptor "cd".
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unlike other ..._configure routines this routine is called multiple
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * times since there will be an unknown number of open descriptors. At
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cache config time if tracing is enabled only the slot for SDT_INV_CD
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is created.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate the SD cache trace area (per device)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_tr_configure(int cd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdtr_table_t *t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmutex_t *lk;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!_sd_cache_config.trace_size)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cd == SDT_INV_CD)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_trace_configed = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_sd_trace_table[cd].tbl)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size = sizeof (_sdtr_table_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cache_config.trace_size * sizeof (_sdtr_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((t = (_sdtr_table_t *)nsc_kmem_zalloc(size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP, sdbc_stats_mem)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "sdbc(_sdbc_tr_configure) failed to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "allocate %d bytes for trace, cd=%d", size, cd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk = nsc_kmem_zalloc(sizeof (kmutex_t), KM_NOSLEEP, sdbc_local_mem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!lk) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(t, size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "sdbc(_sdbc_tr_configure) cannot "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "alloc trace lock for cd %d", cd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(lk, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_trace_table[cd].t_lock = lk;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_cd = cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_max = _sd_cache_config.trace_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_mask = _sd_cache_config.trace_mask;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_lbolt = (char)_sd_cache_config.trace_lbolt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_good = (char)_sd_cache_config.trace_good;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_trace_mask |= t->tt_mask;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_trace_table[cd].tbl = t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sdbc_tr_deconfigure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * free all trace memory (regions) when deconfiguring cache
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_tr_deconfigure(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i, size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdbc_trace_t *tt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!_sd_cache_config.trace_size || !_sd_trace_configed)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_sd_adump_lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_trace_configed = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_broadcast(&_sd_adump_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_sd_adump_lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = -1, tt = &_sd_trace_table[-1]; i < sdbc_max_devs; i++, tt++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tt->tbl == NULL) continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size = tt->tbl->tt_max * sizeof (_sdtr_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (_sdtr_table_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tt->t_lock) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(tt->t_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(tt->t_lock, sizeof (kmutex_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(tt->tbl, size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tt->t_lock = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tt->tbl = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _alert_cd = SDT_ANY_CD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _last_cd = SDT_ANY_CD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int first_alert = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SDALERT(f,cd,len,fba,flg,ret) \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_alert(f,cd,len,fba,flg,ret)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Build a ALERT trace entry and place it into the trace table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_alert(int f, int cd, int len, nsc_off_t fba, int flg, int ret)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int tin;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdtr_t *tp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdtr_table_t *t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmutex_t *lk;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!first_alert) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte first_alert++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "sdbc(_sd_alert) cd=%x f=%x len=%x fba=%" NSC_SZFMT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " flg=%x ret=%x", cd, f, len, fba, flg, ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Watch out for negative error codes or simply bogus cd's */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cd < -1 || cd >= sdbc_max_devs) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * no device trace buffer -- use SDT_INV_CD table?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((t = _sd_trace_table[-1].tbl) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk = _sd_trace_table[-1].t_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk = _sd_trace_table[cd].t_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((t = _sd_trace_table[cd].tbl) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * no device trace buffer -- use SDT_INV_CD table?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((t = _sd_trace_table[-1].tbl) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk = _sd_trace_table[-1].t_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(t->tt_mask & ST_ALERT))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return; /* check per-device mask */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t->tt_good) mutex_enter(lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_alert++; /* alert on this device */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_cnt++; /* overwritten entries if (tt_cnt >= tt_max) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tin = t->tt_in++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tin >= t->tt_max) tin = t->tt_in = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp = &t->tt_buf[tin];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_time = 0; /* not filled in yet */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t->tt_good) mutex_exit(lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_func = (ushort_t)f | ST_ALERT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_len = (ushort_t)len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_fba = fba;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_flg = flg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_ret = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * On LP64 systems we will only capture the low 32 bits of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * time this really should be good enough for our purposes.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t->tt_lbolt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_time = (int)nsc_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_time = (int)nsc_usec();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* wakeup trace daemon, with hint */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _alert_cd = cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_sd_trace_configed)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&_sd_adump_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SDTRACE(f,cd,len,fba,flg,ret) \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if (_sd_trace_mask & (f)) _sd_trace(f,cd,len,fba,flg,ret)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Build a trace entry and place it into the trace table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_trace(int f, int cd, int len, nsc_off_t fba, int flg, int ret)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int tin;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdtr_t *tp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdtr_table_t *t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmutex_t *lk;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Watch out for negative error codes or simply bogus cd's */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cd < -1 || cd >= sdbc_max_devs) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * no device trace buffer -- use SDT_INV_CD table?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((t = _sd_trace_table[-1].tbl) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk = _sd_trace_table[-1].t_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk = _sd_trace_table[cd].t_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((t = _sd_trace_table[cd].tbl) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(t->tt_mask & f))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return; /* check per-device mask */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Don't overwrite if alert signaled (count lost instead)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Locking only if 'trace_good' parameter set.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t->tt_good) mutex_enter(lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t->tt_alert && (t->tt_cnt >= t->tt_max)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_lost++; /* lost during alert */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t->tt_good) mutex_exit(lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_cnt++; /* overwritten entries if (tt_cnt >= tt_max) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tin = t->tt_in++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tin >= t->tt_max) tin = t->tt_in = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp = &t->tt_buf[tin];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_time = 0; /* not filled in yet */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t->tt_good) mutex_exit(lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_func = (ushort_t)f;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_len = (ushort_t)len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_fba = fba;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_flg = flg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_ret = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * On LP64 systems we will only capture the low 32 bits of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * time this really should be good enough for our purposes.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t->tt_lbolt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_time = (int)nsc_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tp->t_time = (int)nsc_usec();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_scan_alert -- search for device with trace alert
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_scan_alert(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte XMEM(cd, _alert_cd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cd != SDT_ANY_CD) && _sd_trace_table[cd].tbl->tt_alert)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cd = _last_cd + 1; cd < sdbc_max_devs; cd++)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_sd_trace_table[cd].tbl &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_trace_table[cd].tbl->tt_alert)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_last_cd = cd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cd = SDT_INV_CD; cd <= _last_cd; cd++)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_sd_trace_table[cd].tbl &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_trace_table[cd].tbl->tt_alert)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_last_cd = cd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (SDT_ANY_CD);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_scan_entries -- search for next device with trace entries
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_scan_entries(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cd = _last_cd + 1; cd < sdbc_max_devs; cd++)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_sd_trace_table[cd].tbl && _sd_trace_table[cd].tbl->tt_cnt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_last_cd = cd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cd = SDT_INV_CD; cd <= _last_cd; cd++)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_sd_trace_table[cd].tbl && _sd_trace_table[cd].tbl->tt_cnt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_last_cd = cd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (SDT_ANY_CD);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_adump
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * copy information about new trace records to trace daemon,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or modify trace parameters.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Some tracing parameters can be modified
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * [Either per-device if cd specified, or the defaults if cd = SDT_ANY_CD]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SD_LOGSIZE: table.tt_max (size for future opens)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SD_SET_LBOLT: table.tt_lbolt
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SD_SET_MASK: table.tt_mask
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SD_SET_GOOD: table.tt_good
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if (cd >= 0) dump specific device records;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if (cd == SDT_INV_CD) dump records which don't apply to any one device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if (cd == SDT_ANY_CD), then choose a device:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 1) most recent alert, block if (flag & SD_ALERT_WAIT)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 2) "next" device with unprocessed records.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_adump(void *args, int *rvp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct a {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte long cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdtr_table_t *table;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdtr_t *buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte long size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte long flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } *uap = (struct a *)args;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdtr_t *ubuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdtr_table_t tt, *t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmutex_t *lk;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cd, count, lost, new_cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (uap->flag & (SD_SET_SIZE|SD_SET_MASK|SD_SET_LBOLT|SD_SET_GOOD)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_sd_set_adump(uap->cd, uap->flag, uap->table));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (! _sd_trace_configed) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL); /* not initialized yet */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (uap->cd >= SDT_INV_CD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* specific device: check if configured. dump current state. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((uap->cd > (long)sdbc_max_devs) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !(t = _sd_trace_table[uap->cd].tbl)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOSPC); /* no space configured */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk = _sd_trace_table[uap->cd].t_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cd = uap->cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SDT_ANY_CD:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SD_ALERT_WAIT - wait for alert
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scan:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cd = _sd_scan_alert()) != SDT_ANY_CD)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto dump;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((uap->flag & SD_ALERT_WAIT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&_sd_adump_lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!_sd_trace_configed) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_sd_adump_lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!cv_wait_sig(&_sd_adump_cv, &_sd_adump_lk)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_sd_adump_lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINTR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&_sd_adump_lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!_sd_trace_configed || !_sd_cache_initialized) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIDRM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto scan;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* any device with entries */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cd = _sd_scan_entries()) == SDT_INV_CD)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0); /* no new entries */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dump:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk = _sd_trace_table[cd].t_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((t = _sd_trace_table[cd].tbl) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (uap->flag & SD_ALERT_WAIT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t = _sd_trace_table[-1].tbl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk = _sd_trace_table[-1].t_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOSPC); /* no space configured */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * take a snapshot of the table state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t->tt_good)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tt = *t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t->tt_good)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * copy trace log entries to daemon
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * size: entries in user-level 'buf'
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * count: how many entries to copy [force count <= size]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tt_max: size of kernel buffer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tt_cnt: written entries [lossage if tt_cnt > tt_max]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cnt: for wrap-around calculations
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((count = tt.tt_cnt) > tt.tt_max) { /* lost from beginning */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tt.tt_out = tt.tt_in;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count = tt.tt_max;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lost = tt.tt_cnt - tt.tt_max;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lost = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (count <= 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((long)count > uap->size)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count = uap->size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ubuf = uap->buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((tt.tt_out + count) > tt.tt_max) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cnt = tt.tt_max - tt.tt_out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cnt > count)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt = count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (copyout(&(t->tt_buf[tt.tt_out]), ubuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt * sizeof (_sdtr_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ubuf += cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt = count - cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (copyout(&(t->tt_buf[0]), ubuf, cnt * sizeof (_sdtr_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tt.tt_out = cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (copyout(&(t->tt_buf[tt.tt_out]), ubuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count * sizeof (_sdtr_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tt.tt_out += count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tt.tt_out == tt.tt_max)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tt.tt_out = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tt_alert uses fuzzy counting.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if multiple alerts signaled, leave it at 1.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t->tt_alert)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_alert = (t->tt_alert > 1) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tt_cntout is tt_cnt after dump
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * update tt_cnt for copied entries
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t->tt_good)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tt.tt_cntout = t->tt_cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_out = tt.tt_out;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_cnt = t->tt_cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((new_cnt -= count+lost) < 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_cnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_cnt = new_cnt; /* race with new traces if not "tt_good" */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t->tt_good)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(lk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (copyout(&tt, uap->table, sizeof (tt) - sizeof (_sdtr_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *rvp = count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte first_alert = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* set size, mask, lbolt, or good(locks) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_set_adump(int cd, int flag, _sdtr_table_t *table)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdtr_table_t tt, *t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (copyin(table, &tt, sizeof (tt) - sizeof (_sdtr_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cd == SDT_ANY_CD) { /* modify config parameter */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & SD_SET_SIZE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cache_config.trace_size = tt.tt_max;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & SD_SET_MASK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cache_config.trace_mask = tt.tt_mask;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* explicitly set global mask, not bitwise or */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_trace_mask = tt.tt_mask;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & SD_SET_LBOLT)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cache_config.trace_lbolt = tt.tt_lbolt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & SD_SET_GOOD)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cache_config.trace_good = tt.tt_good;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & SD_SET_SIZE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cache_config.trace_size = tt.tt_max;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* modify particular device parameters */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!_sd_trace_table[cd].tbl)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) _sdbc_tr_configure(cd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((t = _sd_trace_table[cd].tbl) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & SD_SET_MASK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_mask = tt.tt_mask;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_trace_mask |= tt.tt_mask; /* or-ed with global mask */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & SD_SET_LBOLT)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_lbolt = tt.tt_lbolt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & SD_SET_GOOD)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t->tt_good = tt.tt_good;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (copyout(t, table, sizeof (*t) - sizeof (_sdtr_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else /* ! _SD_NOTRACE */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint _sd_adump() { return (ENOSYS); }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint _sdbc_tr_load(void) { return (0); }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint _sdbc_tr_configure(void) { return (0); }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid _sdbc_tr_deconfigure(void) { return; }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid _sdbc_tr_unload(void) { return; }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* ! _SD_NOTRACE */