8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / mdb / common / modules / crypto / sched_impl.c
blob14549dca4ebf547c352070dc04cb06255d27dec4
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <stdio.h>
27 #include <sys/mdb_modapi.h>
28 #include <sys/modctl.h>
29 #include <sys/types.h>
30 #include <sys/crypto/api.h>
31 #include <sys/crypto/common.h>
32 #include <sys/crypto/api.h>
33 #include <sys/crypto/sched_impl.h>
34 #include "crypto_cmds.h"
36 static void
37 prt_an_state(int state)
39 switch (state) {
40 case REQ_ALLOCATED:
41 mdb_printf("REQ_ALLOCATED ");
42 break;
43 case REQ_WAITING:
44 mdb_printf("REQ_WAITING ");
45 break;
46 case REQ_INPROGRESS:
47 mdb_printf("REQ_INPROGRESS ");
48 break;
49 case REQ_DONE:
50 mdb_printf("REQ_DONE ");
51 break;
52 case REQ_CANCELED:
53 mdb_printf("REQ_CANCELED ");
54 break;
55 default:
56 mdb_printf("? %d ?? ", state);
57 break;
62 static const mdb_bitmask_t call_flags[] = {
63 { "CRYPTO_ALWAYS_QUEUE", CRYPTO_ALWAYS_QUEUE, CRYPTO_ALWAYS_QUEUE },
64 { "CRYPTO_NOTIFY_OPDONE", CRYPTO_NOTIFY_OPDONE, CRYPTO_NOTIFY_OPDONE },
65 { "CRYPTO_SKIP_REQID", CRYPTO_SKIP_REQID, CRYPTO_SKIP_REQID },
66 { NULL, 0, 0 }
69 /*ARGSUSED*/
70 static int
71 kcf_areq_node_simple(kcf_areq_node_t *areqn)
73 mdb_printf("\nan_type: ");
74 if (areqn->an_type != CRYPTO_ASYNCH)
75 mdb_printf("%-8d ", areqn->an_type);
76 else
77 mdb_printf("CRYPTO_ASYNCH");
79 mdb_printf("\nan_state: ");
80 prt_an_state(areqn->an_state);
82 mdb_printf("\nan_context: %-16p\t", areqn->an_context);
83 mdb_printf("an_is_my_turn: %s\t ", areqn->an_is_my_turn == B_FALSE ?
84 "B_FALSE" : "B_TRUE");
86 mdb_printf("\ncr_reqid: %lx\n", areqn->an_reqarg.cr_reqid);
87 return (DCMD_OK);
90 * Verbose print of kcf_areq_node_t
92 static int
93 v_kcf_areq_node(kcf_areq_node_t *areqn)
96 /* contents only -- the address is printed elsewhere */
97 /* First column */
99 mdb_printf("\n%16s: ", "an_type");
100 if (areqn->an_type != CRYPTO_ASYNCH)
101 mdb_printf("%-8d ", areqn->an_type);
102 else
103 mdb_printf("CRYPTO_ASYNCH");
105 /* Second column */
106 mdb_printf("\t\t%16s: %p\n", "an_lock", areqn->an_lock);
108 /* First column */
109 mdb_printf("%16s: ", "an_state");
110 prt_an_state(areqn->an_state);
112 /* Second column */
113 mdb_printf("%14s: next 4 items\n", "an_reqarg");
115 /* First column again */
116 mdb_printf("%16s: '%16b'", "cr_flag", areqn->an_reqarg.cr_flag,
117 call_flags);
119 /* Second column */
120 mdb_printf("\t%16s: %p\n", "cr_callback_func",
121 areqn->an_reqarg.cr_callback_func);
123 /* First column again */
124 mdb_printf("%16s: %-16p", "cr_callback_arg",
125 areqn->an_reqarg.cr_callback_arg);
127 /* Second column */
128 mdb_printf("\t%16s: %lx\n", "cr_reqid",
129 (ulong_t)areqn->an_reqarg.cr_reqid);
131 /* First column again */
132 mdb_printf("%16s: %d", "an_params.rp_opgrp",
133 areqn->an_params.rp_opgrp);
135 /* Second column */
136 mdb_printf("\t%16s: %d\n", "an_params.rp_optype",
137 areqn->an_params.rp_optype);
139 /* First column again */
140 mdb_printf("%16s: %-16p", "an_context",
141 areqn->an_context);
143 /* Second column */
144 mdb_printf("\t%16s: %p\n", "an_ctxchain_next",
145 areqn->an_ctxchain_next);
147 /* First column again */
148 mdb_printf("%16s: %s", "an_is_my_turn",
149 areqn->an_is_my_turn == B_FALSE ? "B_FALSE" : "B_TRUE");
151 /* Second column */
152 mdb_printf("\t\t%16s: %s\n", "an_isdual",
153 areqn->an_isdual == B_FALSE ? "B_FALSE" : "B_TRUE");
155 /* First column again */
156 mdb_printf("%16s: %p", "an_next",
157 areqn->an_next);
159 /* Second column */
160 mdb_printf("\t\t%16s: %p\n", "an_prev", areqn->an_prev);
162 /* First column again */
163 mdb_printf("%16s: %p", "an_provider",
164 areqn->an_provider);
166 /* Second column */
167 mdb_printf("\t\t%16s: %p\n", "an_idnext", areqn->an_idnext);
169 /* First column again */
170 mdb_printf("%16s: %p", "an_idprev",
171 areqn->an_idprev);
173 /* Second column */
174 mdb_printf("\t\t%16s: %hx\n", "an_done", areqn->an_done);
176 /* First column again */
177 mdb_printf("%16s: %d\n", "an_refcnt",
178 areqn->an_refcnt);
180 return (DCMD_OK);
182 /*ARGSUSED*/
184 kcf_areq_node(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
186 kcf_areq_node_t areqn;
187 uint_t opt_v = FALSE;
190 if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &opt_v,
191 NULL) != argc)
192 return (DCMD_USAGE);
195 * read even if we're looping, because the cbdata design does not
196 * apply to mdb_pwalk_dcmd
198 if (mdb_vread(&areqn, sizeof (kcf_areq_node_t), addr) == -1) {
199 mdb_warn("cannot read %p", addr);
200 return (DCMD_ERR);
202 if (opt_v) /* verbose */
203 return (v_kcf_areq_node(&areqn));
204 else
205 return (kcf_areq_node_simple(&areqn));
208 /*ARGSUSED*/
210 kcf_global_swq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
212 kcf_global_swq_t swq;
213 kcf_global_swq_t *ptr;
215 if (!(flags & DCMD_ADDRSPEC)) {
216 if (mdb_readsym(&ptr, sizeof (uintptr_t), "gswq")
217 == -1) {
218 mdb_warn("cannot read gswq");
219 return (DCMD_ERR);
222 else
223 ptr = (kcf_global_swq_t *)addr;
225 if (mdb_vread(&swq, sizeof (kcf_global_swq_t), (uintptr_t)ptr) == -1) {
226 mdb_warn("cannot read %p", ptr);
227 return (DCMD_ERR);
229 mdb_printf("gs_lock (mutex):\t%p\n", swq.gs_lock);
230 mdb_printf("gs_cv:\t%hx\n", swq.gs_cv._opaque);
231 mdb_printf("gs_njobs:\t%u\n", swq.gs_njobs);
232 mdb_printf("gs_maxjobs:\t%u\n", swq.gs_maxjobs);
233 mdb_printf("gs_first:\t%p\n", swq.gs_first);
234 mdb_printf("gs_last:\t%p\n", swq.gs_last);
235 return (mdb_pwalk_dcmd("an_next", "kcf_areq_node", argc,
236 argv, (uintptr_t)swq.gs_first));
239 static int
240 areq_walk_init_common(mdb_walk_state_t *wsp, boolean_t use_first)
242 kcf_global_swq_t gswq_copy;
243 uintptr_t gswq_ptr;
245 if (mdb_readsym(&gswq_ptr, sizeof (gswq_ptr), "gswq") == -1) {
246 mdb_warn("failed to read 'gswq'");
247 return (WALK_ERR);
249 if (mdb_vread(&gswq_copy, sizeof (gswq_copy), gswq_ptr) == -1) {
250 mdb_warn("cannot read %p", gswq_ptr);
251 return (WALK_ERR);
253 if ((wsp->walk_addr = (use_first ? (uintptr_t)gswq_copy.gs_first :
254 (uintptr_t)gswq_copy.gs_last)) == NULL) {
255 mdb_printf("Global swq is empty\n");
256 return (WALK_DONE);
258 wsp->walk_data = mdb_alloc(sizeof (kcf_areq_node_t), UM_SLEEP);
259 return (WALK_NEXT);
263 areq_first_walk_init(mdb_walk_state_t *wsp)
265 return (areq_walk_init_common(wsp, B_TRUE));
269 areq_last_walk_init(mdb_walk_state_t *wsp)
271 return (areq_walk_init_common(wsp, B_FALSE));
274 typedef enum idwalk_type {
275 IDNEXT, /* an_idnext */
276 IDPREV, /* an_idprev */
277 CTXCHAIN /* an_ctxchain_next */
278 } idwalk_type_t;
280 static int
281 an_id_walk_init(mdb_walk_state_t *wsp, idwalk_type_t type)
283 kcf_areq_node_t *adn;
285 if (wsp->walk_addr == NULL) {
286 mdb_warn("must give kcf_areq_node address\n");
287 return (WALK_ERR);
289 adn = wsp->walk_data = mdb_alloc(sizeof (kcf_areq_node_t), UM_SLEEP);
291 if (mdb_vread(adn, sizeof (kcf_areq_node_t), wsp->walk_addr) == -1) {
292 mdb_warn("cannot read %p", wsp->walk_addr);
293 return (WALK_ERR);
296 switch (type) {
297 case IDNEXT:
298 wsp->walk_addr = (uintptr_t)adn->an_idnext;
299 break;
300 case IDPREV:
301 wsp->walk_addr = (uintptr_t)adn->an_idprev;
302 break;
303 case CTXCHAIN:
304 wsp->walk_addr = (uintptr_t)adn->an_ctxchain_next;
305 break;
306 default:
307 mdb_warn("Bad structure member in walk_init\n");
308 return (WALK_ERR);
310 return (WALK_NEXT);
313 an_idnext_walk_init(mdb_walk_state_t *wsp)
315 return (an_id_walk_init(wsp, IDNEXT));
318 an_idprev_walk_init(mdb_walk_state_t *wsp)
320 return (an_id_walk_init(wsp, IDPREV));
323 an_ctxchain_walk_init(mdb_walk_state_t *wsp)
325 return (an_id_walk_init(wsp, CTXCHAIN));
328 * At each step, read a kcf_areq_node_t into our private storage, then invoke
329 * the callback function. We terminate when we reach a NULL type pointer.
331 static int
332 an_id_walk_step(mdb_walk_state_t *wsp, idwalk_type_t type)
334 int status;
335 kcf_areq_node_t *ptr;
337 if (wsp->walk_addr == NULL) /* then we're done */
338 return (WALK_DONE);
340 ptr = wsp->walk_data;
342 if (mdb_vread(wsp->walk_data, sizeof (kcf_areq_node_t),
343 wsp->walk_addr) == -1) {
344 mdb_warn("cannot read %p", wsp->walk_addr);
345 return (WALK_ERR);
348 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
349 wsp->walk_cbdata);
351 switch (type) {
352 case IDNEXT:
353 if ((wsp->walk_addr =
354 (uintptr_t)ptr->an_idnext) == NULL)
355 return (WALK_DONE);
356 break;
358 case IDPREV:
359 if ((wsp->walk_addr =
360 (uintptr_t)ptr->an_idprev) == NULL)
361 return (WALK_DONE);
362 break;
364 case CTXCHAIN:
365 if ((wsp->walk_addr =
366 (uintptr_t)ptr->an_ctxchain_next) == NULL)
367 return (WALK_DONE);
368 break;
370 default:
371 mdb_warn("Bad structure member in walk_step\n");
372 return (WALK_ERR);
374 return (status);
377 an_idnext_walk_step(mdb_walk_state_t *wsp)
379 return (an_id_walk_step(wsp, IDNEXT));
382 an_idprev_walk_step(mdb_walk_state_t *wsp)
384 return (an_id_walk_step(wsp, IDPREV));
387 an_ctxchain_walk_step(mdb_walk_state_t *wsp)
389 return (an_id_walk_step(wsp, CTXCHAIN));
393 * The walker's fini function is invoked at the end of each walk. Since we
394 * dynamically allocated a kcf_areq_node_t in areq_walk_init,
395 * we must free it now.
397 void
398 areq_walk_fini(mdb_walk_state_t *wsp)
400 #ifdef DEBUG
401 mdb_printf("...end of kcf_areq_node walk\n");
402 #endif
403 mdb_free(wsp->walk_data, sizeof (kcf_areq_node_t));
407 * At each step, read a kcf_areq_node_t into our private storage, then invoke
408 * the callback function. We terminate when we reach a NULL an_next pointer
409 * or a NULL an_prev pointer. use_next flag indicates which one to check.
411 static int
412 an_walk_step_common(mdb_walk_state_t *wsp, boolean_t use_next)
414 int status;
415 kcf_areq_node_t *ptr;
417 ptr = (kcf_areq_node_t *)wsp->walk_data;
419 if (mdb_vread(wsp->walk_data, sizeof (kcf_areq_node_t),
420 wsp->walk_addr) == -1) {
421 mdb_warn("failed to read kcf_areq_node at %p", wsp->walk_addr);
422 return (WALK_DONE);
424 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
425 wsp->walk_cbdata);
427 if ((wsp->walk_addr = (use_next ? (uintptr_t)ptr->an_next :
428 (uintptr_t)ptr->an_prev)) == NULL)
429 return (WALK_DONE);
431 return (status);
435 an_next_walk_step(mdb_walk_state_t *wsp)
437 return (an_walk_step_common(wsp, B_TRUE));
441 an_prev_walk_step(mdb_walk_state_t *wsp)
443 return (an_walk_step_common(wsp, B_FALSE));
447 * Walker data for reqid_table walking
449 typedef struct reqid_data {
450 kcf_reqid_table_t rd_table;
451 kcf_reqid_table_t *rd_tbl_ptrs[REQID_TABLES];
452 int rd_cur_index;
453 } reqid_data_t;
455 typedef struct reqid_cb_data {
456 crypto_req_id_t cb_reqid;
457 int verbose;
458 int found;
459 } reqid_cb_data_t;
461 extern int crypto_pr_reqid(uintptr_t, reqid_data_t *, reqid_cb_data_t *);
465 reqid_table_walk_init(mdb_walk_state_t *wsp)
467 reqid_data_t *wdata;
468 reqid_cb_data_t *cbdata;
470 wsp->walk_callback = (mdb_walk_cb_t)crypto_pr_reqid;
472 wsp->walk_data = mdb_alloc(sizeof (reqid_data_t), UM_SLEEP);
474 /* see if the walker was called from the command line or mdb_pwalk */
475 if (wsp->walk_cbdata == NULL) { /* command line */
476 if ((wsp->walk_cbdata = mdb_zalloc(sizeof (reqid_cb_data_t),
477 UM_SLEEP)) == NULL) {
478 mdb_warn("couldn't get cb memory for "
479 "reqid_table_walker");
480 return (WALK_ERR);
482 /* initialize for a simple walk, as opposed to a reqid search */
483 cbdata = wsp->walk_cbdata;
484 cbdata->verbose = TRUE;
485 cbdata->cb_reqid = 0;
488 wdata = (reqid_data_t *)wsp->walk_data;
490 if (mdb_readsym(wdata->rd_tbl_ptrs, sizeof (wdata->rd_tbl_ptrs),
491 "kcf_reqid_table") == -1) {
492 mdb_warn("failed to read 'kcf_reqid_table'");
493 return (WALK_ERR);
496 wdata->rd_cur_index = 0;
497 wsp->walk_addr = (uintptr_t)wdata->rd_tbl_ptrs[wdata->rd_cur_index];
500 return (WALK_NEXT);
504 * At each step, read a kcf_reqid_table_t into our private storage, then invoke
505 * the callback function. We terminate when we reach a
508 reqid_table_walk_step(mdb_walk_state_t *wsp)
510 int status;
511 reqid_data_t *wdata;
514 wdata = wsp->walk_data;
515 wsp->walk_addr = (uintptr_t)wdata->rd_tbl_ptrs[wdata->rd_cur_index];
517 #ifdef DEBUG
518 mdb_printf(
519 "DEBUG: kcf_reqid_table at %p, sizeof kcf_reqid_table_t = %d\n",
520 wsp->walk_addr, sizeof (kcf_reqid_table_t));
521 #endif
523 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
524 wsp->walk_cbdata);
526 /* get ready for next call */
527 wdata->rd_cur_index++;
528 if (wdata->rd_cur_index >= REQID_TABLES)
529 return (WALK_DONE);
530 return (status);
534 * The walker's fini function is invoked at the end of each walk. Since we
535 * dynamically allocated a reqid_data_t in areq_walk_init,
536 * we must free it now.
538 void
539 reqid_table_walk_fini(mdb_walk_state_t *wsp)
541 #ifdef DEBUG
542 mdb_printf("...end of kcf_reqid walk\n");
543 #endif
544 mdb_free(wsp->walk_data, sizeof (reqid_data_t));
548 * If there's an argument beyond -v, then we're looking for a specific
549 * reqid, otherwise, print any non-null kcf_areq things we run across.
553 crypto_pr_reqid(uintptr_t addr, reqid_data_t *data, reqid_cb_data_t *cbdata)
555 kcf_areq_node_t node;
556 int i;
557 int needhdr = TRUE;
559 if (addr == NULL) {
560 mdb_printf("kcf_reqid_table[%d] = NULL\n", data->rd_cur_index);
561 return (WALK_NEXT);
564 if (mdb_vread(&(data->rd_table), sizeof (kcf_reqid_table_t),
565 addr) == -1) {
566 mdb_warn("failed to read kcf_reqid_table at %p",
567 addr);
568 return (WALK_ERR);
571 /* Loop over all rt_idhash's */
572 for (i = 0; i < REQID_BUCKETS; i++) {
573 uint_t number_in_chain = 0;
574 uintptr_t node_addr;
576 /* follow the an_idnext chains for each bucket */
577 do {
578 /* read kcf_areq_node */
579 if (number_in_chain == 0)
580 node_addr = (uintptr_t)data->rd_table.rt_idhash[i];
581 else
582 /*LINTED*/
583 node_addr = (uintptr_t)node.an_idnext;
584 #ifdef DEBUG
585 mdb_printf("DEBUG: node_addr = %p\n", node_addr);
586 #endif
588 if (node_addr == NULL)
589 break; /* skip */
591 if (mdb_vread(&node, sizeof (kcf_areq_node_t), node_addr)
592 == -1) {
593 if (cbdata->verbose == TRUE)
594 mdb_printf(
595 "cannot read rt_idhash %d an_idnext %d\n",
596 i, number_in_chain);
597 break;
599 /* see if we want to print it */
600 if ((cbdata->cb_reqid == 0) ||
601 (node.an_reqarg.cr_reqid == cbdata->cb_reqid)) {
602 cbdata->found = TRUE; /* printed if false || reqid */
603 /* is this the first rd_idhash found for this table? */
604 if (needhdr == TRUE) {
605 /* print both indices in bold */
606 mdb_printf("%<b>kcf_reqid_table[%lu] at %p:%</b>\n",
607 data->rd_cur_index, addr);
608 mdb_printf("\trt_lock: %p\trt_curid: %llx\n",
609 data->rd_table.rt_lock,
610 data->rd_table.rt_curid);
611 needhdr = FALSE;
613 /* print kcf_areq_node */
614 if (number_in_chain < 1)
615 mdb_printf(
616 " %<b>rt_idhash[%lu%]%</b> = %<b>%p:%</b>\n",
617 i, node_addr);
618 else
619 mdb_printf(
620 " rt_idhash[%lu%]"
621 " an_idnext %d = %<b>%p:%</b>\n",
622 i, number_in_chain, node_addr);
623 mdb_inc_indent(8);
625 /* if we're looking for one and only one reqid */
626 /* do it REALLY verbose */
627 if ((node.an_reqarg.cr_reqid == cbdata->cb_reqid) &&
628 (cbdata->cb_reqid != 0))
629 v_kcf_areq_node(&node);
630 else if (cbdata->verbose == TRUE)
632 * verbose for this walker means non-verbose for
633 * the kcf_areq_node details
635 kcf_areq_node_simple(&node);
636 mdb_dec_indent(8);
638 /* if we only wanted one reqid, quit now */
639 if (node.an_reqarg.cr_reqid == cbdata->cb_reqid) {
640 return (WALK_DONE);
643 number_in_chain++;
645 } while (node.an_idnext != NULL); /* follow chain in same bucket */
647 } /* for each REQID_BUCKETS */
649 if ((needhdr == TRUE) && (cbdata->cb_reqid == 0)) {
650 mdb_printf("%kcf_reqid_table[%lu]: %p\n",
651 data->rd_cur_index, addr);
653 return (WALK_NEXT);
656 /*ARGSUSED*/
658 crypto_find_reqid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
660 const mdb_arg_t *argp = NULL;
661 reqid_cb_data_t cbdata;
662 int i, status;
664 cbdata.cb_reqid = 0L;
665 cbdata.verbose = FALSE;
666 cbdata.found = FALSE;
668 if (flags & DCMD_ADDRSPEC) {
669 mdb_printf("use addr ::kcf_reqid_table\n");
670 return (DCMD_USAGE);
672 if ((i = mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE,
673 &cbdata.verbose, NULL)) != argc) {
674 if (argc - i > 1)
675 return (DCMD_USAGE);
678 if (argc > i)
679 argp = &argv[i];
681 if ((argp != NULL)) {
682 if (argp->a_type == MDB_TYPE_IMMEDIATE)
683 cbdata.cb_reqid = argp->a_un.a_val;
684 else
685 cbdata.cb_reqid = (crypto_req_id_t)
686 mdb_strtoull(argp->a_un.a_str);
688 status = mdb_pwalk("kcf_reqid_table", (mdb_walk_cb_t)crypto_pr_reqid,
689 &cbdata, addr);
691 if ((cbdata.cb_reqid != 0L) && (cbdata.found == FALSE))
692 mdb_printf("ID 0x%lx not found\n", cbdata.cb_reqid);
693 #ifdef DEBUG
694 else
695 mdb_printf("DEBUG: cbdata.db_reqid = %lx, cbdata.found = %d\n",
696 cbdata.cb_reqid, cbdata.found);
697 #endif
699 return (status);
703 kcf_reqid_table_dcmd(uintptr_t addr, uint_t flags, int argc,
704 const mdb_arg_t *argv)
706 reqid_data_t wdata;
707 reqid_cb_data_t cbdata;
709 if (!(flags & DCMD_ADDRSPEC))
710 return (DCMD_USAGE);
712 memset(&wdata, 0, sizeof (wdata));
713 memset(&cbdata, 0, sizeof (cbdata));
715 if ((mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE,
716 &cbdata.verbose, NULL)) != argc) {
717 return (DCMD_USAGE);
719 crypto_pr_reqid(addr, &wdata, &cbdata);
720 return (DCMD_OK);