From 39f030b80b0794a689e3fad42f42c12612f88545 Mon Sep 17 00:00:00 2001 From: Patrick Mooney Date: Thu, 19 May 2016 18:10:02 +0000 Subject: [PATCH] 7299 want dnlc walker for mdb Reviewed by: Jerry Jelinek Reviewed by: Gordon Ross Approved by: Richard Lowe --- .../cmd/mdb/common/modules/genunix/Makefile.files | 3 +- usr/src/cmd/mdb/common/modules/genunix/dnlc.c | 104 +++++++++++++++++++++ usr/src/cmd/mdb/common/modules/genunix/dnlc.h | 33 +++++++ usr/src/cmd/mdb/common/modules/genunix/genunix.c | 3 + 4 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 usr/src/cmd/mdb/common/modules/genunix/dnlc.c create mode 100644 usr/src/cmd/mdb/common/modules/genunix/dnlc.h diff --git a/usr/src/cmd/mdb/common/modules/genunix/Makefile.files b/usr/src/cmd/mdb/common/modules/genunix/Makefile.files index bb9fed2547..5d9cf9bb8f 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/Makefile.files +++ b/usr/src/cmd/mdb/common/modules/genunix/Makefile.files @@ -21,7 +21,7 @@ # # Copyright 2011 Nexenta Systems, Inc. All rights reserved. # Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright (c) 2013, Joyent, Inc. All rights reserved. +# Copyright 2016 Joyent, Inc. # Copyright (c) 2013 by Delphix. All rights reserved. # @@ -44,6 +44,7 @@ GENUNIX_SRCS = \ ddi_periodic.c \ devinfo.c \ dist.c \ + dnlc.c \ findstack.c \ findstack_subr.c \ fm.c \ diff --git a/usr/src/cmd/mdb/common/modules/genunix/dnlc.c b/usr/src/cmd/mdb/common/modules/genunix/dnlc.c new file mode 100644 index 0000000000..27a93c4ae7 --- /dev/null +++ b/usr/src/cmd/mdb/common/modules/genunix/dnlc.c @@ -0,0 +1,104 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Joyent, Inc. + */ + +#include "dnlc.h" + +#include +#include + +typedef struct dnlc_walk { + int dw_hashsz; + int dw_index; + uintptr_t dw_hash; + uintptr_t dw_head; +} dnlc_walk_t; + + +int +dnlc_walk_init(mdb_walk_state_t *wsp) +{ + dnlc_walk_t *dwp; + + if (wsp->walk_addr != NULL) { + mdb_warn("dnlc walk doesn't support global walks\n"); + return (WALK_ERR); + } + + dwp = mdb_zalloc(sizeof (dnlc_walk_t), UM_SLEEP); + if (mdb_readvar(&dwp->dw_hashsz, "nc_hashsz") == -1 || + dwp->dw_hashsz <= 0) { + mdb_warn("failed to read 'nc_hashsz'\n"); + mdb_free(dwp, sizeof (dnlc_walk_t)); + return (WALK_ERR); + } + if (dwp->dw_hashsz <= 0) { + mdb_warn("invalid 'nc_hashsz' value\n"); + mdb_free(dwp, sizeof (dnlc_walk_t)); + return (WALK_ERR); + } + if (mdb_readvar(&dwp->dw_hash, "nc_hash") == -1) { + mdb_warn("failed to read 'nc_hash'\n"); + mdb_free(dwp, sizeof (dnlc_walk_t)); + return (WALK_ERR); + } + + wsp->walk_data = dwp; + return (WALK_NEXT); +} + +int +dnlc_walk_step(mdb_walk_state_t *wsp) +{ + dnlc_walk_t *dwp = wsp->walk_data; + nc_hash_t hash; + uintptr_t result, addr = wsp->walk_addr; + +next: + while (addr == dwp->dw_head || addr == NULL) { + if (dwp->dw_index >= dwp->dw_hashsz) { + return (WALK_DONE); + } + dwp->dw_head = dwp->dw_hash + + (sizeof (nc_hash_t) * dwp->dw_index); + if (mdb_vread(&hash, sizeof (hash), dwp->dw_head) == -1) { + mdb_warn("failed to read nc_hash_t at %#lx", + dwp->dw_hash); + return (WALK_ERR); + } + dwp->dw_index++; + addr = (uintptr_t)hash.hash_next; + } + + result = addr; + if (mdb_vread(&addr, sizeof (uintptr_t), addr) == -1) { + /* + * This entry may have become bogus since acquiring the address + * from its neighbor. Continue on if that is the case. + */ + addr = NULL; + goto next; + } + wsp->walk_addr = addr; + + return (wsp->walk_callback(result, &result, wsp->walk_cbdata)); +} + +void +dnlc_walk_fini(mdb_walk_state_t *wsp) +{ + dnlc_walk_t *dwp = wsp->walk_data; + + mdb_free(dwp, sizeof (dnlc_walk_t)); +} diff --git a/usr/src/cmd/mdb/common/modules/genunix/dnlc.h b/usr/src/cmd/mdb/common/modules/genunix/dnlc.h new file mode 100644 index 0000000000..a046d8b0b7 --- /dev/null +++ b/usr/src/cmd/mdb/common/modules/genunix/dnlc.h @@ -0,0 +1,33 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Joyent, Inc. + */ + +#ifndef _MDB_DNLC_H +#define _MDB_DNLC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern int dnlc_walk_init(mdb_walk_state_t *); +extern int dnlc_walk_step(mdb_walk_state_t *); +extern void dnlc_walk_fini(mdb_walk_state_t *); + +#ifdef __cplusplus +} +#endif + +#endif /* _MDB_DNLC_H */ diff --git a/usr/src/cmd/mdb/common/modules/genunix/genunix.c b/usr/src/cmd/mdb/common/modules/genunix/genunix.c index 0ba14e436e..0b9b686498 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/genunix.c +++ b/usr/src/cmd/mdb/common/modules/genunix/genunix.c @@ -74,6 +74,7 @@ #include "damap.h" #include "ddi_periodic.h" #include "devinfo.h" +#include "dnlc.h" #include "findstack.h" #include "fm.h" #include "gcore.h" @@ -4301,6 +4302,8 @@ static const mdb_walker_t walkers[] = { { "callout_table", "walk callout table array", callout_table_walk_init, callout_table_walk_step, callout_table_walk_fini }, { "cpu", "walk cpu structures", cpu_walk_init, cpu_walk_step }, + { "dnlc", "walk dnlc entries", + dnlc_walk_init, dnlc_walk_step, dnlc_walk_fini }, { "ereportq_dump", "walk list of ereports in dump error queue", ereportq_dump_walk_init, ereportq_dump_walk_step, NULL }, { "ereportq_pend", "walk list of ereports in pending error queue", -- 2.11.4.GIT