1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _ISCSI_STATS_H 27 #define _ISCSI_STATS_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /* 34 * This file contains all the definitions and prototypes relevant to KSTAT. 35 * It also contains the declaration and initialization of data. When including 36 * this file, if _INIT_KSTAT_DATA_ is defined, the data is declared AND 37 * initialized. As a consequence, this file should be included only once with 38 * _INIT_KSTAT_DATA_ defined. Failure to do so will lead to a link error. 39 * Today, iscsi_stats.c is the only file defining _INIT_KSTAT_DATA_. 40 * 41 * Four types of KSTAT structures are created for iSCSI. 42 * 43 * sun_iscsi_hba 44 * ------------- 45 * 46 * This structure gathers statistics relevant to an HBA. Each HBA or 47 * software state structure is given one. It contains the following 48 * fieds: 49 * 50 * _name iSCSI name of the HBA 51 * _alias iSCSI alias of the HBA 52 * _cntr_sess Numbers of sessions created 53 * 54 * sun_iscsi_sess 55 * -------------- 56 * 57 * This structure gathers statistics relevant to a session. Each session 58 * is given one. It contains the following fields: 59 * 60 * _state State of the session 61 * _oid OID of the session 62 * _hba HBA the session belongs to. It is the name 63 * of the sun_iscsi_hba structure of the HBA 64 * _cntr_conn Number of connections 65 * _cntr_pkt_pending Number of scsi_pkt in the pending queue 66 * _cmd_sn CmdSN 67 * _cmd_sn_exp CmdSNExp, 68 * _cmd_sn_max CmdSNMax 69 * 70 * sun_iscsi_sess_io 71 * ----------------- 72 * 73 * This structure is completely defined by the KSTAT frame work of Solaris. 74 * It contains accumulated time and queue length statistics. It assumes 75 * the driver has a pending queue and an active. In our implementation, 76 * the pending queue is the pending queue defined in the session context. 77 * The active queue is any queue defined in the connection context. 78 * If you want more information about the meaning of the fields of this 79 * structure you can read the nice explanation contained in the file: 80 * /usr/src/uts/common/sys/kstat.h. 81 * At any rate, all the sessions are given a sun_iscsi_sess_io structure. 82 * The fields are: 83 * 84 * nread number of bytes read without iSCSI overhead. 85 * nwritten number of bytes written without iSCSI overhead. 86 * reads number of read operations 87 * writes number of write operations 88 * wtime cumulative wait (pre-service) time 89 * wlentime cumulative wait length*time product 90 * wlastupdate last time wait queue changed 91 * rtime cumulative run (service) time 92 * rlentime cumulative run length*time product 93 * rlastupdate last time run queue changed 94 * wcnt count of elements in wait state 95 * rcnt count of elements in run state 96 * 97 * The time is expressed in nanoseconds. 98 * 99 * sun_iscsi_conn 100 * -------------- 101 * 102 * This structure gathers statistics relevant to a connection. Each 103 * connection is given one. It contains the following fields: 104 * 105 * _state State of the connection 106 * _cid iSCSI CID 107 * _oid OID of the connection 108 * _session Session the connection belongs to. It is the 109 * name of the sun_iscsi_sess structure of the 110 * session. 111 * _err_header_digest Number of header digest errors 112 * _err_data_digest Number of data digest errors 113 * _err_connection_reset Number of reset 114 * _err_protocol_error Number of protocol errors 115 * _cntr_tx_bytes Number of bytes transmitted with iSCSI overhead. 116 * _cntr_rx_bytes Number of bytes received with iSCSI overhead. 117 * _cntr_qactive Number of requests in the active queue. 118 * _stat_sn_exp ExpStatusSN 119 * _stat_sn_last LastStatusSN (Last one sent to the target) 120 * 121 * 122 * 123 * The KSTAT frame work of Solaris associates a module name, a instance number 124 * a class and a name to every kstat structure. All the kstat structures of 125 * iSCSI have the same module name. It is define farther down in this file to 126 * "iscsi". Regarding the class, three classes are defined here. Those classes 127 * are: 128 * 129 * - issci_hba 130 * - iscsi_sess 131 * - iscsi_conn 132 * 133 * The instance number is the number returned by ddi_get_instance. Today the 134 * the driver creates one HBA only. Therefore, all the structures will have 135 * zero as instance number. 136 * 137 * 138 * Each kstat structure can be named. The naming convention is the following: 139 * 140 * KSTAT Struct Class Name 141 * 142 * sun_iscsi_hba iscsi_hba "sun_iscsi_hba" + instance number 143 * sun_iscsi_sess iscsi_sess "sun_iscsi_sess" + session oid 144 * sun_iscsi_sess_io iscsi_sess "sun_iscsi_sess_io" + session oid 145 * sun_iscsi_conn iscsi_conn "sun_iscsi_conn" + connection oid 146 */ 147 148 /* 149 * strings used by kstat (Module name and Class name). 150 */ 151 #define iSCSI_MODULE_NAME "iscsi" 152 153 typedef struct _kstat_item { 154 char *_name; 155 uchar_t _data_type; 156 } kstat_item_t; 157 158 /* 159 * ========================= Connection Class Section ====================== 160 */ 161 162 #define iSCSI_CLASS_CONN "iscsi_conn" 163 #define iSCSI_CONN_BASE_NAME "iscsi_conn_%d_%d_%d" 164 165 #define ISCSI_CONN_STATE_FREE_STR "free" 166 #define ISCSI_CONN_STATE_IN_LOGIN_STR "in_login" 167 #define ISCSI_CONN_STATE_LOGGED_IN_STR "logged_in" 168 #define ISCSI_CONN_STATE_IN_LOGOUT_STR "in_logout" 169 #define ISCSI_CONN_STATE_CLEANUP_WAIT_STR "cleanup_wait" 170 171 /* 172 * WARNING: The order of this enum important. If you change it you have to 173 * reorder the table kstat_items_conn (in the file iscsi_stats.c) 174 * accordingly. 175 */ 176 typedef enum _kn_conn_idx { 177 KN_CONN_IDX_STATE = 0, 178 KN_CONN_IDX_CID, 179 KN_CONN_IDX_OID, 180 KN_CONN_IDX_SESS, 181 KN_CONN_IDX_ERR_HDR_DIGEST, 182 KN_CONN_IDX_ERR_DATA_DIGEST, 183 KN_CONN_IDX_ERR_CONN_RESET, 184 KN_CONN_IDX_ERR_PROTOCOL, 185 KN_CONN_IDX_CNTR_TX_BYTES, 186 KN_CONN_IDX_CNTR_RX_BYTES, 187 KN_CONN_IDX_CNTR_QACTIVE, 188 KN_CONN_IDX_EXPSTATSN, 189 KN_CONN_IDX_LASTSTATSN, 190 KN_CONN_IDX_MAX 191 } kn_conn_idx_t; 192 193 typedef struct _iscsi_conn_kstats { 194 kstat_named_t kn[KN_CONN_IDX_MAX]; 195 char sess_str[KSTAT_STRLEN]; 196 char state_str[KSTAT_STRLEN]; 197 } iscsi_conn_stats_t; 198 199 #define KSTAT_INC_CONN_ERR_HEADER_DIGEST(_icp_) \ 200 (_icp_->stats.ks_data.kn[KN_CONN_IDX_ERR_HDR_DIGEST].value.ul++) 201 202 #define KSTAT_INC_CONN_ERR_DATA_DIGEST(_icp_) \ 203 (_icp_->stats.ks_data.kn[KN_CONN_IDX_ERR_DATA_DIGEST].value.ul++) 204 205 #define KSTAT_INC_CONN_ERR_PROTOCOL(_icp_) \ 206 (_icp_->stats.ks_data.kn[KN_CONN_IDX_ERR_PROTOCOL].value.ul++) 207 208 #define KSTAT_INC_CONN_ERR_RESET(_icp_) \ 209 (_icp_->stats.ks_data.kn[KN_CONN_IDX_ERR_CONN_RESET].value.ul++) 210 211 #define KSTAT_ADD_CONN_TX_BYTES(_icp_, _v_) \ 212 (_icp_->stats.ks_data.kn[KN_CONN_IDX_CNTR_TX_BYTES].value.ui64 += \ 213 _v_) 214 215 #define KSTAT_ADD_CONN_RX_BYTES(_icp_, _v_) \ 216 (_icp_->stats.ks_data.kn[KN_CONN_IDX_CNTR_RX_BYTES].value.ui64 += \ 217 _v_) 218 219 /* 220 * ========================== Session Class Section ======================== 221 */ 222 223 /* Session Class */ 224 #define iSCSI_CLASS_SESS "iscsi_sess" 225 #define iSCSI_SESS_BASE_NAME "iscsi_sess_%d_%d" 226 #define iSCSI_SESS_IO_BASE_NAME "iscsi_sess_io_%d_%d" 227 228 #define ISCSI_SESS_STATE_FREE_STR "free" 229 #define ISCSI_SESS_STATE_LOGGED_IN_STR "logged_in" 230 #define ISCSI_SESS_STATE_FAILED_STR "failed" 231 232 /* 233 * WARNING: The order of this enum important. If you change it you have to 234 * reorder the table kstat_items_sess (in the file iscsi_stats.c) 235 * accordingly. 236 */ 237 typedef enum _kn_sess_idx { 238 KN_SESS_IDX_STATE = 0, 239 KN_SESS_IDX_OID, 240 KN_SESS_IDX_HBA, 241 KN_SESS_IDX_CNTR_CONN, 242 KN_SESS_IDX_CNTR_RESET, 243 KN_SESS_IDX_CNTR_PKT_PENDING, 244 KN_SESS_IDX_CMDSN, 245 KN_SESS_IDX_EXPCMDSN, 246 KN_SESS_IDX_MAXCMDSN, 247 KN_SESS_IDX_TARGET_NAME, 248 KN_SESS_IDX_TARGET_ALIAS, 249 KN_SESS_IDX_TPGT, 250 KN_SESS_IDX_MAX 251 } kn_sess_idx_t; 252 253 typedef struct _iscsi_sess_stats { 254 kstat_named_t kn[KN_SESS_IDX_MAX]; 255 char hba_str[KSTAT_STRLEN]; 256 char state_str[KSTAT_STRLEN]; 257 char target_name[ISCSI_MAX_NAME_LEN]; 258 char target_alias[ISCSI_MAX_NAME_LEN]; 259 } iscsi_sess_stats_t; 260 261 #define KSTAT_INC_SESS_CNTR_RESET(_isp_) \ 262 (_isp_->stats.ks_data.kn[KN_SESS_IDX_CNTR_RESET].value.ul++) 263 264 #define KSTAT_INC_SESS_CNTR_CONN(_isp_) \ 265 (_isp_->stats.ks_data.kn[KN_SESS_IDX_CNTR_CONN].value.ul++) 266 267 #define KSTAT_DEC_SESS_CNTR_CONN(_isp_) \ 268 (_isp_->stats.ks_data.kn[KN_SESS_IDX_CNTR_CONN].value.ul--) 269 270 #define KSTAT_ADD_SESS_CNTR_TX_BYTES(_isp_, _v_) \ 271 mutex_enter(&_isp_->stats.ks_io_lock); \ 272 (_isp_->stats.ks_io_data.nwritten += _v_); \ 273 mutex_exit(&_isp_->stats.ks_io_lock); 274 275 #define KSTAT_ADD_SESS_CNTR_RX_BYTES(_isp_, _v_) \ 276 mutex_enter(&_isp_->stats.ks_io_lock); \ 277 (_isp_->stats.ks_io_data.nread += _v_); \ 278 mutex_exit(&_isp_->stats.ks_io_lock); 279 280 #define KSTAT_INC_SESS_CNTR_NWRITES(_isp_) \ 281 mutex_enter(&_isp_->stats.ks_io_lock); \ 282 (_isp_->stats.ks_io_data.writes++); \ 283 mutex_exit(&_isp_->stats.ks_io_lock); 284 285 #define KSTAT_INC_SESS_CNTR_NREADS(_isp_) \ 286 mutex_enter(&_isp_->stats.ks_io_lock); \ 287 (_isp_->stats.ks_io_data.reads++); \ 288 mutex_exit(&_isp_->stats.ks_io_lock); 289 290 #define KSTAT_WAITQ_ENTER(_isp_) \ 291 mutex_enter(&_isp_->stats.ks_io_lock); \ 292 (kstat_waitq_enter(&_isp_->stats.ks_io_data)); \ 293 mutex_exit(&_isp_->stats.ks_io_lock); 294 295 #define KSTAT_WAITQ_EXIT(_isp_) \ 296 mutex_enter(&_isp_->stats.ks_io_lock); \ 297 (kstat_waitq_exit(&_isp_->stats.ks_io_data)); \ 298 mutex_exit(&_isp_->stats.ks_io_lock); 299 300 #define KSTAT_RUNQ_ENTER(_isp_) \ 301 mutex_enter(&_isp_->stats.ks_io_lock); \ 302 (kstat_runq_enter(&_isp_->stats.ks_io_data)); \ 303 mutex_exit(&_isp_->stats.ks_io_lock); 304 305 #define KSTAT_RUNQ_EXIT(_isp_) \ 306 mutex_enter(&_isp_->stats.ks_io_lock); \ 307 (kstat_runq_exit(&_isp_->stats.ks_io_data)); \ 308 mutex_exit(&_isp_->stats.ks_io_lock); 309 310 #define KSTAT_SESS_TX_IO_DONE(_isp_, _v_) \ 311 mutex_enter(&_isp_->stats.ks_io_lock); \ 312 (_isp_->stats.ks_io_data.nwritten += _v_); \ 313 (_isp_->stats.ks_io_data.writes++); \ 314 mutex_exit(&_isp_->stats.ks_io_lock); 315 316 #define KSTAT_SESS_RX_IO_DONE(_isp_, _v_) \ 317 mutex_enter(&_isp_->stats.ks_io_lock); \ 318 (_isp_->stats.ks_io_data.nread += _v_); \ 319 (_isp_->stats.ks_io_data.reads++); \ 320 mutex_exit(&_isp_->stats.ks_io_lock); 321 322 /* 323 * ============================ HBA Class Section ========================== 324 */ 325 326 #define iSCSI_CLASS_HBA "iscsi_hba" 327 #define iSCSI_HBA_BASE_NAME "iscsi_hba_%d" 328 329 /* 330 * WARNING: The order of this enum important. If you change it you have to 331 * reorder the table kstat_items_hba (in iscsi_stats.c) accordingly. 332 */ 333 typedef enum _kn_hba_idx { 334 KN_HBA_IDX_NAME = 0, 335 KN_HBA_IDX_ALIAS, 336 KN_HBA_IDX_CNTR_SESS, 337 KN_HBA_IDX_MAX 338 } kn_hba_idx_t; 339 340 typedef struct _iscsi_hba_stats { 341 kstat_named_t kn[KN_HBA_IDX_MAX]; 342 char name[ISCSI_MAX_NAME_LEN]; 343 char alias[ISCSI_MAX_NAME_LEN]; 344 } iscsi_hba_stats_t; 345 346 #define KSTAT_INC_HBA_CNTR_SESS(_ihp_) \ 347 (_ihp_->stats.ks_data.kn[KN_HBA_IDX_CNTR_SESS].value.ul++) 348 349 #define KSTAT_DEC_HBA_CNTR_SESS(_ihp_) \ 350 (_ihp_->stats.ks_data.kn[KN_HBA_IDX_CNTR_SESS].value.ul--) 351 352 #ifdef __cplusplus 353 } 354 #endif 355 356 #endif /* _ISCSI_STATS_H */ 357