2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright (c) 2015, Joyent, Inc. All rights reserved.
16 #include <sys/mdb_modapi.h>
20 typedef struct kmemlog_walk
{
22 mm_logentry_t
*kmlw_entries
;
29 kmemlog_walk_init(mdb_walk_state_t
*wsp
)
34 if (mdb_lookup_by_name("mm_kmemlog", &sym
) != 0) {
35 mdb_warn("couldn't find symbol 'mm_kmemlog'");
39 kw
= mdb_zalloc(sizeof (kmemlog_walk_t
), UM_SLEEP
);
40 kw
->kmlw_entries
= mdb_zalloc(sym
.st_size
, UM_SLEEP
);
41 kw
->kmlw_addr
= sym
.st_value
;
43 if (mdb_vread(kw
->kmlw_entries
, sym
.st_size
, sym
.st_value
) == -1) {
44 mdb_warn("couldn't read log at %p", sym
.st_value
);
45 mdb_free(kw
->kmlw_entries
, sym
.st_size
);
46 mdb_free(kw
, sizeof (kmemlog_walk_t
));
50 kw
->kmlw_nentries
= sym
.st_size
/ sizeof (mm_logentry_t
);
52 mdb_readvar(&kw
->kmlw_entry
, "mm_kmemlogent");
53 kw
->kmlw_oldest
= kw
->kmlw_entry
;
60 kmemlog_walk_step(mdb_walk_state_t
*wsp
)
62 kmemlog_walk_t
*kw
= wsp
->walk_data
;
66 ent
= &kw
->kmlw_entries
[kw
->kmlw_entry
];
68 if (++kw
->kmlw_entry
== kw
->kmlw_nentries
)
71 if (ent
->mle_hrtime
!= 0) {
72 rval
= wsp
->walk_callback(kw
->kmlw_addr
+ ((uintptr_t)ent
-
73 (uintptr_t)kw
->kmlw_entries
), ent
, wsp
->walk_cbdata
);
76 if (rval
== WALK_NEXT
&& kw
->kmlw_entry
== kw
->kmlw_oldest
)
83 kmemlog_walk_fini(mdb_walk_state_t
*wsp
)
85 kmemlog_walk_t
*kw
= wsp
->walk_data
;
87 mdb_free(kw
->kmlw_entries
, kw
->kmlw_nentries
* sizeof (mm_logentry_t
));
88 mdb_free(kw
, sizeof (kmemlog_walk_t
));
92 kmemlog(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
96 if (!(flags
& DCMD_ADDRSPEC
)) {
97 if (mdb_walk_dcmd("kmemlog", "kmemlog", argc
, argv
) == -1) {
98 mdb_warn("can't walk 'kmemlog'");
104 if (DCMD_HDRSPEC(flags
)) {
105 mdb_printf("%?s %-20s %?s %5s %s\n",
106 "ADDR", "TIME", "VADDR", "PID", "PSARGS");
109 if (mdb_vread(&ent
, sizeof (ent
), addr
) == -1) {
110 mdb_warn("can't read mm_logentry_t at %p", addr
);
114 mdb_printf("%?p %-20Y %?p %5d %s\n",
115 addr
, ent
.mle_hrestime
.tv_sec
, ent
.mle_vaddr
, ent
.mle_pid
,
121 static const mdb_dcmd_t dcmds
[] = {
122 { "kmemlog", NULL
, "print log of writes via /dev/kmem", kmemlog
},
126 static const mdb_walker_t walkers
[] = {
127 { "kmemlog", "walk entries in /dev/kmem write log",
128 kmemlog_walk_init
, kmemlog_walk_step
, kmemlog_walk_fini
},
132 static const mdb_modinfo_t modinfo
= {
133 MDB_API_VERSION
, dcmds
, walkers
136 const mdb_modinfo_t
*