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.
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.
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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/mdb_modapi.h>
27 #include <sys/nsc_thread.h>
29 /* needed to maintain identical _sd_bitmap_t sizes */
30 #define _SD_8K_BLKSIZE
31 #include <sys/nsctl/sd_bcache.h>
33 #include <ns/sdbc/sd_io.h>
34 #include <ns/sdbc/sd_ft.h>
35 #include <ns/sdbc/safestore.h>
38 * initialize cd filter options to this
39 * to differentiate with kernel values in range [-1, sdbc_max_devs]
41 #define MDB_CD ((uintptr_t)~1)
42 #define OPT_C_SELECTED (opt_c != MDB_CD)
44 /* initialize block filters to this */
45 #define MDB_BLKNUM ((uintptr_t)~1)
46 #define OPT_B_SELECTED (opt_b != MDB_BLKNUM)
48 enum vartype
{ UINTTYPE
= 0, ADDRTYPE
, LOCKTYPE
, CVTYPE
};
50 static void display_var(char *, enum vartype
);
52 static void print_wrq(_sd_writeq_t
*, uint_t
);
61 mdb_bitmask_t host_states
[] = {
62 { "HOST_NONE", 0xff, _SD_HOST_NONE
},
63 { "HOST_CONFIGURED", 0xff, _SD_HOST_CONFIGURED
},
64 { "HOST_DECONFIGURED", 0xff, _SD_HOST_DECONFIGURED
},
65 { "HOST_NOCACHE", 0xff, _SD_HOST_NOCACHE
},
70 mdb_bitmask_t cache_hints
[] = {
71 { "WRTHRU", NSC_WRTHRU
, NSC_WRTHRU
},
72 { "FORCED_WRTHRU", NSC_FORCED_WRTHRU
, NSC_FORCED_WRTHRU
},
73 { "NOCACHE", NSC_NOCACHE
, NSC_NOCACHE
},
74 { "QUEUE", NSC_QUEUE
, NSC_QUEUE
},
75 { "RDAHEAD", NSC_RDAHEAD
, NSC_RDAHEAD
},
76 { "NO_FORCED_WRTHRU", NSC_NO_FORCED_WRTHRU
, NSC_NO_FORCED_WRTHRU
},
77 { "METADATA", NSC_METADATA
, NSC_METADATA
},
78 { "SEQ_IO", NSC_SEQ_IO
, NSC_SEQ_IO
},
85 * some cache general dcmds that do not use walkers
89 sdbc_config(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
91 _sd_cache_param_t _sd_cache_config
;
92 _sd_net_t _sd_net_config
;
93 _sd_ft_info_t _sd_ft_data
;
95 char sdbc_version
[17];
97 if (mdb_readvar(sdbc_version
, "sdbc_version") == -1) {
98 mdb_warn("failed to read sdbc_version symbol");
100 sdbc_version
[16] = '\0'; /* make sure string is terminated */
101 mdb_printf("sdbc_version %s\n", sdbc_version
);
104 if (mdb_readvar(&_sd_cache_config
, "_sd_cache_config") == -1) {
105 mdb_warn("failed to read _sd_cache_config symbol");
108 mdb_printf("SDBC Configuration:\n");
110 mdb_printf("user magic: %X kernel magic: %X (should match)\n",
111 _SD_MAGIC
, _sd_cache_config
.magic
);
113 "mirror host: %2d Block size: %4d threads %4d "
114 "write cache: %4dM\n",
115 _sd_cache_config
.mirror_host
,
116 _sd_cache_config
.blk_size
,
117 _sd_cache_config
.threads
,
118 _sd_cache_config
.write_cache
);
119 mdb_printf("num_handles %4-d cache_mem %4dM prot_lru %d\n",
120 _sd_cache_config
.num_handles
,
121 _sd_cache_config
.cache_mem
[0],
122 _sd_cache_config
.prot_lru
);
123 mdb_printf("gen_pattern %d fill_pattern %?-p num_nodes %d\n",
124 _sd_cache_config
.gen_pattern
,
125 _sd_cache_config
.fill_pattern
,
126 _sd_cache_config
.num_nodes
);
130 if (mdb_readvar(&_sd_net_config
, "_sd_net_config") == -1) {
131 mdb_warn("failed to read _sd_net_config symbol");
135 "psize %4-d configured %d csize %10-d wsize %10-d cpages %6d\n",
136 _sd_net_config
.sn_psize
,
137 _sd_net_config
.sn_configured
,
138 _sd_net_config
.sn_csize
,
139 _sd_net_config
.sn_wsize
,
140 _sd_net_config
.sn_cpages
);
144 print_wrq(&(_sd_net_config
.sn_wr_queue
), FALSE
);
149 if (mdb_readvar(&_sd_ft_data
, "_sd_ft_data") == -1) {
150 mdb_warn("failed to read _sd_ft_data symbol");
153 mdb_printf("FT data:\n");
155 mdb_printf("crashed %d host_state <%b> numio %d\n",
156 _sd_ft_data
.fi_crashed
,
157 _sd_ft_data
.fi_host_state
, host_states
,
158 _sd_ft_data
.fi_numio
);
159 mdb_printf("lock %?-p (owner) rem_sv %h-x sleep %?-p (owner)\n",
160 _sd_ft_data
.fi_lock
._opaque
[0],
161 _sd_ft_data
.fi_rem_sv
._opaque
,
162 _sd_ft_data
.fi_sleep
._opaque
[0]);
166 if (mdb_readvar(&_sd_node_hint
, "_sd_node_hint") == -1) {
167 mdb_warn("failed to read _sd_node_hint symbol");
170 mdb_printf("Node Hints: %08x <%b>\n",
171 _sd_node_hint
, cache_hints
);
173 display_var("sdbc_wrthru_len", UINTTYPE
);
174 display_var("_sd_debug_level", UINTTYPE
);
175 display_var("_sdbc_attached", UINTTYPE
);
181 sdbc_hit_percent(uint_t hits
, uint_t misses
, char *type
)
183 uint64_t dhits
, dmisses
;
184 uint64_t hit_rate
= 0;
186 mdb_printf("%s hits: %u\t %s misses: %u\n", type
, hits
, type
, misses
);
188 /* a little crude. anything less than 1 percent will show as 0 */
189 if (hits
> 0 || misses
> 0) {
190 dhits
= (uint64_t)hits
;
191 dmisses
= (uint64_t)misses
;
192 hit_rate
= (dhits
* 100)/ (dhits
+ dmisses
);
193 mdb_printf("%s hit rate: %lld %%\n", type
, hit_rate
);
200 sdbc_stats(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
204 _sd_stats_t
*_sd_cache_stats
; /* local memory */
205 uintptr_t _sd_cache_statsp
; /* kernel pointer */
214 /* get the number of volumes */
215 if (mdb_readvar(&maxdevs
, "sdbc_max_devs") == -1) {
216 mdb_warn("failed to read sdbc_max_devs");
220 statssize
= sizeof (_sd_stats_t
) + (maxdevs
- 1) *
221 sizeof (_sd_shared_t
);
223 _sd_cache_stats
= mdb_zalloc(statssize
, UM_SLEEP
);
225 if (mdb_lookup_by_obj("sdbc", "_sd_cache_stats", &sym
) == -1) {
226 mdb_warn("failed to lookup _sd_cache_stats symbol");
230 if (mdb_vread(&_sd_cache_statsp
, sizeof (uintptr_t),
231 sym
.st_value
) == -1) {
232 mdb_warn("failed to read _sd_stats_t pointer");
236 if (mdb_vread(_sd_cache_stats
, statssize
, _sd_cache_statsp
) == -1) {
237 mdb_warn("failed to read _sd_stats_t structure");
241 mdb_printf("Storage Device Block Cache Statistics\n");
242 mdb_printf("-------------------------------------\n");
244 i
= _sd_cache_stats
->st_blksize
;
245 mdb_printf("Blocksize: 0x%x (%d)\n", i
, i
);
248 sdbc_hit_percent(_sd_cache_stats
->st_rdhits
, _sd_cache_stats
->st_rdmiss
,
250 sdbc_hit_percent(_sd_cache_stats
->st_wrhits
, _sd_cache_stats
->st_wrmiss
,
253 mdb_printf("%3s %10s %8s %8s %8s %8s %8s %7s %4s %4s %s\n",
255 "CacheRd", "CacheWr", "DiskRd", "DiskWr",
256 "DirtyBl", "#IO", "Fail", "F");
257 for (i
= 0; i
< maxdevs
; i
++) {
258 sh
= &_sd_cache_stats
->st_shared
[i
];
261 fn
= strrchr(sh
->sh_filename
, '/');
262 fn
= fn
? fn
+1 : sh
->sh_filename
;
263 mdb_printf("%3d %10s %7d %8d %8d %8d %8d %7d %4d %4d %d\n",
264 sh
->sh_cd
, fn
, sh
->sh_filesize
,
265 sh
->sh_cache_read
, sh
->sh_cache_write
,
266 sh
->sh_disk_read
, sh
->sh_disk_write
,
267 sh
->sh_numdirty
, sh
->sh_numio
, sh
->sh_numfail
,
271 mdb_free(_sd_cache_stats
, statssize
);
276 * display some variables and counters
279 display_var(char *name
, enum vartype type
)
288 if (mdb_readvar(&uintval
, name
) == -1) {
289 mdb_warn("failed to read %s variable", name
);
291 mdb_printf("%s =\t%8x %12u\n",
292 name
, uintval
, uintval
);
295 if (mdb_readvar(&addrval
, name
) == -1) {
296 mdb_warn("failed to read %s variable", name
);
298 mdb_printf("%s =\t%?-p\n",
302 if (mdb_readvar(&lockval
, name
) == -1) {
303 mdb_warn("failed to read %s lock variable",
306 mdb_printf("%s =\t%-p (owner)\n",
307 name
, lockval
._opaque
[0]);
310 if (mdb_readvar(&cvval
, name
) == -1) {
311 mdb_warn("failed to read %s condvar variable",
314 mdb_printf("%s = \t%h-x\n",
315 name
, cvval
._opaque
);
318 mdb_warn("display_var: unknown type");
322 mdb_bitmask_t dealloc_flag_vals
[] = {
323 { "PROCESS_CACHE_DM", (u_longlong_t
)~0, PROCESS_CACHE_DM
},
324 { "CACHE_SHUTDOWN_DM", (u_longlong_t
)~0, CACHE_SHUTDOWN_DM
},
325 { "CACHE_THREAD_TERMINATED_DM",
326 (u_longlong_t
)~0, CACHE_THREAD_TERMINATED_DM
},
327 { "TIME_DELAY_LVL0", (u_longlong_t
)~0, TIME_DELAY_LVL0
},
328 { "TIME_DELAY_LVL1", (u_longlong_t
)~0, TIME_DELAY_LVL1
},
329 { "TIME_DELAY_LVL2", (u_longlong_t
)~0, TIME_DELAY_LVL2
},
333 mdb_bitmask_t mdp_bits
[] = {
334 { "MONITOR_DYNMEM_PROCESS_DEFAULT",
335 (u_longlong_t
)~0, MONITOR_DYNMEM_PROCESS_DEFAULT
},
336 { "RPT_SHUTDOWN_PROCESS_DM",
337 RPT_SHUTDOWN_PROCESS_DM
, RPT_SHUTDOWN_PROCESS_DM
},
338 { "RPT_DEALLOC_STATS1_DM",
339 RPT_DEALLOC_STATS1_DM
, RPT_DEALLOC_STATS1_DM
},
340 { "RPT_DEALLOC_STATS2_DM",
341 RPT_DEALLOC_STATS2_DM
, RPT_DEALLOC_STATS2_DM
},
345 mdb_bitmask_t process_directive_bits
[] = {
346 { "PROCESS_DIRECTIVE_DEFAULT",
347 (u_longlong_t
)~0, PROCESS_DIRECTIVE_DEFAULT
},
348 { "WAKE_DEALLOC_THREAD_DM",
349 WAKE_DEALLOC_THREAD_DM
, WAKE_DEALLOC_THREAD_DM
},
350 { "MAX_OUT_ACCEL_HIST_FLAG_DM",
351 MAX_OUT_ACCEL_HIST_FLAG_DM
, MAX_OUT_ACCEL_HIST_FLAG_DM
},
357 sdbc_vars(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
359 int sd_dealloc_flag_dm
;
360 _dm_process_vars_t dynmem_processing_dm
;
365 mdb_printf("counters and other variables:\n");
368 display_var("xmem_inval_hit", UINTTYPE
);
369 display_var("xmem_inval_miss", UINTTYPE
);
370 display_var("xmem_inval_inuse", UINTTYPE
);
372 display_var("sdbc_allocb_pageio1", UINTTYPE
);
373 display_var("sdbc_allocb_pageio2", UINTTYPE
);
374 display_var("sdbc_allocb_inuse", UINTTYPE
);
375 display_var("sdbc_allocb_hit", UINTTYPE
);
376 display_var("sdbc_allocb_lost", UINTTYPE
);
377 display_var("sdbc_pageio_always", UINTTYPE
);
378 display_var("sdbc_do_page", UINTTYPE
);
379 display_var("sdbc_flush_pageio", UINTTYPE
);
381 display_var("sdbc_centry_hit", UINTTYPE
);
382 display_var("sdbc_centry_inuse", UINTTYPE
);
383 display_var("sdbc_centry_lost", UINTTYPE
);
384 display_var("sdbc_centry_deallocd", UINTTYPE
);
386 display_var("_sd_prefetch_opt", UINTTYPE
);
388 display_var("sdbc_ra_hash", UINTTYPE
);
389 display_var("sdbc_ra_none", UINTTYPE
);
391 display_var("sdbc_static_cache", UINTTYPE
);
392 display_var("sdbc_use_dmchain", UINTTYPE
);
394 /* in no particular order ... */
395 display_var("sdbc_check_cot", UINTTYPE
);
396 display_var("_sd_cctl_groupsz", UINTTYPE
);
397 display_var("CBLOCKS", UINTTYPE
);
398 display_var("_SD_SELF_HOST", UINTTYPE
);
399 display_var("_SD_MIRROR_HOST", UINTTYPE
);
400 display_var("sdbc_bio_count", UINTTYPE
);
401 display_var("_sd_cblock_shift", UINTTYPE
);
402 display_var("_sd_nodes_configured", UINTTYPE
);
403 display_var("nv_alloc_factor", UINTTYPE
);
404 display_var("_sd_ft_exit", UINTTYPE
);
405 display_var("_sd_flush_exit", UINTTYPE
);
406 display_var("_sd_node_recovery", UINTTYPE
);
407 display_var("_sd_async_recovery", UINTTYPE
);
408 display_var("_sdbc_ft_hold_io", UINTTYPE
);
409 display_var("mirror_clean_shutdown", UINTTYPE
);
410 display_var("_sd_ft_warm_start", UINTTYPE
);
414 /* some addresses of various lists and tables */
415 mdb_printf("Addresses:\n");
417 display_var("_sd_htable", ADDRTYPE
);
418 display_var("_sdbc_gl_centry_info", ADDRTYPE
);
419 display_var("_sdbc_gl_centry_info_nvmem", ADDRTYPE
);
420 display_var("_sdbc_gl_centry_info_size", ADDRTYPE
); /* size_t */
421 display_var("_sdbc_gl_file_info", ADDRTYPE
);
422 display_var("_sdbc_gl_file_info_size", ADDRTYPE
); /* size_t */
426 /* dynamic memory variables */
427 mdb_printf("Dynamic Memory variables and stats:\n");
429 display_var("_sdbc_memtype_deconfigure_delayed", UINTTYPE
);
431 if (mdb_readvar(&sd_dealloc_flag_dm
, "sd_dealloc_flag_dm") == -1) {
432 mdb_warn("failed to read sd_dealloc_flag_dm symbol");
434 mdb_printf("sd_dealloc_flag_dm %08x <%b>\n",
436 sd_dealloc_flag_dm
, dealloc_flag_vals
);
438 if (mdb_readvar(&dynmem_processing_dm
, "dynmem_processing_dm") == -1) {
439 mdb_warn("failed to read dynmem_processing_dm structure");
441 _dm_process_vars_t
*dp
;
443 dp
= &dynmem_processing_dm
;
446 "thread_dm_cv %h-x thread_dm_lock %?-p (owner)\n",
447 dp
->thread_dm_cv
._opaque
,
448 dp
->thread_dm_lock
._opaque
[0]);
450 mdb_printf("sd_dealloc_flagx %x %8Tmax_dyn_list %3-d\n",
451 dp
->sd_dealloc_flagx
,
454 mdb_printf("monitor_dynmem_process <%b>\n",
455 dp
->monitor_dynmem_process
, mdp_bits
);
458 "cache_aging_ct1 %3-d %8Tcache_aging_ct2 %3-d cache_aging_ct3 %3-d\n",
461 dp
->cache_aging_ct3
);
464 "cache_aging_sec1 %3-d %8Tcache_aging_sec2 %3-d"
465 " cache_aging_sec3 %3-d\n",
466 dp
->cache_aging_sec1
,
467 dp
->cache_aging_sec2
,
468 dp
->cache_aging_sec3
);
470 mdb_printf("cache_aging_pcnt1 %3-d %8Tcache_aging_pcnt2 %3-d\n",
471 dp
->cache_aging_pcnt1
,
472 dp
->cache_aging_pcnt2
);
475 "max_holds_pcnt %3-d %8Talloc_ct %8-d dealloc_ct %8-d\n",
481 "history %4x %8Tnodatas %8-d notavail %8-d candidates %8-d\n",
488 "deallocs %8-d %8Thosts %8-d pests %8-d metas %8-d\n",
494 mdb_printf("holds %8-d %8Tothers %8-d\n",
498 mdb_printf("process_directive <%b>\n",
499 dp
->process_directive
, process_directive_bits
);
501 mdb_printf("read_hits %8-d %8Tread_misses %8-d\n",
506 "write_thru %8-d %8Twrite_hits %8-d write_misses %8-d\n",
511 mdb_printf("prefetch_hits %8-d prefetch_misses %8-d\n",
513 dp
->prefetch_misses
);
518 /* some locks and condition variables */
519 mdb_printf("Locks:\n");
521 display_var("mutex_and_condvar_flag", UINTTYPE
);
522 display_var("_sd_cache_lock", LOCKTYPE
);
523 display_var("_sd_block_lk", LOCKTYPE
);
524 display_var("_sdbc_config_lock", LOCKTYPE
);
525 display_var("_sdbc_ft_hold_io_lk", LOCKTYPE
);
526 display_var("_sd_flush_cv", CVTYPE
);
527 display_var("_sdbc_ft_hold_io_cv", CVTYPE
);
534 const mdb_bitmask_t nsc_buf_bits
[] = {
535 {"HALLOCATED", NSC_HALLOCATED
, NSC_HALLOCATED
},
536 {"HACTIVE", NSC_HACTIVE
, NSC_HACTIVE
},
537 {"RDBUF", NSC_RDBUF
, NSC_RDBUF
},
538 {"WRBUF", NSC_WRBUF
, NSC_WRBUF
},
539 {"NOBLOCK", NSC_NOBLOCK
, NSC_NOBLOCK
},
540 {"WRTHRU", NSC_WRTHRU
, NSC_WRTHRU
},
541 {"NOCACHE", NSC_NOCACHE
, NSC_NOCACHE
},
542 {"BCOPY", NSC_BCOPY
, NSC_BCOPY
},
543 {"PAGEIO", NSC_PAGEIO
, NSC_PAGEIO
},
544 {"PINNABLE", NSC_PINNABLE
, NSC_PINNABLE
},
545 {"FORCED_WRTHRU", NSC_FORCED_WRTHRU
, NSC_FORCED_WRTHRU
},
546 {"METADATA", NSC_METADATA
, NSC_METADATA
},
547 {"MIXED", NSC_MIXED
, NSC_MIXED
},
553 * HELP functions for cache ctl type dcmds
557 cctl_help_common(char *name
)
560 mdb_printf("-c cd displays cctls for cache descriptor 'cd'\n");
562 mdb_printf("inclusive filters:\n");
564 mdb_printf("-b blk displays cctls for cache block number 'blk'\n");
565 mdb_printf("-d displays cctls with dirty bits\n");
566 mdb_printf("-h displays cctls that are hashed\n");
567 mdb_printf("-i displays cctls that are inuse\n");
568 mdb_printf("-o displays cctls that have I/O in progress\n");
569 mdb_printf("-p displays cctls that have pagio set\n");
570 mdb_printf("-B displays cctls that are marked BAD\n");
571 mdb_printf("-H displays cctls that are HOSTS\n");
572 mdb_printf("-P displays cctls that are PARASITES\n");
573 mdb_printf("-R displays cctls that are explicit (NSC_RDAHEAD) "
575 mdb_printf("-r displays cctls that are implicit Prefetch bufs\n");
576 mdb_printf("-V displays cctls that have valid bits set\n");
577 mdb_printf("-v verbose\n");
580 mdb_printf("Default: %s displays all cctls in the list\n", name
);
583 mdb_printf("Example:\n");
586 mdb_printf("%s -io -c 5 displays all cctls for cd 5 that are\n"
587 "in use or have I/O in progress\n", name
);
591 #define CCTL_OPTIONSTRING "[-vdhiopBHPV][-c cd][-b blknum]"
595 mdb_printf("sdbc_cctl displays cache ctl structures\n");
596 mdb_printf("Usage: [address]::sdbc_cctl " CCTL_OPTIONSTRING
"\n");
597 cctl_help_common("sdbc_cctl");
603 mdb_printf("sdbc_cchain displays cache ctl structures in a"
604 " (alloc) cc_chain\n");
605 mdb_printf("Usage: address::sdbc_cchain " CCTL_OPTIONSTRING
"\n");
606 cctl_help_common("sdbc_cchain");
612 mdb_printf("sdbc_dchain displays cache ctl structures in a"
614 mdb_printf("Usage: address::sdbc_dchain " CCTL_OPTIONSTRING
"\n");
615 cctl_help_common("sdbc_dchain");
621 mdb_printf("sdbc_dmchain displays cache ctl structures in a"
622 " dynamic memory allocation chain\n");
623 mdb_printf("order of display is:\n"
624 "the cctl represented by the given address,\n"
625 "the cc_head_dm cctl,\n"
626 "the chain starting at cc_next_dm of the head cctl\n");
627 mdb_printf("Usage: address::sdbc_dmchain " CCTL_OPTIONSTRING
"\n");
628 cctl_help_common("sdbc_dmchain");
634 mdb_printf("sdbc_hashchain displays cache ctl structures in a"
636 mdb_printf("Usage: address::sdbc_hashchain " CCTL_OPTIONSTRING
"\n");
637 cctl_help_common("sdbc_hashchain");
643 mdb_printf("sdbc_hashtable displays the hash table and its chains\n");
644 mdb_printf("Usage: address::sdbc_hashtable " CCTL_OPTIONSTRING
"\n");
645 cctl_help_common("sdbc_hashtable");
652 mdb_printf("sdbc_lru displays cache ctl structures in the LRU queue\n");
653 mdb_printf("Usage: [address]::sdbc_lru " CCTL_OPTIONSTRING
"\n");
654 cctl_help_common("sdbc_lru");
658 * help functions for write ctl dcmds
661 wctl_help_common(char *name
)
664 mdb_printf("-v verbose\n");
665 mdb_printf("-c cd show ctl structs for cache descriptor 'cd'\n");
666 mdb_printf("-d show ctl structs that have dirty bits set\n");
668 mdb_printf("Default: %s displays all write ctl in the list\n", name
);
675 "sdbc_wctl displays the allocated array of write ctl structures\n");
676 mdb_printf("Usage: [address]::sdbc_wctl [-vd][-c cd]\n");
677 wctl_help_common("sdbc_wctl");
683 mdb_printf("sdbc_wrq displays the write ctl queue (wctl free list)\n");
684 mdb_printf("Usage: [address]::sdbc_wrq [-vd][-c cd]\n");
685 wctl_help_common("sdbc_wrq");
688 /* help function for the sdbc_cdinfo dcmd */
693 "sdbc_cdinfo displays cd information from the _sd_cache_files table\n");
694 mdb_printf("Usage: [address]::sdbc_cdfinfo [-av][-c cd]\n");
696 mdb_printf("-a displays info for all cd_info structures\n");
697 mdb_printf("-c cd displays info for cache descriptor 'cd'\n");
698 mdb_printf("-v verbose\n");
700 mdb_printf("Default: display info for cd's that are allocated\n");
707 "sdbc_ftctl displays the array of fault tolerant structures \n");
708 mdb_printf("Usage: [address]::sdbc_ftctl [-vd][-c cd]\n");
709 wctl_help_common("sdbc_ftctl");
713 * help function for the sdbc_handles dcmd
718 mdb_printf("sdbc_handles displays active or allocated"
719 " cache buffer handles\n");
720 mdb_printf("Usage: [address]::sdbc_handles [-avC][-c cd]\n");
722 mdb_printf("-a displays all handles\n");
723 mdb_printf("-c n displays handle for cd n\n");
724 mdb_printf("-v displays detailed handle data\n");
725 mdb_printf("-C displays the handle cc_chain\n");
727 mdb_printf("Default: display only allocated or active handles\n");
731 * help functions for the "global" memory dcmds
736 mdb_printf("sdbc_glcinfo displays the global cache entry info\n");
737 mdb_printf("Usage: [address]::sdbc_glcinfo [-adC][-c cd][-b fbapos]\n");
739 mdb_printf("-a displays all global info structs\n");
740 mdb_printf("-b fbapos displays structs that match FBA block"
741 "(not cache block) 'fbapos'\n");
742 mdb_printf("-c cd displays structs that match cache descriptor 'cd'\n");
743 mdb_printf("-d displays structs with dirty bits set\n");
744 mdb_printf("-C does consistency check against nvram copy\n");
746 mdb_printf("Default: display entries with a valid cd\n");
752 mdb_printf("sdbc_glfinfo displays the global file info\n");
753 mdb_printf("Usage: [address]::sdbc_glfinfo [-aptC]\n");
755 mdb_printf("-a displays all global info structs\n");
756 mdb_printf("-p displays structs for pinned volumes\n");
757 mdb_printf("-t displays structs for attached volumes\n");
758 mdb_printf("-C does consistency check against nvram copy\n");
760 mdb_printf("Default: display entries with non-null filename\n");
769 * walker for the cctl list using the cc_link_list_dm pointers
772 sdbc_cctl_winit(mdb_walk_state_t
*wsp
)
774 _sd_cctl_t
*_sd_cctl
[_SD_CCTL_GROUPS
]; /* for getting first entry */
775 struct walk_info
*winfo
;
777 winfo
= mdb_zalloc(sizeof (struct walk_info
), UM_SLEEP
);
779 if (wsp
->walk_addr
== NULL
) {
781 * we get the "first" cctl from memory and then traverse
782 * the cc_link_list_dm pointers.
783 * this traversal could start from any cctl. here we start with
784 * the first cctl in the _sd_cctl[] array.
786 if (mdb_readvar(_sd_cctl
, "_sd_cctl") == -1) {
787 mdb_warn("failed to read _sd_cctl array");
791 wsp
->walk_addr
= (uintptr_t)_sd_cctl
[0];
795 winfo
->w_end
= wsp
->walk_addr
;
796 wsp
->walk_data
= winfo
;
802 sdbc_cctl_wstep(mdb_walk_state_t
*wsp
)
804 struct walk_info
*winfo
= wsp
->walk_data
;
808 if (wsp
->walk_addr
== NULL
) /* should not happen */
812 * w_start is 0 on the first iteration so the test
813 * will fail, allowing the first centry to be processed
815 if (wsp
->walk_addr
== winfo
->w_start
)
818 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
821 if (mdb_vread(¢ry
, sizeof (_sd_cctl_t
), wsp
->walk_addr
) == -1) {
822 mdb_warn("failed to read centry at %p", wsp
->walk_addr
);
825 wsp
->walk_addr
= (uintptr_t)(centry
.cc_link_list_dm
);
826 /* set termination condition. only needs to be done once */
827 winfo
->w_start
= winfo
->w_end
;
833 sdbc_cctl_wfini(mdb_walk_state_t
*wsp
)
835 mdb_free(wsp
->walk_data
, sizeof (struct walk_info
));
839 * walk the cc_chain list of a _sd_cctl_t
840 * no global walks -- must be called with an address
843 sdbc_cchain_winit(mdb_walk_state_t
*wsp
)
845 if (wsp
->walk_addr
== NULL
)
848 wsp
->walk_data
= mdb_zalloc(sizeof (_sd_cctl_t
), UM_SLEEP
);
854 sdbc_cchain_wstep(mdb_walk_state_t
*wsp
)
858 if (wsp
->walk_addr
== NULL
)
861 if (mdb_vread(wsp
->walk_data
, sizeof (_sd_cctl_t
), wsp
->walk_addr
)
863 mdb_warn("sdbc_cchain_wstep failed to read centry at %p",
868 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
871 wsp
->walk_addr
= (uintptr_t)(((_sd_cctl_t
*)
872 (wsp
->walk_data
))->cc_chain
);
877 sdbc_cchain_wfini(mdb_walk_state_t
*wsp
)
879 mdb_free(wsp
->walk_data
, sizeof (_sd_cctl_t
));
884 * walk the dirty chain list of a _sd_cctl_t
885 * no global walks -- must be called with an address
888 sdbc_dchain_winit(mdb_walk_state_t
*wsp
)
890 if (wsp
->walk_addr
== NULL
)
893 wsp
->walk_data
= mdb_zalloc(sizeof (_sd_cctl_t
), UM_SLEEP
);
895 /* walk data stores the first and subsequent cc_dirty_link */
896 if (mdb_vread(wsp
->walk_data
, sizeof (_sd_cctl_t
), wsp
->walk_addr
)
898 mdb_warn("sdbc_dchain_winit failed to read centry at %p",
907 sdbc_dchain_wstep(mdb_walk_state_t
*wsp
)
912 if (wsp
->walk_addr
== NULL
)
915 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
919 if (mdb_vread(¢ry
, sizeof (_sd_cctl_t
), wsp
->walk_addr
)
921 mdb_warn("sdbc_dchain_wstep failed to read centry at %p",
927 (uintptr_t)(centry
.cc_dirty_next
);
929 /* end of dirty_next chain? start on subsequent dirty_link */
930 if (wsp
->walk_addr
== NULL
) {
932 (uintptr_t)(((_sd_cctl_t
*)(wsp
->walk_data
))->cc_dirty_link
);
934 /* update dirty link */
935 /* walk data stores the first and subsequent cc_dirty_link */
936 if (wsp
->walk_addr
) {
937 if (mdb_vread(wsp
->walk_data
, sizeof (_sd_cctl_t
),
938 wsp
->walk_addr
) == -1) {
941 "sdbc_dchain_wstep failed to read centry at %p",
953 sdbc_dchain_wfini(mdb_walk_state_t
*wsp
)
955 mdb_free(wsp
->walk_data
, sizeof (_sd_cctl_t
));
958 /* for stepping thru the dynmem chain */
959 #define GET_HEAD_DM 0x1
960 #define GET_NEXT_DM 0x2
963 * walk the dm chain of a cctl
964 * start with current address, then cc_head_dm, then the cc_next_dm chain
967 sdbc_dmchain_winit(mdb_walk_state_t
*wsp
)
969 if (wsp
->walk_addr
== NULL
)
972 wsp
->walk_data
= (void *)GET_HEAD_DM
;
978 sdbc_dmchain_wstep(mdb_walk_state_t
*wsp
)
983 if (wsp
->walk_addr
== NULL
)
986 if (mdb_vread(¢ry
, sizeof (_sd_cctl_t
), wsp
->walk_addr
)
988 mdb_warn("sdbc_dmchain_wstep failed to read centry at %p",
993 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
996 if (wsp
->walk_data
== (void *)GET_HEAD_DM
) {
997 wsp
->walk_addr
= (uintptr_t)centry
.cc_head_dm
;
998 wsp
->walk_data
= (void *)GET_NEXT_DM
;
1000 wsp
->walk_addr
= (uintptr_t)centry
.cc_next_dm
;
1007 sdbc_dmchain_wfini(mdb_walk_state_t
*wsp
)
1013 * requires an address
1017 sdbc_hashchain_winit(mdb_walk_state_t
*wsp
)
1020 if (wsp
->walk_addr
== NULL
)
1028 sdbc_hashchain_wstep(mdb_walk_state_t
*wsp
)
1031 _sd_hash_hd_t hash_entry
;
1034 if (wsp
->walk_addr
== NULL
)
1037 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
1040 if (mdb_vread(&hash_entry
, sizeof (_sd_hash_hd_t
),
1041 wsp
->walk_addr
) == -1) {
1043 "sdbc_hashchain_wstep failed to read hash_entry at %p",
1045 return (WALK_ERR
); /* will upper layer continue ? */
1048 wsp
->walk_addr
= (uintptr_t)hash_entry
.hh_next
;
1055 sdbc_hashchain_wfini(mdb_walk_state_t
*wsp
)
1060 * walk the sdbc lru list
1063 sdbc_lru_winit(mdb_walk_state_t
*wsp
)
1065 struct walk_info
*winfo
;
1068 winfo
= mdb_zalloc(sizeof (struct walk_info
), UM_SLEEP
);
1070 /* if called without an address, start at the head of the queue */
1071 if (wsp
->walk_addr
== NULL
) {
1073 if (mdb_lookup_by_obj("sdbc", "_sd_lru_q", &sym
) == -1) {
1074 mdb_warn("failed to lookup _sd_lru_q symbol");
1078 /* &(_sd_lru_q.sq_qhead) */
1079 wsp
->walk_addr
= (uintptr_t)(sym
.st_value
);
1083 winfo
->w_end
= wsp
->walk_addr
;
1084 wsp
->walk_data
= winfo
;
1090 sdbc_lru_wstep(mdb_walk_state_t
*wsp
)
1092 struct walk_info
*winfo
= wsp
->walk_data
;
1096 if (wsp
->walk_addr
== NULL
) /* should not happen */
1100 * w_start is 0 on the first iteration so the test
1101 * will fail, allowing the first centry to be processed
1103 if (wsp
->walk_addr
== winfo
->w_start
)
1106 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
1109 if (mdb_vread(¢ry
, sizeof (_sd_cctl_t
), wsp
->walk_addr
) == -1) {
1110 mdb_warn("failed to read centry at %p", wsp
->walk_addr
);
1113 wsp
->walk_addr
= (uintptr_t)(centry
.cc_next
);
1115 /* set termination condition. only needs to be done once */
1116 winfo
->w_start
= winfo
->w_end
;
1122 sdbc_lru_wfini(mdb_walk_state_t
*wsp
)
1124 mdb_free(wsp
->walk_data
, sizeof (struct walk_info
));
1130 * walk the array of allocated write control structures
1134 sdbc_wctl_winit(mdb_walk_state_t
*wsp
)
1136 _sd_net_t _sd_net_config
;
1138 struct walk_info
*winfo
;
1143 winfo
= mdb_zalloc(sizeof (struct walk_info
), UM_SLEEP
);
1145 /* need to calculate the end of the array */
1146 if (mdb_readvar(&_sd_net_config
, "_sd_net_config") == -1) {
1147 mdb_warn("failed to read _sd_net_config structure");
1151 if (wsp
->walk_addr
== NULL
)
1152 wsp
->walk_addr
= (uintptr_t)(_sd_net_config
.sn_wr_cctl
);
1155 * this module assumes 8k block size so this code can
1156 * be commented out if necessary.
1158 if (mdb_readvar(&blk_shft
, "_sd_cblock_shift") == -1) {
1159 mdb_warn("failed to read _sd_cblock_shift."
1160 "assuming 8k cache block size");
1164 count
= (_sd_net_config
.sn_wpages
* _sd_net_config
.sn_psize
) /
1167 winfo
->w_end
= (uintptr_t)(_sd_net_config
.sn_wr_cctl
+ count
);
1168 wsp
->walk_data
= winfo
;
1174 sdbc_wctl_wstep(mdb_walk_state_t
*wsp
)
1176 struct walk_info
*winfo
= wsp
->walk_data
;
1179 if (wsp
->walk_addr
== NULL
)
1182 if (wsp
->walk_addr
>= winfo
->w_end
)
1185 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
1188 wsp
->walk_addr
+= sizeof (_sd_wr_cctl_t
);
1195 sdbc_wctl_wfini(mdb_walk_state_t
*wsp
)
1197 mdb_free(wsp
->walk_data
, sizeof (struct walk_info
));
1201 * walk the queue (free list) of write control structures
1205 sdbc_wrq_winit(mdb_walk_state_t
*wsp
)
1207 _sd_net_t _sd_net_config
;
1210 /* if called without an address, start at the head of the queue */
1211 if (wsp
->walk_addr
== NULL
) {
1213 if (mdb_readvar(&_sd_net_config
, "_sd_net_config") == -1) {
1214 mdb_warn("failed to read _sd_net_config structure");
1218 wsp
->walk_addr
= (uintptr_t)
1219 (_sd_net_config
.sn_wr_queue
.wq_qtop
);
1226 sdbc_wrq_wstep(mdb_walk_state_t
*wsp
)
1231 if (wsp
->walk_addr
== NULL
)
1234 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
1237 if (mdb_vread(&wctl
, sizeof (_sd_wr_cctl_t
), wsp
->walk_addr
)
1239 mdb_warn("sdbc_cchain_wstep failed to read wctl at %p",
1244 /* special case -- mini-DSP fake wr_cctl */
1245 if (wsp
->walk_addr
== (uintptr_t)wctl
.wc_next
)
1248 wsp
->walk_addr
= (uintptr_t)(wctl
.wc_next
);
1254 sdbc_wrq_wfini(mdb_walk_state_t
*wsp
)
1257 #endif /* SAFESTORE */
1259 * walk the _sd_cache_files array of cd_info structures
1262 sdbc_cdinfo_winit(mdb_walk_state_t
*wsp
)
1264 struct walk_info
*winfo
;
1265 _sd_cd_info_t
*_sd_cache_files_addr
;
1268 winfo
= mdb_zalloc(sizeof (struct walk_info
), UM_SLEEP
);
1271 /* get the address of the cdinfo table */
1272 if (mdb_readvar(&_sd_cache_files_addr
, "_sd_cache_files") == -1) {
1273 mdb_warn("failed to read _sd_cache_files address\n");
1277 /* if called without an address, start at the head of the queue */
1278 if (wsp
->walk_addr
== NULL
) {
1279 /* address of first _sd_cd_info_t */
1280 wsp
->walk_addr
= (uintptr_t)(_sd_cache_files_addr
);
1283 /* get the number of volumes */
1284 if (mdb_readvar(&maxdevs
, "sdbc_max_devs") == -1) {
1285 mdb_warn("failed to read sdbc_max_devs");
1289 winfo
->w_end
= (uintptr_t)(_sd_cache_files_addr
+ maxdevs
);
1290 wsp
->walk_data
= winfo
;
1296 sdbc_cdinfo_wstep(mdb_walk_state_t
*wsp
)
1298 struct walk_info
*winfo
= wsp
->walk_data
;
1301 if (wsp
->walk_addr
>= winfo
->w_end
)
1304 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
1307 wsp
->walk_addr
+= sizeof (_sd_cd_info_t
);
1313 sdbc_cdinfo_wfini(mdb_walk_state_t
*wsp
)
1315 mdb_free(wsp
->walk_data
, sizeof (struct walk_info
));
1320 * walk the array of allocated fault tolerant control structures
1323 sdbc_ftctl_winit(mdb_walk_state_t
*wsp
)
1325 _sd_net_t _sd_net_config
;
1326 struct walk_info
*winfo
;
1327 int blk_shft
= 13; /* 8k default */
1331 winfo
= mdb_zalloc(sizeof (struct walk_info
), UM_SLEEP
);
1333 /* need to calculate the end of the array */
1334 if (mdb_readvar(&_sd_net_config
, "_sd_net_config") == -1) {
1335 mdb_warn("failed to read _sd_net_config structure");
1339 if (wsp
->walk_addr
== NULL
)
1340 wsp
->walk_addr
= (uintptr_t)(_sd_net_config
.sn_ft_cctl
);
1343 * this module assumes 8k block size so this code can
1344 * be commented out if necessary.
1346 if (mdb_readvar(&blk_shft
, "_sd_cblock_shift") == -1) {
1347 mdb_warn("failed to read _sd_cblock_shift."
1348 "assuming 8k cache block size");
1352 count
= (_sd_net_config
.sn_wpages
* _sd_net_config
.sn_psize
) /
1355 winfo
->w_end
= (uintptr_t)(_sd_net_config
.sn_ft_cctl
+ count
);
1356 wsp
->walk_data
= winfo
;
1362 sdbc_ftctl_wstep(mdb_walk_state_t
*wsp
)
1364 struct walk_info
*winfo
= wsp
->walk_data
;
1367 if (wsp
->walk_addr
== NULL
)
1370 if (wsp
->walk_addr
>= winfo
->w_end
)
1373 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
1376 wsp
->walk_addr
+= sizeof (_sd_ft_cctl_t
);
1382 sdbc_ftctl_wfini(mdb_walk_state_t
*wsp
)
1384 mdb_free(wsp
->walk_data
, sizeof (struct walk_info
));
1386 #endif /* SAFESTORE */
1389 * walk the handle list
1392 sdbc_handle_winit(mdb_walk_state_t
*wsp
)
1395 struct walk_info
*winfo
;
1398 if (mdb_readvar(&hl
, "_sd_handle_list") == -1) {
1399 mdb_warn("failed to read _sd_handle_list structure");
1403 if (mdb_lookup_by_obj("sdbc", "_sd_handle_list", &sym
) == -1) {
1404 mdb_warn("failed to lookup _sd_handle_list symbol");
1408 /* if called without an address, start at first element in list */
1409 if (wsp
->walk_addr
== NULL
)
1410 wsp
->walk_addr
= (uintptr_t)(hl
.hl_top
.bh_next
);
1412 winfo
= mdb_zalloc(sizeof (struct walk_info
), UM_SLEEP
);
1414 winfo
->w_end
= (uintptr_t)(sym
.st_value
); /* &_sd_handle_list.hl_top */
1415 wsp
->walk_data
= winfo
;
1421 sdbc_handle_wstep(mdb_walk_state_t
*wsp
)
1423 struct walk_info
*winfo
= wsp
->walk_data
;
1424 _sd_buf_handle_t handle
;
1427 if (wsp
->walk_addr
== NULL
)
1430 if (wsp
->walk_addr
== winfo
->w_end
)
1433 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
1436 if (mdb_vread(&handle
, sizeof (_sd_buf_handle_t
), wsp
->walk_addr
)
1438 mdb_warn("failed to read handle at %p", wsp
->walk_addr
);
1442 wsp
->walk_addr
= (uintptr_t)(handle
.bh_next
);
1448 sdbc_handle_wfini(mdb_walk_state_t
*wsp
)
1450 mdb_free(wsp
->walk_data
, sizeof (struct walk_info
));
1454 * walk the global info array (dirty bits)
1458 sdbc_glcinfo_winit(mdb_walk_state_t
*wsp
)
1460 ss_centry_info_t
*gl_centry_info
;
1461 size_t gl_centry_info_size
;
1462 struct walk_info
*winfo
;
1465 winfo
= mdb_zalloc(sizeof (struct walk_info
), UM_SLEEP
);
1467 /* get start of the cache entry metadata */
1468 if (mdb_readvar(&gl_centry_info
, "_sdbc_gl_centry_info") == -1) {
1469 mdb_warn("failed to read _sdbc_gl_centry_info");
1473 /* need to calculate the end of the array */
1474 if (mdb_readvar(&gl_centry_info_size
,
1475 "_sdbc_gl_centry_info_size") == -1) {
1476 mdb_warn("failed to read _sdbc_gl_centry_info_size");
1480 if (wsp
->walk_addr
== NULL
)
1481 wsp
->walk_addr
= (uintptr_t)(gl_centry_info
);
1485 winfo
->w_end
= ((uintptr_t)(gl_centry_info
)) + gl_centry_info_size
;
1486 wsp
->walk_data
= winfo
;
1492 sdbc_glcinfo_wstep(mdb_walk_state_t
*wsp
)
1494 struct walk_info
*winfo
= wsp
->walk_data
;
1497 if (wsp
->walk_addr
== NULL
)
1500 if (wsp
->walk_addr
>= winfo
->w_end
)
1502 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
1505 wsp
->walk_addr
+= sizeof (ss_centry_info_t
);
1511 sdbc_glcinfo_wfini(mdb_walk_state_t
*wsp
)
1513 mdb_free(wsp
->walk_data
, sizeof (struct walk_info
));
1517 * walk the global file info array
1520 sdbc_glfinfo_winit(mdb_walk_state_t
*wsp
)
1522 ss_voldata_t
*gl_file_info
;
1523 struct walk_info
*winfo
;
1527 winfo
= mdb_zalloc(sizeof (struct walk_info
), UM_SLEEP
);
1529 /* get start of the cache entry metadata */
1530 if (mdb_readvar(&gl_file_info
, "_sdbc_gl_file_info") == -1) {
1531 mdb_warn("failed to read _sdbc_gl_file_info");
1536 if (wsp
->walk_addr
== NULL
)
1537 wsp
->walk_addr
= (uintptr_t)(gl_file_info
);
1539 /* get the number of volumes */
1540 if (mdb_readvar(&maxdevs
, "sdbc_max_devs") == -1) {
1541 mdb_warn("failed to read sdbc_max_devs");
1545 /* end of the array */
1546 winfo
->w_end
= (uintptr_t)((gl_file_info
) + maxdevs
);
1548 wsp
->walk_data
= winfo
;
1554 sdbc_glfinfo_wstep(mdb_walk_state_t
*wsp
)
1556 struct walk_info
*winfo
= wsp
->walk_data
;
1559 if (wsp
->walk_addr
== NULL
)
1562 if (wsp
->walk_addr
>= winfo
->w_end
)
1565 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
1568 wsp
->walk_addr
+= sizeof (ss_voldata_t
);
1575 sdbc_glfinfo_wfini(mdb_walk_state_t
*wsp
)
1577 mdb_free(wsp
->walk_data
, sizeof (struct walk_info
));
1580 /* end of WALKERS section */
1583 const mdb_bitmask_t cc_flag_bits
[] = {
1584 {"PEND_DIRTY", CC_PEND_DIRTY
, CC_PEND_DIRTY
},
1585 {"PINNED", CC_PINNED
, CC_PINNED
},
1586 {"PINNABLE", CC_PINNABLE
, CC_PINNABLE
},
1587 {"QHEAD", CC_QHEAD
, CC_QHEAD
},
1591 const mdb_bitmask_t io_status_bits
[] = {
1592 {"IO_NONE", 0xff, _SD_IO_NONE
},
1593 {"IO_INITIATE", 0xff, _SD_IO_INITIATE
},
1594 {"IO_DONE", 0xff, _SD_IO_DONE
},
1595 {"IO_FAILED", 0xff, _SD_IO_FAILED
},
1596 {"IO_DISCARDED", 0xff, _SD_IO_DISCARDED
},
1600 const mdb_bitmask_t cc_aging_bits
[] = {
1601 {"FOUND_IN_HASH", FOUND_IN_HASH_DM
, FOUND_IN_HASH_DM
},
1602 {"FOUND_HOLD_OVER", FOUND_HOLD_OVER_DM
, FOUND_HOLD_OVER_DM
},
1603 {"HOST_ENTRY", HOST_ENTRY_DM
, HOST_ENTRY_DM
},
1604 {"PARASITIC_ENTRY", PARASITIC_ENTRY_DM
, PARASITIC_ENTRY_DM
},
1605 {"STICKY_METADATA", STICKY_METADATA_DM
, STICKY_METADATA_DM
},
1606 {"ELIGIBLE_ENTRY", ELIGIBLE_ENTRY_DM
, ELIGIBLE_ENTRY_DM
},
1607 {"HASH_ENTRY", HASH_ENTRY_DM
, HASH_ENTRY_DM
},
1608 {"HOLD_ENTRY", HOLD_ENTRY_DM
, HOLD_ENTRY_DM
},
1609 {"AVAIL_ENTRY", AVAIL_ENTRY_DM
, AVAIL_ENTRY_DM
},
1610 {"BAD_CHAIN", BAD_CHAIN_DM
, BAD_CHAIN_DM
},
1611 {"BAD_ENTRY", BAD_ENTRY_DM
, BAD_ENTRY_DM
},
1612 {"PREFETCH_I", PREFETCH_BUF_I
, PREFETCH_BUF_I
},
1613 {"PREFETCH_E", PREFETCH_BUF_E
, PREFETCH_BUF_E
},
1618 /* DCMDS that use walkers */
1621 * dcmd to display cache entry control structures
1624 sdbc_cctl(uintptr_t addr
, uint_t flags
, int argc
,
1625 const mdb_arg_t
*argv
)
1627 uint_t opt_a
= FALSE
;
1628 uintptr_t opt_c
= MDB_CD
; /* cd */
1629 uintptr_t opt_b
= MDB_BLKNUM
; /* block num */
1630 uint_t opt_B
= FALSE
; /* BAD CHAIN or ENTRY */
1631 uint_t opt_d
= FALSE
; /* dirty */
1632 uint_t opt_H
= FALSE
; /* HOST */
1633 uint_t opt_h
= FALSE
; /* hashed */
1634 uint_t opt_i
= FALSE
; /* inuse */
1635 uint_t opt_p
= FALSE
; /* pageio */
1636 uint_t opt_P
= FALSE
; /* PARASITE */
1637 uint_t opt_R
= FALSE
; /* explicit read-ahead (prefetch) */
1638 uint_t opt_r
= FALSE
; /* implicit read-ahead (prefetch) */
1639 uint_t opt_o
= FALSE
; /* io in progress */
1640 uint_t opt_m
= FALSE
; /* has memory allocated */
1641 uint_t opt_V
= FALSE
; /* valid bits */
1642 uint_t opt_v
= FALSE
; /* verbose */
1643 uint_t nofilter
= FALSE
; /* true if b, d, h, i, o, p, V are all false */
1645 _sd_cctl_sync_t cc_sync
;
1648 * possible enhancements -- option to filter on flag bits
1649 * option that toggles other options.
1651 if (mdb_getopts(argc
, argv
,
1652 'a', MDB_OPT_SETBITS
, TRUE
, &opt_a
,
1653 'B', MDB_OPT_SETBITS
, TRUE
, &opt_B
,
1654 'b', MDB_OPT_UINTPTR
, &opt_b
,
1655 'c', MDB_OPT_UINTPTR
, &opt_c
,
1656 'd', MDB_OPT_SETBITS
, TRUE
, &opt_d
,
1657 'H', MDB_OPT_SETBITS
, TRUE
, &opt_H
,
1658 'h', MDB_OPT_SETBITS
, TRUE
, &opt_h
,
1659 'i', MDB_OPT_SETBITS
, TRUE
, &opt_i
,
1660 'o', MDB_OPT_SETBITS
, TRUE
, &opt_o
,
1661 'm', MDB_OPT_SETBITS
, TRUE
, &opt_m
,
1662 'P', MDB_OPT_SETBITS
, TRUE
, &opt_P
,
1663 'p', MDB_OPT_SETBITS
, TRUE
, &opt_p
,
1664 'R', MDB_OPT_SETBITS
, TRUE
, &opt_R
,
1665 'r', MDB_OPT_SETBITS
, TRUE
, &opt_r
,
1666 'V', MDB_OPT_SETBITS
, TRUE
, &opt_V
,
1667 'v', MDB_OPT_SETBITS
, TRUE
, &opt_v
) != argc
)
1668 return (DCMD_USAGE
);
1671 nofilter
= (!OPT_B_SELECTED
&& !opt_d
&& !opt_h
&& !opt_i
&&
1672 !opt_o
&& !opt_m
&& !opt_p
&& !opt_V
&& !opt_B
&&
1673 !opt_P
&& !opt_H
&& !opt_R
&& !opt_r
); /* no options */
1675 if (!(flags
& DCMD_ADDRSPEC
)) {
1676 if (mdb_walk_dcmd("sdbc`sdbc_cctl", "sdbc`sdbc_cctl",
1677 argc
, argv
) == -1) {
1678 mdb_warn("failed to walk 'cctl' list");
1684 if (DCMD_HDRSPEC(flags
)) {
1685 mdb_printf("sdbc cache ctl structures:\n");
1689 if (mdb_vread(¢ry
, sizeof (_sd_cctl_t
), addr
) == -1) {
1690 mdb_warn("dcmd failed to read centry at %p", addr
);
1694 /* filter exclusively on a cd number if specified */
1695 if (OPT_C_SELECTED
&& (centry
.cc_head
.hh_cd
!= opt_c
))
1698 /* all other filters are inclusive */
1700 (OPT_B_SELECTED
&& (centry
.cc_head
.hh_blk_num
== opt_b
)) ||
1701 (opt_B
&& (centry
.cc_aging_dm
&
1702 (BAD_ENTRY_DM
| BAD_CHAIN_DM
))) ||
1703 (opt_d
&& (centry
.cc_dirty
)) ||
1704 (opt_H
&& (centry
.cc_aging_dm
& HOST_ENTRY_DM
)) ||
1705 (opt_h
&& (centry
.cc_head
.hh_hashed
)) ||
1706 (opt_i
&& (centry
.cc_inuse
)) ||
1707 (opt_p
&& (centry
.cc_pageio
)) ||
1708 (opt_P
&& (centry
.cc_aging_dm
& PARASITIC_ENTRY_DM
)) ||
1709 (opt_R
&& (centry
.cc_aging_dm
& PREFETCH_BUF_E
)) ||
1710 (opt_r
&& (centry
.cc_aging_dm
& PREFETCH_BUF_I
)) ||
1711 (opt_V
&& (centry
.cc_valid
)) ||
1712 (opt_m
&& (centry
.cc_alloc_size_dm
)) ||
1713 (opt_o
&& (centry
.cc_iostatus
!= _SD_IO_NONE
)))
1720 "%-?p cd %3-d blk_num %10-d valid %04hx dirty %04hx flag %02x\n",
1721 addr
, centry
.cc_head
.hh_cd
,
1722 centry
.cc_head
.hh_blk_num
, centry
.cc_valid
,
1723 centry
.cc_dirty
, centry
.cc_flag
);
1732 "hashed %d seq %4-d toflush %04hx %8Tawait_use %4-d await_page %4-d\n",
1733 centry
.cc_head
.hh_hashed
, centry
.cc_seq
,
1734 centry
.cc_toflush
, centry
.cc_await_use
,
1735 centry
.cc_await_page
);
1737 mdb_printf("inuse %d pageio %d cc_flag <%b>\n",
1738 centry
.cc_inuse
, centry
.cc_pageio
,
1739 centry
.cc_flag
, cc_flag_bits
);
1741 mdb_printf("iocount %2d iostatus <%b>\n",
1742 centry
.cc_iocount
, centry
.cc_iostatus
, io_status_bits
);
1744 if (mdb_vread(&cc_sync
, sizeof (struct _sd_cctl_sync
),
1745 (uintptr_t)centry
.cc_sync
)
1747 mdb_warn("failed to read cc_sync"); /* not catastophic */
1750 mdb_printf("cc_sync blkcv: %h-x %8Tlock: 0x%p (owner)\n",
1751 cc_sync
._cc_blkcv
._opaque
,
1752 cc_sync
._cc_lock
._opaque
[0]);
1754 mdb_printf("dynamic memory allocation:\n");
1756 mdb_printf("aging_dm age %3d %4Tage flags: <%b> 0x%x\n",
1757 centry
.cc_aging_dm
& 0xff,
1758 centry
.cc_aging_dm
, cc_aging_bits
, centry
.cc_aging_dm
);
1760 mdb_printf("alloc_size_dm %10-d head_dm %?-p\n",
1761 centry
.cc_alloc_size_dm
, centry
.cc_head_dm
);
1762 mdb_printf("next_dm %?-p link_list_dm %?-p\n",
1763 centry
.cc_next_dm
, centry
.cc_link_list_dm
);
1765 mdb_printf("alloc_ct_dm %10-d dealloc_ct_dm %10-d\n",
1766 centry
.cc_alloc_ct_dm
, centry
.cc_dealloc_ct_dm
);
1770 mdb_printf("cctl pointers:\n");
1773 mdb_printf("next %?-p prev %?-p chain %?-p\n",
1774 centry
.cc_next
, centry
.cc_prev
, centry
.cc_chain
);
1775 mdb_printf("dirty_next %?-p dirty_link %?-p\n",
1776 centry
.cc_dirty_next
, centry
.cc_dirty_link
);
1777 mdb_printf("data %?-p write ctl %?-p\n",
1778 centry
.cc_data
, centry
.cc_write
);
1783 mdb_printf("cctl dmqueue index cc_blocks %4-d\n", centry
.cc_cblocks
);
1785 mdb_printf("anon_addr %?-p anon_len %8-d\n",
1786 centry
.cc_anon_addr
.sa_virt
, centry
.cc_anon_len
);
1789 mdb_printf("cctl stats: ");
1791 mdb_printf("hits %8-d creat time %?-p\n", centry
.cc_hits
,
1804 * convenience dcmd to display the _sd_cctl cc_chain list (alloc list)
1805 * Must be called with an address of a cache entry (_sd_cctl_t)
1806 * same options as sdbc_cctl().
1807 * alternatively the user can call the sdbc_cchain walker
1808 * and pipe the addresses to sdbc_cctl dcmd.
1811 sdbc_cchain(uintptr_t addr
, uint_t flags
, int argc
,
1812 const mdb_arg_t
*argv
)
1815 if (!(flags
& DCMD_ADDRSPEC
))
1816 return (DCMD_USAGE
);
1818 if (mdb_pwalk_dcmd("sdbc`sdbc_cchain", "sdbc`sdbc_cctl",
1821 mdb_warn("failed to walk cc_chain at addr %p", addr
);
1830 * convenience dcmd to cdisplay the _sd_cctl dirty chain
1831 * (which is really a 2d chain).
1832 * Must be called with an address of a cache entry (_sd_cctl_t)
1833 * same options as sdbc_cctl().
1834 * alternatively the user can call the sdbc_dchain walker
1835 * and pipe the addresses to sdbc_cctl dcmd.
1838 sdbc_dchain(uintptr_t addr
, uint_t flags
, int argc
,
1839 const mdb_arg_t
*argv
)
1842 if (!(flags
& DCMD_ADDRSPEC
))
1843 return (DCMD_USAGE
);
1845 if (mdb_pwalk_dcmd("sdbc`sdbc_dchain", "sdbc`sdbc_cctl",
1848 mdb_warn("failed to walk dirty chain at addr %p", addr
);
1856 * convenience dcmd to display the _sd_cctl dm chain list
1857 * Must be called with an address of a cache entry (_sd_cctl_t)
1858 * same options as sdbc_cctl().
1859 * alternatively the user can call the sdbc_dmchain walker
1860 * and pipe the addresses to sdbc_cctl dcmd.
1863 sdbc_dmchain(uintptr_t addr
, uint_t flags
, int argc
,
1864 const mdb_arg_t
*argv
)
1867 if (!(flags
& DCMD_ADDRSPEC
))
1868 return (DCMD_USAGE
);
1870 if (mdb_pwalk_dcmd("sdbc`sdbc_dmchain", "sdbc`sdbc_cctl",
1873 mdb_warn("failed to walk dm chain at addr %p", addr
);
1881 * dcmd to walk a hash chain
1882 * requires an address. same options as sdbc_cctl dcmd
1885 sdbc_hashchain(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1887 if (!(flags
& DCMD_ADDRSPEC
))
1888 return (DCMD_USAGE
);
1890 if (mdb_pwalk_dcmd("sdbc`sdbc_hashchain", "sdbc`sdbc_cctl",
1891 argc
, argv
, addr
) == -1) {
1892 mdb_warn("failed to walk hashchain at %p", addr
);
1901 display_hash_table(_sd_hash_table_t
*addr
, _sd_hash_table_t
*ht
)
1903 mdb_printf("hash table (%p):\n", addr
);
1905 mdb_printf("size %7-d bits %2-d mask %8-x nmask %8-x buckets %p\n",
1906 ht
->ht_size
, ht
->ht_bits
, ht
->ht_mask
,
1907 ht
->ht_nmask
, ht
->ht_buckets
);
1912 display_hash_bucket(_sd_hash_bucket_t
*addr
, _sd_hash_bucket_t
*hb
)
1917 if ((rc
= mdb_vread(&lock
, sizeof (kmutex_t
),
1918 (uintptr_t)hb
->hb_lock
)) == -1)
1919 mdb_warn("failed to read bucket lock at %p", hb
->hb_lock
);
1921 mdb_printf("hash bucket (%p):\n", addr
);
1923 mdb_printf("head %?-p tail %?-p lock %?-p %s\n",
1924 hb
->hb_head
, hb
->hb_tail
,
1925 (rc
== -1) ? hb
->hb_lock
: lock
._opaque
[0],
1926 (rc
== -1) ? "" : "(owner)");
1927 mdb_printf("inlist %d seq %d\n", hb
->hb_inlist
, hb
->hb_seq
);
1932 * dcmd to walk the hash table
1933 * defaults to _sd_htable the cache hash table,
1934 * but wil accept an address which is probably only useful
1935 * in the event that other hash tables are implemented in
1938 * calls sdbc_hashchain dcmd. same options as sdbc_cctl dcmd.
1941 sdbc_hashtable(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1943 _sd_hash_table_t
*sd_htable_addr
;
1944 _sd_hash_table_t _sd_htable
;
1945 _sd_hash_bucket_t hash_bucket
;
1950 if (!(flags
& DCMD_ADDRSPEC
)) {
1951 /* get the address of the standard cache hash table */
1952 if (mdb_readvar(&sd_htable_addr
, "_sd_htable") == -1) {
1953 mdb_warn("failed to read _sd_htable address\n");
1957 sd_htable_addr
= (_sd_hash_table_t
*)addr
;
1959 /* read in the hash table structure */
1960 if (mdb_vread(&_sd_htable
, sizeof (_sd_hash_table_t
),
1961 (uintptr_t)sd_htable_addr
) == -1) {
1962 mdb_warn("failed to read _sd_htable structure at %p\n",
1967 display_hash_table(sd_htable_addr
, &_sd_htable
);
1970 * read in the hash buckets
1971 * and display chains if there are any
1973 for (i
= 0; i
< _sd_htable
.ht_size
; ++i
) {
1974 if (mdb_vread(&hash_bucket
, sizeof (_sd_hash_bucket_t
),
1975 (uintptr_t)(_sd_htable
.ht_buckets
+ i
)) == -1) {
1976 mdb_warn("failed to read ht_buckets at %p\n",
1977 _sd_htable
.ht_buckets
+ i
);
1981 if (hash_bucket
.hb_head
!= NULL
) {
1982 display_hash_bucket(_sd_htable
.ht_buckets
+ i
,
1985 * if this walk fails, continue trying
1986 * to read hash buckets
1988 if (mdb_call_dcmd("sdbc`sdbc_hashchain",
1989 (uintptr_t)hash_bucket
.hb_head
,
1990 flags
|DCMD_ADDRSPEC
, argc
, argv
)
1993 "failed to walk hash chain at %p",
1994 hash_bucket
.hb_head
);
2002 * dcmd to display the sdbc lru queue
2003 * same options as sdbc_cctl().
2004 * alternatively the user can call the sdbc_lru walker
2005 * and pipe the addresses to sdbc_cctl dcmd.
2008 sdbc_lru(uintptr_t addr
, uint_t flags
, int argc
,
2009 const mdb_arg_t
*argv
)
2011 _sd_queue_t _sd_lru_q
;
2014 if (!(flags
& DCMD_ADDRSPEC
)) {
2015 if (mdb_lookup_by_obj("sdbc", "_sd_lru_q", &sym
) == -1) {
2016 mdb_warn("failed to lookup _sd_lru_q symbol");
2020 if (mdb_vread(&_sd_lru_q
, sizeof (_sd_queue_t
),
2021 sym
.st_value
) == -1) {
2022 mdb_warn("failed to read _sd_lru_q structure");
2026 mdb_printf("Cache LRU Queue\n");
2029 "qlock: 0x%-p (owner) await %d seq %d inq %d req %d noreq %d\n",
2030 _sd_lru_q
.sq_qlock
._opaque
[0],
2034 _sd_lru_q
.sq_req_stat
,
2035 _sd_lru_q
.sq_noreq_stat
);
2037 addr
= (uintptr_t)(sym
.st_value
);
2040 if (mdb_pwalk_dcmd("sdbc`sdbc_lru", "sdbc`sdbc_cctl",
2041 argc
, argv
, addr
) == -1) {
2042 mdb_warn("failed to walk lru at addr %p", addr
);
2051 print_wrq(_sd_writeq_t
*wrq
, uint_t verbose
)
2055 mdb_printf("Cache Write Ctl Queue:\n");
2057 mdb_printf("qtop %-p qlock: %-p (owner) inq %d\n",
2059 wrq
->wq_qlock
._opaque
[0],
2062 mdb_printf("slp_top %3-d slp_index %3-d slp_inq %3-d\n",
2067 for (i
= 0; verbose
&& i
< SD_WR_SLP_Q_MAX
; i
+= 2) {
2068 mdb_printf("%3d: cv %h-x wq_need %3-d wq_held %3-d%4T",
2070 wrq
->wq_slp
[i
].slp_wqcv
._opaque
,
2071 wrq
->wq_slp
[i
].slp_wqneed
,
2072 wrq
->wq_slp
[i
].slp_wqheld
);
2073 if (SD_WR_SLP_Q_MAX
> (i
+ 1)) {
2075 "%3d: cv %h-x wq_need %3-d wq_held %3-d%\n",
2077 wrq
->wq_slp
[i
+1].slp_wqcv
._opaque
,
2078 wrq
->wq_slp
[i
+1].slp_wqneed
,
2079 wrq
->wq_slp
[i
+1].slp_wqheld
);
2086 * dcmd to display write control structures
2090 sdbc_wctl(uintptr_t addr
, uint_t flags
, int argc
,
2091 const mdb_arg_t
*argv
)
2094 ss_centry_info_t gl_info
;
2095 ss_centry_info_t nv_gl_info
;
2096 uintptr_t opt_c
= MDB_CD
;
2097 uint_t opt_d
= FALSE
;
2098 uint_t opt_v
= FALSE
;
2101 /* TODO option for fba pos */
2102 if (mdb_getopts(argc
, argv
,
2103 'd', MDB_OPT_SETBITS
, TRUE
, &opt_d
,
2104 'c', MDB_OPT_UINTPTR
, &opt_c
,
2105 'v', MDB_OPT_SETBITS
, TRUE
, &opt_v
) != argc
)
2106 return (DCMD_USAGE
);
2109 if (!(flags
& DCMD_ADDRSPEC
)) {
2110 if (mdb_walk_dcmd("sdbc`sdbc_wctl", "sdbc`sdbc_wctl",
2111 argc
, argv
) == -1) {
2112 mdb_warn("failed to walk write ctl array");
2118 if (DCMD_HDRSPEC(flags
)) {
2119 mdb_printf("write control block structures:\n");
2122 if (mdb_vread(&wctl
, sizeof (_sd_wr_cctl_t
), addr
) == -1) {
2123 mdb_warn("failed to read wctl at 0x%p", addr
);
2129 * print "all" is the default.
2130 * filter conditions can only be checked by reading in wc_gl_info
2132 if (opt_c
|| opt_d
|| opt_v
)
2133 if (mdb_vread(&gl_info
, sizeof (ss_centry_info_t
),
2134 (uintptr_t)wctl
.wc_gl_info
) == -1) {
2135 mdb_warn("failed to read at wc_gl_info 0x%p", addr
);
2140 if (OPT_C_SELECTED
&& (gl_info
.gl_cd
!= opt_c
))
2143 if (opt_d
&& !(gl_info
.gl_dirty
))
2147 mdb_printf("%-p data %-p gl_info %-p Ngl_info %-p flg %02x\n",
2151 wctl
.wc_nvmem_gl_info
,
2160 mdb_printf("next %?-p prev %?-p\n", wctl
.wc_next
, wctl
.wc_prev
);
2161 mdb_printf(" gl_info: ");
2162 mdb_printf("cd %3-d fpos %10-d dirty %04x flag <%b>\n",
2163 gl_info
.gl_cd
, gl_info
.gl_fpos
, gl_info
.gl_dirty
& 0xffff,
2164 gl_info
.gl_flag
, cc_flag_bits
);
2166 if (wctl
.wc_nvmem_gl_info
) {
2167 if (mdb_vread(&nv_gl_info
, sizeof (ss_centry_info_t
),
2168 (uintptr_t)wctl
.wc_nvmem_gl_info
) == -1) {
2169 mdb_warn("failed to read at wc_nvmem_gl_info 0x%p",
2170 wctl
.wc_nvmem_gl_info
); /* not catastophic, continue */
2173 /* consistency check */
2174 if (memcmp(&gl_info
, &nv_gl_info
,
2175 sizeof (ss_centry_info_t
) != 0)) {
2176 mdb_warn("nvram and host memory are NOT identical!");
2177 mdb_printf("nvmem_gl_info: ");
2178 mdb_printf("cd %3-d fpos %10-d dirty %04x flag <%b>\n",
2179 nv_gl_info
.gl_cd
, nv_gl_info
.gl_fpos
,
2180 nv_gl_info
.gl_dirty
& 0xffff,
2181 nv_gl_info
.gl_flag
, cc_flag_bits
);
2193 * dcmd to display write control structures in the free list
2194 * same options as sdbc_wctl
2198 sdbc_wrq(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
2200 _sd_net_t _sd_net_config
;
2201 uintptr_t opt_c
= MDB_CD
;
2202 uint_t opt_d
= FALSE
;
2203 uint_t opt_v
= FALSE
;
2206 /* look for verbose option */
2207 if (mdb_getopts(argc
, argv
,
2208 'd', MDB_OPT_SETBITS
, TRUE
, &opt_d
,
2209 'c', MDB_OPT_UINTPTR
, &opt_c
,
2210 'v', MDB_OPT_SETBITS
, TRUE
, &opt_v
) != argc
)
2211 return (DCMD_USAGE
);
2213 if (!(flags
& DCMD_ADDRSPEC
)) {
2214 if (mdb_readvar(&_sd_net_config
, "_sd_net_config") == -1) {
2215 mdb_warn("failed to read _sd_net_config structure");
2219 print_wrq(&(_sd_net_config
.sn_wr_queue
), opt_v
);
2221 addr
= (uintptr_t)(_sd_net_config
.sn_wr_queue
.wq_qtop
);
2224 if (mdb_pwalk_dcmd("sdbc`sdbc_wrq", "sdbc`sdbc_wctl",
2225 argc
, argv
, addr
) == -1) {
2226 mdb_warn("failed to walk write ctl queue at addr %p", addr
);
2234 * dcmd to display the dm queues
2235 * use sdbc_lru walker to walk each queue.
2239 sdbc_dmqueues(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
2241 _sd_queue_t
*sdbc_dm_queues
; /* kernel address of dm queues */
2243 _sd_queue_t
*queues
= NULL
; /* local copy */
2248 return (DCMD_USAGE
);
2250 if (!(flags
& DCMD_ADDRSPEC
)) {
2251 if (mdb_readvar(&sdbc_dm_queues
, "sdbc_dm_queues") == -1) {
2252 mdb_warn("failed to read sdbc_dm_queues address\n");
2256 if (mdb_readvar(&max_dm_queues
, "max_dm_queues") == -1) {
2257 mdb_warn("failed to read max_dm_queues variable\n");
2261 queues
= mdb_zalloc(max_dm_queues
* sizeof (_sd_queue_t
),
2263 mdb_printf("max_dm_queues %d sdbc_dm_queues %p queues %p\n",
2264 max_dm_queues
, sdbc_dm_queues
, queues
);
2266 if (mdb_vread(queues
, max_dm_queues
* sizeof (_sd_queue_t
),
2267 (uintptr_t)sdbc_dm_queues
) == -1) {
2268 mdb_warn("failed to read sdbc_dm_queues");
2272 for (i
= 0; i
< max_dm_queues
; ++i
) {
2273 mdb_printf("Cache DM Queue %d %p\n",
2274 queues
[i
].sq_dmchain_cblocks
,
2277 mdb_printf("qlock: 0x%-p (owner) await %d "
2278 "seq %d inq %d req %d noreq %d\n",
2279 queues
[i
].sq_qlock
._opaque
[0],
2283 queues
[i
].sq_req_stat
,
2284 queues
[i
].sq_noreq_stat
);
2294 mdb_bitmask_t cd_writer_bits
[] = {
2295 { "NONE ", (u_longlong_t
)~0, _SD_WRITER_NONE
},
2296 { "CREATE ", (u_longlong_t
)~0, _SD_WRITER_CREATE
},
2297 { "RUNNING", (u_longlong_t
)~0, _SD_WRITER_RUNNING
},
2301 mdb_bitmask_t sh_failed_status
[] = {
2302 { "STATUS OK", (u_longlong_t
)~0, 0 },
2303 { "I/O ERROR", (u_longlong_t
)~0, 1 },
2304 { "OPEN FAIL", (u_longlong_t
)~0, 2 },
2308 mdb_bitmask_t sh_flag_bits
[] = {
2309 { "ATTACHED", CD_ATTACHED
, CD_ATTACHED
},
2313 mdb_bitmask_t sh_alloc_bits
[] = {
2314 { "ALLOC_IN_PROGRESS", CD_ALLOC_IN_PROGRESS
, CD_ALLOC_IN_PROGRESS
},
2315 { "ALLOCATED", CD_ALLOCATED
, CD_ALLOCATED
},
2316 { "CLOSE_IN_PROGRESS", CD_CLOSE_IN_PROGRESS
, CD_CLOSE_IN_PROGRESS
},
2321 * dcmd to display cd information
2324 sdbc_cdinfo(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
2326 _sd_shared_t sd_shared
;
2328 ss_voldata_t gl_file
;
2329 char *fn
= "nopath"; /* filename if sd_shared info cannot be read */
2330 uchar_t sh_alloc
= 0; /* assume not alloc'd if sd_shared info unavail */
2331 uintptr_t opt_c
= MDB_CD
;
2332 uint_t opt_a
= FALSE
;
2333 uint_t opt_v
= FALSE
;
2336 dev_t_chars
= sizeof (dev_t
) * 2; /* # chars to display dev_t */
2339 if (mdb_getopts(argc
, argv
,
2340 'a', MDB_OPT_SETBITS
, TRUE
, &opt_a
,
2341 'c', MDB_OPT_UINTPTR
, &opt_c
,
2342 'v', MDB_OPT_SETBITS
, TRUE
, &opt_v
) != argc
)
2343 return (DCMD_USAGE
);
2345 if (!(flags
& DCMD_ADDRSPEC
)) {
2346 if (mdb_walk_dcmd("sdbc`sdbc_cdinfo", "sdbc`sdbc_cdinfo",
2347 argc
, argv
) == -1) {
2348 mdb_warn("failed to walk cd info array");
2354 if (DCMD_HDRSPEC(flags
)) {
2355 mdb_printf("cd info structures:\n");
2358 if (mdb_vread(&cdi
, sizeof (_sd_cd_info_t
), addr
) == -1) {
2359 mdb_warn("failed to read cd info at 0x%p", addr
);
2364 * need to do this read even for non-verbose option to
2365 * get the filename and the sh_alloc field
2368 if (mdb_vread(&sd_shared
, sizeof (_sd_shared_t
),
2369 (uintptr_t)cdi
.cd_info
) == -1) {
2370 mdb_warn("failed to read shared cd info at 0x%p",
2372 /* not catastrophic, keep truckin' */
2374 fn
= sd_shared
.sh_filename
;
2375 sh_alloc
= sd_shared
.sh_alloc
;
2379 if (!opt_a
&& (sh_alloc
== 0))
2382 if (OPT_C_SELECTED
&& (opt_c
!= cdi
.cd_desc
))
2386 mdb_printf("%p cd %3-d filename %s\n",
2387 addr
, cdi
.cd_desc
, fn
);
2388 mdb_printf("alloc <%b> hint <%b>\n",
2389 sh_alloc
, sh_alloc_bits
,
2390 cdi
.cd_hint
, cache_hints
);
2398 mdb_printf("rawfd %?-p crdev %0*lx iodev %?-p\n",
2403 mdb_printf("flag %x %8Tlock %?-p writer <%b>\n",
2405 cdi
.cd_lock
._opaque
[0],
2406 cdi
.cd_writer
, cd_writer_bits
);
2407 mdb_printf("global %?-p dirty_head %?-p\n",
2408 cdi
.cd_global
, cdi
.cd_dirty_head
);
2409 mdb_printf("last_ent %?-p lastchain_ptr %?-p lastchain %d\n",
2410 cdi
.cd_last_ent
, cdi
.cd_lastchain_ptr
,
2412 mdb_printf("io_head %?-p io_tail %?-p fail_head %?-p\n",
2413 cdi
.cd_io_head
, cdi
.cd_io_tail
, cdi
.cd_fail_head
);
2415 "cd_info %?-p failover %d recovering %d write_inprogress %d\n",
2416 cdi
.cd_info
, cdi
.cd_failover
,
2418 cdi
.cd_write_inprogress
);
2420 if (cdi
.cd_global
!= NULL
) {
2421 if (mdb_vread(&gl_file
, sizeof (ss_voldata_t
),
2422 (uintptr_t)cdi
.cd_global
) == -1)
2423 mdb_warn("failed to read cd_global at %p",
2426 mdb_printf("cd_global: %s\n", gl_file
.sv_volname
);
2427 mdb_printf("pinned %2-d attached %2-d devidsz %3-d\n",
2428 gl_file
.sv_pinned
, gl_file
.sv_attached
,
2429 gl_file
.sv_devidsz
);
2430 mdb_printf("devid %s\n", gl_file
.sv_devid
);
2431 mdb_printf("vol %?p\n", gl_file
.sv_vol
);
2433 /* TODO do a consistency check here against the nvram copy */
2436 if (cdi
.cd_info
== NULL
) {
2437 mdb_printf("no shared info\n");
2439 mdb_printf("shared:\n");
2440 mdb_printf("failed <%b> cd %3-d",
2441 sd_shared
.sh_failed
, sh_failed_status
,
2443 mdb_printf("cache_read %10-d cache_write %10-d\n",
2444 sd_shared
.sh_cache_read
, sd_shared
.sh_cache_write
);
2445 mdb_printf("disk_read %10-d disk_write %10-d filesize %10-d\n",
2446 sd_shared
.sh_disk_read
, sd_shared
.sh_disk_write
,
2447 sd_shared
.sh_filesize
);
2448 mdb_printf("numdirty %8-d numio %8-d numfail %8-d\n",
2449 sd_shared
.sh_numdirty
,
2451 sd_shared
.sh_numfail
);
2452 mdb_printf("flushloop %2-d sh_flag <%b>\n",
2453 sd_shared
.sh_flushloop
, sd_shared
.sh_flag
, sh_flag_bits
);
2455 /* this can be really verbose */
2456 if (cdi
.cd_dirty_head
) {
2457 mdb_printf("Dirty Chain (cd_dirty_head):");
2458 /* TODO reconstruct argv without opt_a */
2460 mdb_call_dcmd("sdbc_dchain",
2461 (uintptr_t)cdi
.cd_dirty_head
,
2463 else /* print with no options */
2464 mdb_call_dcmd("sdbc_dchain",
2465 (uintptr_t)cdi
.cd_dirty_head
,
2469 if (cdi
.cd_io_head
) {
2470 mdb_printf("I/O Pending Chain (cd_io_head):");
2471 /* TODO reconstruct argv without opt_a */
2473 mdb_call_dcmd("sdbc_dchain",
2474 (uintptr_t)cdi
.cd_io_head
,
2476 else /* print with no options */
2477 mdb_call_dcmd("sdbc_dchain",
2478 (uintptr_t)cdi
.cd_dirty_head
,
2482 if (cdi
.cd_fail_head
) {
2483 mdb_printf("Failed Chain (cd_fail_head):");
2484 /* TODO reconstruct argv without opt_a */
2486 mdb_call_dcmd("sdbc_dchain",
2487 (uintptr_t)cdi
.cd_fail_head
,
2489 else /* print with no options */
2490 mdb_call_dcmd("sdbc_dchain",
2491 (uintptr_t)cdi
.cd_dirty_head
,
2505 * dcmd to display fault tolerant control structures
2508 sdbc_ftctl(uintptr_t addr
, uint_t flags
, int argc
,
2509 const mdb_arg_t
*argv
)
2511 _sd_ft_cctl_t ft_cent
;
2512 ss_centry_info_t gl_info
;
2513 ss_centry_info_t nv_gl_info
;
2514 uintptr_t opt_c
= MDB_CD
;
2515 uint_t opt_d
= FALSE
;
2516 uint_t opt_v
= FALSE
;
2519 /* TODO option to select on fpos */
2520 if (mdb_getopts(argc
, argv
,
2521 'd', MDB_OPT_SETBITS
, TRUE
, &opt_d
,
2522 'c', MDB_OPT_UINTPTR
, &opt_c
,
2523 'v', MDB_OPT_SETBITS
, TRUE
, &opt_v
) != argc
)
2524 return (DCMD_USAGE
);
2527 if (!(flags
& DCMD_ADDRSPEC
)) {
2528 if (mdb_walk_dcmd("sdbc`sdbc_ftctl", "sdbc`sdbc_ftctl",
2529 argc
, argv
) == -1) {
2530 mdb_warn("failed to walk write ctl array");
2536 if (DCMD_HDRSPEC(flags
)) {
2537 mdb_printf("Ft control block structures:\n");
2540 if (mdb_vread(&ft_cent
, sizeof (_sd_ft_cctl_t
), addr
) == -1) {
2541 mdb_warn("failed to read ft_cent at 0x%p", addr
);
2547 * print "all" is the default.
2548 * filter conditions can only be checked by reading in wc_gl_info
2550 if (opt_c
|| opt_d
|| opt_v
)
2551 if (mdb_vread(&gl_info
, sizeof (ss_centry_info_t
),
2552 (uintptr_t)ft_cent
.ft_gl_info
) == -1) {
2553 mdb_warn("failed to read at wc_gl_info 0x%p", addr
);
2558 if (OPT_C_SELECTED
&& (gl_info
.gl_cd
!= opt_c
))
2561 if (opt_d
&& !(gl_info
.gl_dirty
))
2565 mdb_printf("%-p data %?-p qnext %?-p\n",
2569 mdb_printf("gl_info %?-p nvmem_gl_info %?-p\n",
2571 ft_cent
.ft_nvmem_gl_info
);
2581 mdb_printf(" gl_info: ");
2582 mdb_printf("cd %3-d fpos %10-d dirty %04x flag <%b>\n",
2583 gl_info
.gl_cd
, gl_info
.gl_fpos
, gl_info
.gl_dirty
& 0xffff,
2584 gl_info
.gl_flag
, cc_flag_bits
);
2586 if (ft_cent
.ft_nvmem_gl_info
) {
2587 if (mdb_vread(&nv_gl_info
, sizeof (ss_centry_info_t
),
2588 (uintptr_t)ft_cent
.ft_nvmem_gl_info
) == -1) {
2589 mdb_warn("failed to read at ft_nvmem_gl_info 0x%p",
2590 ft_cent
.ft_nvmem_gl_info
); /* not catastophic, continue */
2592 mdb_printf("nvmem_gl_info: ");
2593 mdb_printf("cd %3-d fpos %10-d dirty %04x flag <%b>\n",
2594 nv_gl_info
.gl_cd
, nv_gl_info
.gl_fpos
,
2595 nv_gl_info
.gl_dirty
& 0xffff,
2596 nv_gl_info
.gl_flag
, cc_flag_bits
);
2598 /* consistency check */
2599 if (memcmp(&gl_info
, &nv_gl_info
, sizeof (ss_centry_info_t
))
2601 mdb_warn("nvram and host memory are NOT identical!");
2611 #endif /* SAFESTORE */
2614 /* dcmd to display buffer handles */
2616 sdbc_handles(uintptr_t addr
, uint_t flags
, int argc
,
2617 const mdb_arg_t
*argv
)
2619 uint_t opt_a
= FALSE
;
2620 uintptr_t opt_c
= MDB_CD
;
2621 uint_t opt_v
= FALSE
;
2622 uint_t opt_C
= FALSE
;
2624 _sd_buf_handle_t bh
;
2627 if (mdb_getopts(argc
, argv
,
2628 'a', MDB_OPT_SETBITS
, TRUE
, &opt_a
,
2629 'c', MDB_OPT_UINTPTR
, &opt_c
,
2630 'C', MDB_OPT_SETBITS
, TRUE
, &opt_C
,
2631 'v', MDB_OPT_SETBITS
, TRUE
, &opt_v
) != argc
)
2632 return (DCMD_USAGE
);
2635 if (mdb_readvar(&hl
, "_sd_handle_list") == -1) {
2636 mdb_warn("failed to read _sd_handle_list structure");
2641 if (!(flags
& DCMD_ADDRSPEC
)) {
2642 if (mdb_walk_dcmd("sdbc`sdbc_handles", "sdbc`sdbc_handles",
2643 argc
, argv
) == -1) {
2644 mdb_warn("failed to walk 'sdbc_handle_list'");
2650 if (DCMD_HDRSPEC(flags
)) {
2651 mdb_printf("Handle List Info:\n");
2654 mdb_printf("hl_top.bh_next: 0x%p\n", hl
.hl_top
.bh_next
);
2655 mdb_printf("hl_lock: 0x%p (owner)\n", hl
.hl_lock
._opaque
[0]);
2656 mdb_printf("hl_count: %hd\n", hl
.hl_count
);
2658 mdb_printf("buf handles:\n");
2661 if (mdb_vread(&bh
, sizeof (bh
), addr
) == -1) {
2662 mdb_warn("failed to read buf handle at 0x%p", addr
);
2666 if (!opt_a
&& !(bh
.bh_flag
& (NSC_HALLOCATED
| NSC_HACTIVE
)))
2670 * may get false matches on cd option --
2671 * a cleared bh_cd field will match if user specified cd 0
2673 if (OPT_C_SELECTED
&& (bh
.bh_cd
!= opt_c
))
2677 mdb_printf("%p %8T cd %3-d %4T<%b> %x\n", addr
, bh
.bh_cd
,
2678 bh
.bh_flag
, nsc_buf_bits
, bh
.bh_flag
);
2680 /* check for verbose, avoid printing twice */
2681 if (!opt_v
&& opt_C
) {
2682 mdb_printf("cc_chain: ");
2684 mdb_call_dcmd("sdbc`sdbc_cchain",
2685 (uintptr_t)bh
.bh_centry
, DCMD_ADDRSPEC
, 0, NULL
);
2696 mdb_printf("callbacks: %-20a%-20a%-20a\n",
2697 bh
.bh_disconnect_cb
, bh
.bh_read_cb
, bh
.bh_write_cb
);
2699 mdb_printf("centry %?p %8T next %?p\n",
2700 bh
.bh_centry
, bh
.bh_next
);
2701 mdb_printf("buffer:\n");
2704 mdb_printf("fd 0x%p pos %10d len %6d flag 0x%x\n",
2705 bh
.bh_buf
.sb_fd
, bh
.bh_fba_pos
, bh
.bh_fba_len
, bh
.bh_flag
);
2707 mdb_printf("alloc_thread %p busy_thread %p\n", bh
.bh_alloc_thread
,
2710 mdb_printf("err %4d %8T bh_vec 0x%p\n", bh
.bh_error
, bh
.bh_vec
);
2713 mdb_printf("bufvec (scatter gather list): %-?s %8T%-s\n",
2716 _sd_bufvec_t
*bv
, *endvec
;
2719 /* todo check for (bh_vec != bh_bufvec) => readahead? */
2722 endvec
= bv
+ _SD_MAX_BLKS
;
2724 while (bv
->bufaddr
) {
2725 mdb_printf("%p %8T%d\n", bv
->bufaddr
, bv
->buflen
);
2728 mdb_warn("END of bh_bufvec ARRAY");
2736 mdb_printf("cc_chain: ");
2738 mdb_call_dcmd("sdbc`sdbc_cchain",
2739 (uintptr_t)bh
.bh_centry
, DCMD_ADDRSPEC
, 0, NULL
);
2748 * dcmd to display ss_centry_info_t structures and
2749 * do optional consistency check with the nvram copy
2750 * if configured for nvram safe storage.
2754 sdbc_glcinfo(uintptr_t addr
, uint_t flags
, int argc
,
2755 const mdb_arg_t
*argv
)
2757 ss_centry_info_t gl_centry_info
;
2758 /* for doing consistency check */
2760 ss_centry_info_t
*gl_centry_info_start
;
2761 ss_centry_info_t
*nv_gl_centry_info_start
;
2763 ss_centry_info_t nv_gl_centry_info
;
2766 uint_t opt_a
= FALSE
;
2767 uintptr_t opt_b
= MDB_BLKNUM
; /* fba pos match */
2768 uintptr_t opt_c
= MDB_CD
;
2769 uintptr_t opt_C
= FALSE
; /* consistency check */
2770 uint_t opt_d
= FALSE
;
2774 if (mdb_getopts(argc
, argv
,
2775 'a', MDB_OPT_SETBITS
, TRUE
, &opt_a
,
2776 'b', MDB_OPT_UINTPTR
, &opt_b
,
2777 'c', MDB_OPT_UINTPTR
, &opt_c
,
2778 'C', MDB_OPT_SETBITS
, TRUE
, &opt_C
,
2779 'd', MDB_OPT_SETBITS
, TRUE
, &opt_d
) != argc
)
2780 return (DCMD_USAGE
);
2783 if (!(flags
& DCMD_ADDRSPEC
)) {
2784 if (mdb_walk_dcmd("sdbc`sdbc_glcinfo", "sdbc`sdbc_glcinfo",
2785 argc
, argv
) == -1) {
2786 mdb_warn("failed to walk global centry info array");
2792 if (DCMD_HDRSPEC(flags
)) {
2793 mdb_printf("global cache entry info:\n");
2796 if (mdb_vread(&gl_centry_info
, sizeof (ss_centry_info_t
), addr
) == -1) {
2797 mdb_warn("failed to read gl_centry_info at 0x%p", addr
);
2803 * default is to print entries initialized with a cd. return if
2804 * no options are selected and cd is invalid.
2806 if (!opt_a
&& (!OPT_B_SELECTED
) && (!OPT_C_SELECTED
) && !opt_d
&&
2807 (gl_centry_info
.sc_cd
== -1))
2812 * opt_c is exclusive filter. if opt_c is selected and there
2813 * is no match on the cd then return
2816 (OPT_C_SELECTED
&& (gl_centry_info
.sc_cd
!= opt_c
)))
2820 * opt_d and opt_b are inclusive. print if either one is chosen
2821 * and the selection condition is true.
2824 (!opt_d
&& (!OPT_B_SELECTED
)) || /* no options chosen */
2825 (opt_d
&& gl_centry_info
.sc_dirty
) ||
2826 (OPT_B_SELECTED
&& (gl_centry_info
.sc_fpos
== opt_b
)))
2832 mdb_printf("%?-p cd %3-d fpos %10-d dirty %04x flag <%b>\n",
2834 gl_centry_info
.sc_cd
,
2835 gl_centry_info
.sc_fpos
,
2836 gl_centry_info
.sc_dirty
& 0xffff,
2837 gl_centry_info
.sc_flag
, cc_flag_bits
);
2840 /* get start of the cache entry metadata */
2841 if (mdb_readvar(&gl_centry_info_start
,
2842 "_sdbc_gl_centry_info") == -1) {
2843 mdb_warn("failed to read _sdbc_gl_centry_info");
2844 /* not catastrophic */
2848 /* get start of the nvram copy cache entry metadata */
2849 if (mdb_readvar(&nv_gl_centry_info_start
,
2850 "_sdbc_gl_centry_info_nvmem") == -1) {
2851 mdb_warn("failed to read _sdbc_gl_centry_info_nvmem");
2852 /* not catastrophic */
2856 nv_addr
= (addr
- (uintptr_t)gl_centry_info_start
) +
2857 (uintptr_t)nv_gl_centry_info_start
;
2859 if (mdb_vread(&nv_gl_centry_info
, sizeof (ss_centry_info_t
),
2861 mdb_warn("failed to read at nvmem_gl_info 0x%p",
2863 /* not catastophic, continue */
2866 /* consistency check */
2868 if (memcmp(&gl_centry_info
, &nv_gl_centry_info
,
2869 sizeof (ss_centry_info_t
) != 0)) {
2871 "nvram and host memory are NOT identical!");
2872 mdb_printf("nvmem_gl_centry_info: ");
2874 "%?-p cd %3-d fpos %10-d dirty %04x flag <%b>\n",
2876 nv_gl_centry_info
.sc_cd
,
2877 nv_gl_centry_info
.sc_fpos
,
2878 nv_gl_centry_info
.sc_dirty
& 0xffff,
2879 nv_gl_centry_info
.sc_flag
, cc_flag_bits
);
2882 mdb_printf("NVRAM ok\n");
2895 * dcmd to display ss_voldata_t structures and
2896 * do optional consistency check with the nvram copy
2897 * if configured for nvram safe storage.
2901 sdbc_glfinfo(uintptr_t addr
, uint_t flags
, int argc
,
2902 const mdb_arg_t
*argv
)
2904 ss_voldata_t gl_file_info
;
2905 /* for doing consistency check */
2907 ss_voldata_t
*gl_file_info_start
;
2908 ss_voldata_t
*nv_gl_file_info_start
;
2910 ss_voldata_t nv_gl_file_info
;
2912 /* options default: valid filename */
2913 uint_t opt_a
= FALSE
; /* all */
2914 uint_t opt_p
= FALSE
; /* PINNED */
2915 uint_t opt_t
= FALSE
; /* attached */
2916 uint_t opt_C
= FALSE
; /* consistency check */
2921 * possible enhancement -- match on filename,
2922 * or filename part (e.g. controller number)
2924 if (mdb_getopts(argc
, argv
,
2925 'a', MDB_OPT_SETBITS
, TRUE
, &opt_a
,
2926 'C', MDB_OPT_SETBITS
, TRUE
, &opt_C
,
2927 'p', MDB_OPT_SETBITS
, TRUE
, &opt_p
,
2928 't', MDB_OPT_SETBITS
, TRUE
, &opt_t
) != argc
)
2929 return (DCMD_USAGE
);
2932 if (!(flags
& DCMD_ADDRSPEC
)) {
2933 if (mdb_walk_dcmd("sdbc`sdbc_glfinfo", "sdbc`sdbc_glfinfo",
2934 argc
, argv
) == -1) {
2935 mdb_warn("failed to walk global file info array");
2941 if (DCMD_HDRSPEC(flags
)) {
2942 mdb_printf("global file entry info:\n");
2945 if (mdb_vread(&gl_file_info
, sizeof (ss_voldata_t
), addr
) == -1) {
2946 mdb_warn("failed to read gl_file_info at 0x%p", addr
);
2952 * default is to print entries initialized with non-null filename.
2953 * return if no options are selected and filename is invalid.
2955 if (!opt_a
&& !opt_p
&& !opt_t
&&
2956 (strlen(gl_file_info
.sv_volname
) == 0))
2961 (!opt_p
&& !opt_t
) || /* no options chosen */
2962 (opt_p
&& (gl_file_info
.sv_pinned
!= _SD_NO_HOST
)) ||
2963 (opt_t
&& (gl_file_info
.sv_attached
!= _SD_NO_HOST
)))
2969 mdb_printf("%?-p %s\n", addr
, gl_file_info
.sv_volname
);
2970 mdb_printf("pinned %2-d attached %2-d devidsz %3-d\n",
2971 gl_file_info
.sv_pinned
,
2972 gl_file_info
.sv_attached
,
2973 gl_file_info
.sv_devidsz
);
2974 mdb_printf("devid %s\n", gl_file_info
.sv_devid
);
2977 /* get start of the cache entry metadata */
2978 if (mdb_readvar(&gl_file_info_start
,
2979 "_sdbc_gl_file_info") == -1) {
2980 mdb_warn("failed to read _sdbc_gl_file_info");
2981 /* not catastrophic */
2985 /* get start of the nvram copy cache entry metadata */
2986 if (mdb_readvar(&nv_gl_file_info_start
,
2987 "_sdbc_gl_file_info_nvmem") == -1) {
2988 mdb_warn("failed to read _sdbc_gl_file_info_nvmem");
2989 /* not catastrophic */
2993 nv_addr
= (addr
- (uintptr_t)gl_file_info_start
) +
2994 (uintptr_t)nv_gl_file_info_start
;
2996 if (mdb_vread(&nv_gl_file_info
, sizeof (ss_voldata_t
),
2998 mdb_warn("failed to read nvmem_gl_info at 0x%p",
3000 /* not catastophic, continue */
3003 /* consistency check */
3005 if (memcmp(&gl_file_info
, &nv_gl_file_info
,
3006 sizeof (ss_centry_info_t
) != 0)) {
3007 mdb_warn("nvram and host memory are NOT identical!");
3008 mdb_printf("nvmem_gl_file_info: ");
3009 mdb_printf("%?-p %s\n", nv_addr
,
3010 nv_gl_file_info
.sv_volname
);
3011 mdb_printf("pinned %2-d attached %2-d devidsz %3-d\n",
3012 nv_gl_file_info
.sv_pinned
,
3013 nv_gl_file_info
.sv_attached
,
3014 nv_gl_file_info
.sv_devidsz
);
3015 mdb_printf("devid %s\n", nv_gl_file_info
.sv_devid
);
3017 mdb_printf("NVRAM ok\n");
3032 * MDB module linkage information:
3034 * We declare a list of structures describing our dcmds, and a function
3035 * named _mdb_init to return a pointer to our module information.
3038 static const mdb_dcmd_t dcmds
[] = {
3040 { "sdbc_config", NULL
,
3041 "display sdbc configuration information",
3043 { "sdbc_stats", NULL
,
3044 "display sdbc stats information",
3046 { "sdbc_vars", NULL
,
3047 "display some sdbc variables, counters and addresses",
3051 {"sdbc_cctl", "?[-vdhioV][-c cd][-b blknum]",
3052 "display sdbc cache ctl structures",
3053 sdbc_cctl
, cctl_help
},
3054 {"sdbc_cchain", ":[-vdhioV][-c cd][-b blknum]",
3055 "display cache ctl structure cc_chain",
3056 sdbc_cchain
, cchain_help
},
3057 {"sdbc_dchain", ":[-vdhioV][-c cd][-b blknum]",
3058 "display cache ctl structure dirty chain",
3059 sdbc_dchain
, dchain_help
},
3060 {"sdbc_dmchain", ":[-vdhioV][-c cd][-b blknum]",
3061 "display dynamic memory cache ctl chain",
3062 sdbc_dmchain
, dmchain_help
},
3063 {"sdbc_hashchain", ":[-vdhioV][-c cd][-b blknum]",
3064 "display a hash chain", sdbc_hashchain
, hashchain_help
},
3065 {"sdbc_hashtable", "?[-vdhioV][-c cd][-b blknum]",
3066 "display hash table", sdbc_hashtable
, hashtable_help
},
3067 {"sdbc_lru", "?[-vdhioV][-c cd][-b blknum]",
3068 "display the cache lru queue",
3069 sdbc_lru
, lru_help
},
3072 {"sdbc_wctl", "?[-vd][-c cd]",
3073 "display the write control structures",
3074 sdbc_wctl
, wctl_help
},
3075 {"sdbc_wrq", "?[-vd][-c cd]",
3076 "display the write control queue",
3077 sdbc_wrq
, wrq_help
},
3078 #endif /* SAFESTORE */
3081 {"sdbc_cdinfo", "?[-av][-c cd]",
3082 "display cache descriptor information",
3083 sdbc_cdinfo
, cdinfo_help
},
3085 {"sdbc_ftctl", "?[-vd][-c cd]",
3086 "display the fault tolerant control structures",
3087 sdbc_ftctl
, ftctl_help
},
3088 #endif /* SAFESTORE */
3089 {"sdbc_handles", "?[-avC][-c cd]",
3090 "display sdbc buffer handle information",
3091 sdbc_handles
, handle_help
},
3093 { "sdbc_dmqueues", NULL
,
3094 "display sdbc dynamic memory buffer queues information",
3097 /* "global" metadata dcmds */
3098 {"sdbc_glcinfo", "?[-adC][-c cd][-b fbapos]",
3099 "display the global cache entry info structures",
3100 sdbc_glcinfo
, glcinfo_help
},
3101 {"sdbc_glfinfo", "?[-aptC]",
3102 "display the global file info structures",
3103 sdbc_glfinfo
, glfinfo_help
},
3107 static const mdb_walker_t walkers
[] = {
3108 /* walkers of cctl list and arrays */
3109 { "sdbc_cchain", "walk the cc_chain (alloc chain) of a cache ctl",
3110 sdbc_cchain_winit
, sdbc_cchain_wstep
, sdbc_cchain_wfini
},
3111 { "sdbc_cctl", "walk the cache ctl structure list",
3112 sdbc_cctl_winit
, sdbc_cctl_wstep
, sdbc_cctl_wfini
},
3113 { "sdbc_dchain", "walk the dirty chain of a cache ctl",
3114 sdbc_dchain_winit
, sdbc_dchain_wstep
, sdbc_dchain_wfini
},
3115 { "sdbc_dmchain", "walk the dynamic memory chain of a cache cctl",
3116 sdbc_dmchain_winit
, sdbc_dmchain_wstep
, sdbc_dmchain_wfini
},
3117 { "sdbc_hashchain", "walk a hash chain",
3118 sdbc_hashchain_winit
, sdbc_hashchain_wstep
,
3119 sdbc_hashchain_wfini
},
3120 { "sdbc_lru", "walk the cache lru queue",
3121 sdbc_lru_winit
, sdbc_lru_wstep
, sdbc_lru_wfini
},
3124 /* walkers of wctl lists and arrays */
3125 { "sdbc_wctl", "walk the allocated write ctl array",
3126 sdbc_wctl_winit
, sdbc_wctl_wstep
, sdbc_wctl_wfini
},
3127 { "sdbc_wrq", "walk the write ctl queue (free list)",
3128 sdbc_wrq_winit
, sdbc_wrq_wstep
, sdbc_wrq_wfini
},
3129 #endif /* SAFESTORE */
3132 "walk the _sd_cache_files array of cache descriptor information",
3133 sdbc_cdinfo_winit
, sdbc_cdinfo_wstep
, sdbc_cdinfo_wfini
},
3136 "walk the allocated array of fault tolerant structures",
3137 sdbc_ftctl_winit
, sdbc_ftctl_wstep
, sdbc_ftctl_wfini
},
3138 #endif /* SAFESTORE */
3139 { "sdbc_handles", "walk array of _sd_buf_handle_t structures",
3140 sdbc_handle_winit
, sdbc_handle_wstep
, sdbc_handle_wfini
},
3142 /* walkers for metadata arrays */
3143 { "sdbc_glcinfo", "walk the allocated global cache entry info array",
3144 sdbc_glcinfo_winit
, sdbc_glcinfo_wstep
, sdbc_glcinfo_wfini
},
3145 { "sdbc_glfinfo", "walk the allocated global file info array",
3146 sdbc_glfinfo_winit
, sdbc_glfinfo_wstep
, sdbc_glfinfo_wfini
},
3150 static const mdb_modinfo_t modinfo
= {
3151 MDB_API_VERSION
, dcmds
, walkers
3154 const mdb_modinfo_t
*