Index: sys/sys/buf.h =================================================================== RCS file: /cvsroot/src/sys/sys/buf.h,v retrieving revision 1.134 diff -p -u -r1.134 buf.h --- sys/sys/buf.h 31 Jul 2020 04:07:30 -0000 1.134 +++ sys/sys/buf.h 28 Oct 2023 05:11:15 -0000 @@ -303,10 +303,6 @@ void bgetvp(struct vnode *, buf_t *); u_long buf_memcalc(void); int buf_drain(int); int buf_setvalimit(vsize_t); -#if defined(DDB) || defined(DEBUGPRINT) -void vfs_buf_print(buf_t *, int, void (*)(const char *, ...) - __printflike(1, 2)); -#endif void buf_init(buf_t *); void buf_destroy(buf_t *); int bbusy(buf_t *, bool, int, kmutex_t *); Index: sys/sys/vnode.h =================================================================== RCS file: /cvsroot/src/sys/sys/vnode.h,v retrieving revision 1.304 diff -p -u -r1.304 vnode.h --- sys/sys/vnode.h 26 Oct 2022 23:40:30 -0000 1.304 +++ sys/sys/vnode.h 28 Oct 2023 05:11:15 -0000 @@ -663,16 +663,12 @@ uint8_t vtype2dt(enum vtype); int vfs_unixify_accmode(accmode_t *); void vfs_getnewfsid(struct mount *); void vfs_timestamp(struct timespec *); -#if defined(DDB) || defined(DEBUGPRINT) +#if defined(DEBUGPRINT) void vfs_vnode_print(struct vnode *, int, void (*)(const char *, ...) __printflike(1, 2)); -void vfs_vnode_lock_print(void *, int, void (*)(const char *, ...) - __printflike(1, 2)); void vfs_mount_print(struct mount *, int, void (*)(const char *, ...) __printflike(1, 2)); -void vfs_mount_print_all(int, void (*)(const char *, ...) - __printflike(1, 2)); -#endif /* DDB */ +#endif /* DEBUGPRINT */ #endif /* _KERNEL */ Index: sys/kern/vfs_mount.c =================================================================== RCS file: /cvsroot/src/sys/kern/vfs_mount.c,v retrieving revision 1.102 diff -p -u -r1.102 vfs_mount.c --- sys/kern/vfs_mount.c 24 Feb 2023 11:02:27 -0000 1.102 +++ sys/kern/vfs_mount.c 28 Oct 2023 05:11:15 -0000 @@ -1688,27 +1688,3 @@ mountlist_remove(struct mount *mp) mountlist_free(me); } -/* - * Unlocked variant to traverse the mountlist. - * To be used from DDB only. - */ -struct mount * -_mountlist_next(struct mount *mp) -{ - struct mountlist_entry *me; - - if (mp == NULL) { - me = TAILQ_FIRST(&mountlist); - } else { - TAILQ_FOREACH(me, &mountlist, me_list) - if (me->me_type == ME_MOUNT && me->me_mount == mp) - break; - if (me != NULL) - me = TAILQ_NEXT(me, me_list); - } - - while (me != NULL && me->me_type != ME_MOUNT) - me = TAILQ_NEXT(me, me_list); - - return (me ? me->me_mount : NULL); -} Index: sys/kern/vfs_subr.c =================================================================== RCS file: /cvsroot/src/sys/kern/vfs_subr.c,v retrieving revision 1.500 diff -p -u -r1.500 vfs_subr.c --- sys/kern/vfs_subr.c 30 Apr 2023 08:46:11 -0000 1.500 +++ sys/kern/vfs_subr.c 28 Oct 2023 05:11:15 -0000 @@ -1668,185 +1668,18 @@ VFS_SUSPENDCTL(struct mount *mp, int a) return error; } -#if defined(DDB) || defined(DEBUGPRINT) -static const char buf_flagbits[] = BUF_FLAGBITS; - -void -vfs_buf_print(struct buf *bp, int full, void (*pr)(const char *, ...)) -{ - char bf[1024]; - - (*pr)(" vp %p lblkno 0x%"PRIx64" blkno 0x%"PRIx64" rawblkno 0x%" - PRIx64 " dev 0x%x\n", - bp->b_vp, bp->b_lblkno, bp->b_blkno, bp->b_rawblkno, bp->b_dev); - - snprintb(bf, sizeof(bf), - buf_flagbits, bp->b_flags | bp->b_oflags | bp->b_cflags); - (*pr)(" error %d flags %s\n", bp->b_error, bf); - - (*pr)(" bufsize 0x%lx bcount 0x%lx resid 0x%lx\n", - bp->b_bufsize, bp->b_bcount, bp->b_resid); - (*pr)(" data %p saveaddr %p\n", - bp->b_data, bp->b_saveaddr); - (*pr)(" iodone %p objlock %p\n", bp->b_iodone, bp->b_objlock); -} +#if defined(DEBUGPRINT) +#include void vfs_vnode_print(struct vnode *vp, int full, void (*pr)(const char *, ...)) { - - uvm_object_printit(&vp->v_uobj, full, pr); - (*pr)("\n"); - vprint_common(vp, "", pr); - if (full) { - struct buf *bp; - - (*pr)("clean bufs:\n"); - LIST_FOREACH(bp, &vp->v_cleanblkhd, b_vnbufs) { - (*pr)(" bp %p\n", bp); - vfs_buf_print(bp, full, pr); - } - - (*pr)("dirty bufs:\n"); - LIST_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs) { - (*pr)(" bp %p\n", bp); - vfs_buf_print(bp, full, pr); - } - } -} - -void -vfs_vnode_lock_print(void *vlock, int full, void (*pr)(const char *, ...)) -{ - struct mount *mp; - vnode_impl_t *vip; - - for (mp = _mountlist_next(NULL); mp; mp = _mountlist_next(mp)) { - TAILQ_FOREACH(vip, &mp->mnt_vnodelist, vi_mntvnodes) { - if (&vip->vi_lock == vlock || - VIMPL_TO_VNODE(vip)->v_interlock == vlock) - vfs_vnode_print(VIMPL_TO_VNODE(vip), full, pr); - } - } -} - -void -vfs_mount_print_all(int full, void (*pr)(const char *, ...)) -{ - struct mount *mp; - for (mp = _mountlist_next(NULL); mp; mp = _mountlist_next(mp)) - vfs_mount_print(mp, full, pr); + db_vnode_print((db_addr_t)vp, full, pr); } void vfs_mount_print(struct mount *mp, int full, void (*pr)(const char *, ...)) { - char sbuf[256]; - - (*pr)("vnodecovered = %p data = %p\n", - mp->mnt_vnodecovered, mp->mnt_data); - - (*pr)("fs_bshift %d dev_bshift = %d\n", - mp->mnt_fs_bshift, mp->mnt_dev_bshift); - - snprintb(sbuf, sizeof(sbuf), __MNT_FLAG_BITS, mp->mnt_flag); - (*pr)("flag = %s\n", sbuf); - - snprintb(sbuf, sizeof(sbuf), __IMNT_FLAG_BITS, mp->mnt_iflag); - (*pr)("iflag = %s\n", sbuf); - - (*pr)("refcnt = %d updating @ %p\n", mp->mnt_refcnt, mp->mnt_updating); - - (*pr)("statvfs cache:\n"); - (*pr)("\tbsize = %lu\n", mp->mnt_stat.f_bsize); - (*pr)("\tfrsize = %lu\n", mp->mnt_stat.f_frsize); - (*pr)("\tiosize = %lu\n", mp->mnt_stat.f_iosize); - - (*pr)("\tblocks = %"PRIu64"\n", mp->mnt_stat.f_blocks); - (*pr)("\tbfree = %"PRIu64"\n", mp->mnt_stat.f_bfree); - (*pr)("\tbavail = %"PRIu64"\n", mp->mnt_stat.f_bavail); - (*pr)("\tbresvd = %"PRIu64"\n", mp->mnt_stat.f_bresvd); - - (*pr)("\tfiles = %"PRIu64"\n", mp->mnt_stat.f_files); - (*pr)("\tffree = %"PRIu64"\n", mp->mnt_stat.f_ffree); - (*pr)("\tfavail = %"PRIu64"\n", mp->mnt_stat.f_favail); - (*pr)("\tfresvd = %"PRIu64"\n", mp->mnt_stat.f_fresvd); - - (*pr)("\tf_fsidx = { 0x%"PRIx32", 0x%"PRIx32" }\n", - mp->mnt_stat.f_fsidx.__fsid_val[0], - mp->mnt_stat.f_fsidx.__fsid_val[1]); - - (*pr)("\towner = %"PRIu32"\n", mp->mnt_stat.f_owner); - (*pr)("\tnamemax = %lu\n", mp->mnt_stat.f_namemax); - - snprintb(sbuf, sizeof(sbuf), __MNT_FLAG_BITS, mp->mnt_stat.f_flag); - - (*pr)("\tflag = %s\n", sbuf); - (*pr)("\tsyncwrites = %" PRIu64 "\n", mp->mnt_stat.f_syncwrites); - (*pr)("\tasyncwrites = %" PRIu64 "\n", mp->mnt_stat.f_asyncwrites); - (*pr)("\tsyncreads = %" PRIu64 "\n", mp->mnt_stat.f_syncreads); - (*pr)("\tasyncreads = %" PRIu64 "\n", mp->mnt_stat.f_asyncreads); - (*pr)("\tfstypename = %s\n", mp->mnt_stat.f_fstypename); - (*pr)("\tmntonname = %s\n", mp->mnt_stat.f_mntonname); - (*pr)("\tmntfromname = %s\n", mp->mnt_stat.f_mntfromname); - - { - int cnt = 0; - vnode_t *vp; - vnode_impl_t *vip; - (*pr)("locked vnodes ="); - TAILQ_FOREACH(vip, &mp->mnt_vnodelist, vi_mntvnodes) { - vp = VIMPL_TO_VNODE(vip); - if (VOP_ISLOCKED(vp)) { - if ((++cnt % 6) == 0) { - (*pr)(" %p,\n\t", vp); - } else { - (*pr)(" %p,", vp); - } - } - } - (*pr)("\n"); - } - - if (full) { - int cnt = 0; - vnode_t *vp; - vnode_impl_t *vip; - (*pr)("all vnodes ="); - TAILQ_FOREACH(vip, &mp->mnt_vnodelist, vi_mntvnodes) { - vp = VIMPL_TO_VNODE(vip); - if (!TAILQ_NEXT(vip, vi_mntvnodes)) { - (*pr)(" %p", vp); - } else if ((++cnt % 6) == 0) { - (*pr)(" %p,\n\t", vp); - } else { - (*pr)(" %p,", vp); - } - } - (*pr)("\n"); - } -} - -/* - * List all of the locked vnodes in the system. - */ -void printlockedvnodes(void); - -void -printlockedvnodes(void) -{ - struct mount *mp; - vnode_t *vp; - vnode_impl_t *vip; - - printf("Locked vnodes\n"); - for (mp = _mountlist_next(NULL); mp; mp = _mountlist_next(mp)) { - TAILQ_FOREACH(vip, &mp->mnt_vnodelist, vi_mntvnodes) { - vp = VIMPL_TO_VNODE(vip); - if (VOP_ISLOCKED(vp)) - vprint(NULL, vp); - } - } + db_mount_print((db_addr_t)mp, full, pr); } - -#endif /* DDB || DEBUGPRINT */ +#endif /* DEBUGPRINT */ Index: sys/kern/vfs_trans.c =================================================================== RCS file: /cvsroot/src/sys/kern/vfs_trans.c,v retrieving revision 1.70 diff -p -u -r1.70 vfs_trans.c --- sys/kern/vfs_trans.c 4 Nov 2022 11:20:39 -0000 1.70 +++ sys/kern/vfs_trans.c 28 Oct 2023 05:11:15 -0000 @@ -1021,118 +1021,3 @@ fscow_run(struct buf *bp, bool data_vali return error; } -#if defined(DDB) -void fstrans_dump(int); - -static void -fstrans_print_lwp(struct proc *p, struct lwp *l, int verbose) -{ - char prefix[9]; - struct fstrans_lwp_info *fli; - - snprintf(prefix, sizeof(prefix), "%d.%d", p->p_pid, l->l_lid); - LIST_FOREACH(fli, &fstrans_fli_head, fli_list) { - if (fli->fli_self != l) - continue; - if (fli->fli_trans_cnt == 0 && fli->fli_cow_cnt == 0) { - if (! verbose) - continue; - } - printf("%-8s", prefix); - if (verbose) - printf(" @%p", fli); - if (fli->fli_mount == dead_rootmount) - printf(" "); - else if (fli->fli_mount != NULL) - printf(" (%s)", fli->fli_mount->mnt_stat.f_mntonname); - else - printf(" NULL"); - if (fli->fli_alias != NULL) { - struct mount *amp = fli->fli_alias->fli_mount; - - printf(" alias"); - if (verbose) - printf(" @%p", fli->fli_alias); - if (amp == NULL) - printf(" NULL"); - else - printf(" (%s)", amp->mnt_stat.f_mntonname); - } - if (fli->fli_mountinfo && fli->fli_mountinfo->fmi_gone) - printf(" gone"); - if (fli->fli_trans_cnt == 0) { - printf(" -"); - } else { - switch (fli->fli_lock_type) { - case FSTRANS_LAZY: - printf(" lazy"); - break; - case FSTRANS_SHARED: - printf(" shared"); - break; - default: - printf(" %#x", fli->fli_lock_type); - break; - } - } - printf(" %d cow %d alias %d\n", - fli->fli_trans_cnt, fli->fli_cow_cnt, fli->fli_alias_cnt); - prefix[0] = '\0'; - } -} - -static void -fstrans_print_mount(struct mount *mp, int verbose) -{ - uint32_t indx; - struct fstrans_mount_info *fmi; - - indx = fstrans_mount_hash(mp); - SLIST_FOREACH(fmi, &fstrans_mount_hashtab[indx], fmi_hash) - if (fmi->fmi_mount == mp) - break; - - if (!verbose && (fmi == NULL || fmi->fmi_state == FSTRANS_NORMAL)) - return; - - printf("%-16s ", mp->mnt_stat.f_mntonname); - if (fmi == NULL) { - printf("(null)\n"); - return; - } - printf("owner %p ", fmi->fmi_owner); - switch (fmi->fmi_state) { - case FSTRANS_NORMAL: - printf("state normal\n"); - break; - case FSTRANS_SUSPENDING: - printf("state suspending\n"); - break; - case FSTRANS_SUSPENDED: - printf("state suspended\n"); - break; - default: - printf("state %#x\n", fmi->fmi_state); - break; - } -} - -void -fstrans_dump(int full) -{ - const struct proclist_desc *pd; - struct proc *p; - struct lwp *l; - struct mount *mp; - - printf("Fstrans locks by lwp:\n"); - for (pd = proclists; pd->pd_list != NULL; pd++) - PROCLIST_FOREACH(p, pd->pd_list) - LIST_FOREACH(l, &p->p_lwps, l_sibling) - fstrans_print_lwp(p, l, full == 1); - - printf("Fstrans state by mount:\n"); - for (mp = _mountlist_next(NULL); mp; mp = _mountlist_next(mp)) - fstrans_print_mount(mp, full == 1); -} -#endif /* defined(DDB) */ Index: sys/uvm/uvm_ddb.h =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_ddb.h,v retrieving revision 1.16 diff -p -u -r1.16 uvm_ddb.h --- sys/uvm/uvm_ddb.h 27 Dec 2019 12:51:57 -0000 1.16 +++ sys/uvm/uvm_ddb.h 28 Oct 2023 05:11:16 -0000 @@ -33,15 +33,10 @@ #ifdef _KERNEL #if defined(DDB) || defined(DEBUGPRINT) -void uvm_map_printit(struct vm_map *, bool, - void (*)(const char *, ...)); -void uvm_object_printit(struct uvm_object *, bool, - void (*)(const char *, ...)); void uvm_page_printit(struct vm_page *, bool, void (*)(const char *, ...)); void uvm_page_printall(void (*)(const char *, ...)); void uvm_page_print_freelists(void (*)(const char *, ...)); -void uvmexp_print(void (*)(const char *, ...)); #endif /* DDB || DEBUGPRINT */ #endif /* _KERNEL */ Index: sys/uvm/uvm_map.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_map.c,v retrieving revision 1.410 diff -p -u -r1.410 uvm_map.c --- sys/uvm/uvm_map.c 23 Sep 2023 18:21:12 -0000 1.410 +++ sys/uvm/uvm_map.c 28 Oct 2023 05:11:16 -0000 @@ -5155,68 +5059,6 @@ uvm_voaddr_compare(const struct uvm_voad return 0; } -#if defined(DDB) || defined(DEBUGPRINT) - -/* - * uvm_map_printit: actually prints the map - */ - -void -uvm_map_printit(struct vm_map *map, bool full, - void (*pr)(const char *, ...)) -{ - struct vm_map_entry *entry; - - (*pr)("MAP %p: [%#lx->%#lx]\n", map, vm_map_min(map), - vm_map_max(map)); - (*pr)("\t#ent=%d, sz=%d, ref=%d, version=%d, flags=%#x\n", - map->nentries, map->size, map->ref_count, map->timestamp, - map->flags); - (*pr)("\tpmap=%p(resident=%ld, wired=%ld)\n", map->pmap, - pmap_resident_count(map->pmap), pmap_wired_count(map->pmap)); - if (!full) - return; - for (entry = map->header.next; entry != &map->header; - entry = entry->next) { - (*pr)(" - %p: %#lx->%#lx: obj=%p/%#llx, amap=%p/%d\n", - entry, entry->start, entry->end, entry->object.uvm_obj, - (long long)entry->offset, entry->aref.ar_amap, - entry->aref.ar_pageoff); - (*pr)( - "\tsubmap=%c, cow=%c, nc=%c, prot(max)=%d/%d, inh=%d, " - "wc=%d, adv=%d%s\n", - (entry->etype & UVM_ET_SUBMAP) ? 'T' : 'F', - (entry->etype & UVM_ET_COPYONWRITE) ? 'T' : 'F', - (entry->etype & UVM_ET_NEEDSCOPY) ? 'T' : 'F', - entry->protection, entry->max_protection, - entry->inheritance, entry->wired_count, entry->advice, - entry == map->first_free ? " (first_free)" : ""); - } -} - -void -uvm_whatis(uintptr_t addr, void (*pr)(const char *, ...)) -{ - struct vm_map *map; - - for (map = kernel_map;;) { - struct vm_map_entry *entry; - - if (!uvm_map_lookup_entry_bytree(map, (vaddr_t)addr, &entry)) { - break; - } - (*pr)("%p is %p+%zu from VMMAP %p\n", - (void *)addr, (void *)entry->start, - (size_t)(addr - (uintptr_t)entry->start), map); - if (!UVM_ET_ISSUBMAP(entry)) { - break; - } - map = entry->object.sub_map; - } -} - -#endif /* DDB || DEBUGPRINT */ - #ifndef __USER_VA0_IS_SAFE static int sysctl_user_va0_disable(SYSCTLFN_ARGS) Index: sys/uvm/uvm_object.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_object.c,v retrieving revision 1.25 diff -p -u -r1.25 uvm_object.c --- sys/uvm/uvm_object.c 15 Aug 2020 07:24:09 -0000 1.25 +++ sys/uvm/uvm_object.c 28 Oct 2023 05:11:16 -0000 @@ -330,46 +330,3 @@ uvm_obj_page_clear_writeback(struct vm_p uvm_obj_page_clear_tag(pg, UVM_PAGE_WRITEBACK_TAG); } -#if defined(DDB) || defined(DEBUGPRINT) - -/* - * uvm_object_printit: actually prints the object - */ -void -uvm_object_printit(struct uvm_object *uobj, bool full, - void (*pr)(const char *, ...)) -{ - struct uvm_page_array a; - struct vm_page *pg; - int cnt = 0; - voff_t off; - - (*pr)("OBJECT %p: locked=%d, pgops=%p, npages=%d, ", - uobj, rw_write_held(uobj->vmobjlock), uobj->pgops, uobj->uo_npages); - if (UVM_OBJ_IS_KERN_OBJECT(uobj)) - (*pr)("refs=\n"); - else - (*pr)("refs=%d\n", uobj->uo_refs); - - if (!full) { - return; - } - (*pr)(" PAGES :\n "); - uvm_page_array_init(&a, uobj, 0); - off = 0; - while ((pg = uvm_page_array_fill_and_peek(&a, off, 0)) != NULL) { - cnt++; - (*pr)("<%p,0x%llx> ", pg, (long long)pg->offset); - if ((cnt % 3) == 0) { - (*pr)("\n "); - } - off = pg->offset + PAGE_SIZE; - uvm_page_array_advance(&a); - } - if ((cnt % 3) != 0) { - (*pr)("\n"); - } - uvm_page_array_fini(&a); -} - -#endif /* DDB || DEBUGPRINT */ Index: sys/uvm/uvm_object.h =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_object.h,v retrieving revision 1.39 diff -p -u -r1.39 uvm_object.h --- sys/uvm/uvm_object.h 14 Aug 2020 09:06:15 -0000 1.39 +++ sys/uvm/uvm_object.h 28 Oct 2023 05:11:16 -0000 @@ -85,7 +85,7 @@ struct uvm_object { #define UVM_OBJ_KERN (-2) #define UVM_OBJ_IS_KERN_OBJECT(uobj) \ - ((uobj)->uo_refs == UVM_OBJ_KERN) + ((uobj)->uo_refs == (unsigned)UVM_OBJ_KERN) #ifdef _KERNEL Index: sys/uvm/uvm_page.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_page.c,v retrieving revision 1.254 diff -p -u -r1.254 uvm_page.c --- sys/uvm/uvm_page.c 23 Sep 2023 18:20:20 -0000 1.254 +++ sys/uvm/uvm_page.c 28 Oct 2023 05:11:16 -0000 @@ -2110,6 +2127,7 @@ uvm_direct_process(struct vm_page **pgs, #if defined(DDB) || defined(DEBUGPRINT) +#if 0 /* * uvm_page_printit: actually print the page */ @@ -2190,6 +2208,7 @@ uvm_page_printit(struct vm_page *pg, boo (*pr)(" >>> PAGE NOT FOUND ON PAGEQ LIST! <<<\n"); } } +#endif /* * uvm_page_printall - print a summary of all managed pages Index: sys/uvm/uvm_stat.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_stat.c,v retrieving revision 1.46 diff -p -u -r1.46 uvm_stat.c --- sys/uvm/uvm_stat.c 14 Jun 2020 21:41:42 -0000 1.46 +++ sys/uvm/uvm_stat.c 28 Oct 2023 05:11:17 -0000 @@ -44,104 +44,6 @@ __KERNEL_RCSID(0, "$NetBSD: uvm_stat.c,v #include #include -#ifdef DDB - -#include - -/* - * uvmexp_print: ddb hook to print interesting uvm counters - */ -void -uvmexp_print(void (*pr)(const char *, ...) - __attribute__((__format__(__printf__,1,2)))) -{ - int64_t anonpg, execpg, filepg; - int active, inactive; - int poolpages, freepg; - - uvm_estimatepageable(&active, &inactive); - poolpages = pool_totalpages_locked(); - - /* this will sync all counters. */ - freepg = uvm_availmem(false); - - anonpg = cpu_count_get(CPU_COUNT_ANONCLEAN) + - cpu_count_get(CPU_COUNT_ANONDIRTY) + - cpu_count_get(CPU_COUNT_ANONUNKNOWN); - execpg = cpu_count_get(CPU_COUNT_EXECPAGES); - filepg = cpu_count_get(CPU_COUNT_FILECLEAN) + - cpu_count_get(CPU_COUNT_FILEDIRTY) + - cpu_count_get(CPU_COUNT_FILEUNKNOWN) - - execpg; - - (*pr)("Current UVM status:\n"); - (*pr)(" pagesize=%d (0x%x), pagemask=0x%x, pageshift=%d, ncolors=%d\n", - uvmexp.pagesize, uvmexp.pagesize, uvmexp.pagemask, - uvmexp.pageshift, uvmexp.ncolors); - (*pr)(" %d VM pages: %d active, %d inactive, %d wired, %d free\n", - uvmexp.npages, active, inactive, uvmexp.wired, freepg); - (*pr)(" pages %" PRId64 " anon, %" PRId64 " file, %" PRId64 " exec\n", - anonpg, filepg, execpg); - (*pr)(" freemin=%d, free-target=%d, wired-max=%d\n", - uvmexp.freemin, uvmexp.freetarg, uvmexp.wiredmax); - (*pr)(" resv-pg=%d, resv-kernel=%d\n", - uvmexp.reserve_pagedaemon, uvmexp.reserve_kernel); - (*pr)(" bootpages=%d, poolpages=%d\n", - uvmexp.bootpages, poolpages); - - (*pr)(" faults=%" PRId64 ", traps=%" PRId64 ", " - "intrs=%" PRId64 ", ctxswitch=%" PRId64 "\n", - cpu_count_get(CPU_COUNT_NFAULT), - cpu_count_get(CPU_COUNT_NTRAP), - cpu_count_get(CPU_COUNT_NINTR), - cpu_count_get(CPU_COUNT_NSWTCH)); - (*pr)(" softint=%" PRId64 ", syscalls=%" PRId64 "\n", - cpu_count_get(CPU_COUNT_NSOFT), - cpu_count_get(CPU_COUNT_NSYSCALL)); - - (*pr)(" fault counts:\n"); - (*pr)(" noram=%" PRId64 ", noanon=%" PRId64 ", pgwait=%" PRId64 - ", pgrele=%" PRId64 "\n", - cpu_count_get(CPU_COUNT_FLTNORAM), - cpu_count_get(CPU_COUNT_FLTNOANON), - cpu_count_get(CPU_COUNT_FLTPGWAIT), - cpu_count_get(CPU_COUNT_FLTPGRELE)); - (*pr)(" ok relocks(total)=%" PRId64 "(%" PRId64 "), " - "anget(retrys)=%" PRId64 "(%" PRId64 "), amapcopy=%" PRId64 "\n", - cpu_count_get(CPU_COUNT_FLTRELCKOK), - cpu_count_get(CPU_COUNT_FLTRELCK), - cpu_count_get(CPU_COUNT_FLTANGET), - cpu_count_get(CPU_COUNT_FLTANRETRY), - cpu_count_get(CPU_COUNT_FLTAMCOPY)); - (*pr)(" neighbor anon/obj pg=%" PRId64 "/%" PRId64 - ", gets(lock/unlock)=%" PRId64 "/%" PRId64 "\n", - cpu_count_get(CPU_COUNT_FLTNAMAP), - cpu_count_get(CPU_COUNT_FLTNOMAP), - cpu_count_get(CPU_COUNT_FLTLGET), - cpu_count_get(CPU_COUNT_FLTGET)); - (*pr)(" cases: anon=%" PRId64 ", anoncow=%" PRId64 ", obj=%" PRId64 - ", prcopy=%" PRId64 ", przero=%" PRId64 "\n", - cpu_count_get(CPU_COUNT_FLT_ANON), - cpu_count_get(CPU_COUNT_FLT_ACOW), - cpu_count_get(CPU_COUNT_FLT_OBJ), - cpu_count_get(CPU_COUNT_FLT_PRCOPY), - cpu_count_get(CPU_COUNT_FLT_PRZERO)); - - (*pr)(" daemon and swap counts:\n"); - (*pr)(" woke=%d, revs=%d, scans=%d, obscans=%d, anscans=%d\n", - uvmexp.pdwoke, uvmexp.pdrevs, uvmexp.pdscans, uvmexp.pdobscan, - uvmexp.pdanscan); - (*pr)(" busy=%d, freed=%d, reactivate=%d, deactivate=%d\n", - uvmexp.pdbusy, uvmexp.pdfreed, uvmexp.pdreact, uvmexp.pddeact); - (*pr)(" pageouts=%d, pending=%d, nswget=%d\n", uvmexp.pdpageouts, - uvmexp.pdpending, uvmexp.nswget); - (*pr)(" nswapdev=%d, swpgavail=%d\n", - uvmexp.nswapdev, uvmexp.swpgavail); - (*pr)(" swpages=%d, swpginuse=%d, swpgonly=%d, paging=%d\n", - uvmexp.swpages, uvmexp.swpginuse, uvmexp.swpgonly, uvmexp.paging); -} -#endif - #if defined(READAHEAD_STATS) #define UVM_RA_EVCNT_DEFINE(name) \ Index: sys/ddb/db_access.c =================================================================== RCS file: /cvsroot/src/sys/ddb/db_access.c,v retrieving revision 1.27 diff -p -u -r1.27 db_access.c --- sys/ddb/db_access.c 1 Sep 2023 10:55:23 -0000 1.27 +++ sys/ddb/db_access.c 28 Oct 2023 05:11:17 -0000 @@ -155,4 +155,16 @@ db_read_int(const char *name) return p; } +void +db_read_string(const char *src, size_t len, char *dst) +{ + size_t i; + + for (i = 0; i < len; i++) { + db_read_bytes((db_addr_t)&src[i], 1, &dst[i]); + if (dst[i] == '\0') + break; + } +} + #endif /* _COMPILE_THIS */ Index: sys/ddb/db_access.h =================================================================== RCS file: /cvsroot/src/sys/ddb/db_access.h,v retrieving revision 1.14 diff -p -u -r1.14 db_access.h --- sys/ddb/db_access.h 12 Sep 2019 09:20:23 -0000 1.14 +++ sys/ddb/db_access.h 28 Oct 2023 05:11:17 -0000 @@ -41,3 +41,4 @@ void db_write_bytes(db_addr_t, size_t, void *db_read_ptr(const char *); int db_read_int(const char *); +void db_read_string(const char *, size_t, char *); Index: sys/ddb/db_command.c =================================================================== RCS file: /cvsroot/src/sys/ddb/db_command.c,v retrieving revision 1.189 diff -p -u -r1.189 db_command.c --- sys/ddb/db_command.c 15 Oct 2023 10:27:33 -0000 1.189 +++ sys/ddb/db_command.c 28 Oct 2023 05:11:17 -0000 @@ -204,6 +204,11 @@ static void db_show_all_locks(db_expr_t, static void db_show_all_tstiles(db_expr_t, bool, db_expr_t, const char *); static void db_show_lockstats(db_expr_t, bool, db_expr_t, const char *); static void db_show_all_freelists(db_expr_t, bool, db_expr_t, const char *); +static void db_iostat_print_cmd(db_expr_t, bool, db_expr_t, const char *); +static void db_show_all_iostats(db_expr_t, bool, db_expr_t, const char *); +#ifdef notyet +static void db_fstrans_print_cmd(db_expr_t, bool, db_expr_t, const char *); +#endif static void db_mount_print_cmd(db_expr_t, bool, db_expr_t, const char *); static void db_show_all_mounts(db_expr_t, bool, db_expr_t, const char *); static void db_mbuf_print_cmd(db_expr_t, bool, db_expr_t, const char *); @@ -279,6 +284,14 @@ static const struct db_command db_show_c "Print the kqueue at address.", "[/f] address",NULL) }, { DDB_ADD_CMD("map", db_map_print_cmd, 0, "Print the vm_map at address.", "[/f] address",NULL) }, + { DDB_ADD_CMD("iostat", db_iostat_print_cmd, 0, + "Print the iostat structure at address.", "[/f] address",NULL) }, + { DDB_ADD_CMD("iostats",db_show_all_iostats, 0, + "Print all iostat structures.", "[/f]", NULL) }, +#ifdef notyet + { DDB_ADD_CMD("fstrans",db_fstrans_print_cmd, 0, + "Print the fstrans locks and state at address.", "[/am] address",NULL) }, +#endif { DDB_ADD_CMD("mbuf", db_mbuf_print_cmd, 0,NULL,NULL, "-c prints all mbuf chains") }, { DDB_ADD_CMD("module", db_show_module_cmd, 0, @@ -1056,7 +1069,6 @@ static void db_map_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) { -#ifdef _KERNEL bool full = false; if (modif[0] == 'f') @@ -1065,10 +1077,7 @@ db_map_print_cmd(db_expr_t addr, bool ha if (have_addr == false) addr = (db_expr_t)(uintptr_t)db_read_ptr("kernel_map"); - uvm_map_printit((struct vm_map *)(uintptr_t) addr, full, db_printf); -#else - db_kernelonly(); -#endif /* XXX CRASH(8) */ + db_uvm_map_print(addr, full, db_printf); } /*ARGSUSED*/ @@ -1076,17 +1085,12 @@ static void db_object_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) { -#ifdef _KERNEL /* XXX CRASH(8) */ bool full = false; if (modif[0] == 'f') full = true; - uvm_object_printit((struct uvm_object *)(uintptr_t) addr, full, - db_printf); -#else - db_kernelonly(); -#endif + db_uvmobject_print(addr, full, db_printf); } /*ARGSUSED*/ @@ -1094,16 +1098,12 @@ static void db_page_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) { -#ifdef _KERNEL /* XXX CRASH(8) */ bool full = false; if (modif[0] == 'f') full = true; - uvm_page_printit((struct vm_page *)(uintptr_t) addr, full, db_printf); -#else - db_kernelonly(); -#endif + db_page_printit(addr, full, db_printf); } /*ARGSUSED*/ @@ -1124,16 +1124,12 @@ static void db_buf_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) { -#ifdef _KERNEL /* XXX CRASH(8) */ bool full = false; if (modif[0] == 'f') full = true; - vfs_buf_print((struct buf *)(uintptr_t) addr, full, db_printf); -#else - db_kernelonly(); -#endif + db_buf_print(addr, full, db_printf); } /*ARGSUSED*/ @@ -1199,16 +1195,12 @@ static void db_vnode_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) { -#ifdef _KERNEL /* XXX CRASH(8) */ bool full = false; if (modif[0] == 'f') full = true; - vfs_vnode_print((struct vnode *)(uintptr_t) addr, full, db_printf); -#else - db_kernelonly(); -#endif + db_vnode_print(addr, full, db_printf); } /*ARGSUSED*/ @@ -1216,16 +1208,12 @@ static void db_vnode_lock_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) { -#ifdef _KERNEL /* XXX CRASH(8) */ bool full = false; if (modif[0] == 'f') full = true; - vfs_vnode_lock_print((struct vnode *)(uintptr_t) addr, full, db_printf); -#else - db_kernelonly(); -#endif + db_vnode_lock_print(addr, full, db_printf); } /*ARGSUSED*/ @@ -1242,32 +1230,96 @@ db_vmem_print_cmd(db_expr_t addr, bool h } static void -db_mount_print_cmd(db_expr_t addr, bool have_addr, +db_iostat_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) { -#ifdef _KERNEL /* XXX CRASH(8) */ bool full = false; if (modif[0] == 'f') full = true; - vfs_mount_print((struct mount *)(uintptr_t) addr, full, db_printf); + db_iostat_print((db_addr_t)addr, full); +} + +static void +db_show_all_iostats(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) +{ + bool full = false; + + if (modif[0] == 'f') + full = true; + + db_iostat_print_all(full); +} + +#ifdef notyet +static void +db_fstrans_print_cmd(db_expr_t addr, bool have_addr, + db_expr_t count, const char *modif) +{ + bool full = false; + char mode = '\0'; + int i; + + i = 0; + while (modif[i]) { + switch (modif[i]) { + case 'f': + full = true; + break; + case 'm': + case 'a': + mode = modif[i]; + break; + } + i++; + } + + if (mode != '\0' && !have_addr) { + db_printf("usage: show fstrans [/a] [/m] [addr]\n"); + db_printf("\t/a == argument is address of any lwp\n"); + db_printf("\t/m == argument is address of mount\n"); + return; + } + + if (mode == '\0' && !have_addr) { + db_fstrans_print_all(full, db_printf); + return; + } + + switch (mode) { + default: + case 'a': + db_fstrans_print_lwp((db_addr_t)addr, full, db_printf); + ;; + case 'm': + db_fstrans_print_mount((db_addr_t)addr, full, db_printf); + ;; + } +} #endif + +static void +db_mount_print_cmd(db_expr_t addr, bool have_addr, + db_expr_t count, const char *modif) +{ + bool full = false; + + if (modif[0] == 'f') + full = true; + + db_mount_print((db_addr_t)addr, full, db_printf); } static void db_show_all_mounts(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) { -#ifdef _KERNEL /* XXX CRASH(8) */ bool full = false; if (modif[0] == 'f') full = true; - vfs_mount_print_all(full, db_printf); -#else - db_kernelonly(); -#endif + db_mount_print_all(full, db_printf); } /*ARGSUSED*/ @@ -1315,11 +1367,7 @@ db_uvmexp_print_cmd(db_expr_t addr, bool db_expr_t count, const char *modif) { -#ifdef _KERNEL /* XXX CRASH(8) */ - uvmexp_print(db_printf); -#else - db_kernelonly(); -#endif + db_uvmexp_print(db_printf); } /*ARGSUSED */ @@ -1665,13 +1713,14 @@ db_whatis_cmd(db_expr_t address, bool ha { const uintptr_t addr = (uintptr_t)address; + db_printsym(addr, DB_STGY_ANY, db_printf); db_lwp_whatis(addr, db_printf); #ifdef _KERNEL /* XXX CRASH(8) */ pool_whatis(addr, db_printf); vmem_whatis(addr, db_printf); - uvm_whatis(addr, db_printf); + db_uvm_whatis(addr, db_printf); module_whatis(addr, db_printf); #else - db_kernelonly(); + db_uvm_whatis(addr, db_printf); #endif } Index: sys/ddb/db_elf.c =================================================================== RCS file: /cvsroot/src/sys/ddb/db_elf.c,v retrieving revision 1.29 diff -p -u -r1.29 db_elf.c --- sys/ddb/db_elf.c 6 Nov 2017 04:08:02 -0000 1.29 +++ sys/ddb/db_elf.c 28 Oct 2023 05:11:17 -0000 @@ -212,10 +212,15 @@ db_elf_sym_init( static char * db_elf_find_strtab(db_symtab_t *stab) { - Elf_Ehdr *elf = STAB_TO_EHDR(stab); - Elf_Shdr *shp = STAB_TO_SHDR(stab, elf); + Elf_Ehdr *elf; + Elf_Shdr *shp; int i; + elf = STAB_TO_EHDR(stab); + if (elf == NULL) + return NULL; + shp = STAB_TO_SHDR(stab, elf); + stab = &db_symtabs; /* Index: sys/ddb/db_fstrans.c =================================================================== RCS file: sys/ddb/db_fstrans.c diff -N sys/ddb/db_fstrans.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/ddb/db_fstrans.c 28 Oct 2023 05:11:17 -0000 @@ -0,0 +1,259 @@ +/* $NetBSD: $ */ + +/*- + * Copyright (c) 2022 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: $"); + +#ifndef _KERNEL +#include +#include +#define __EXPOSE_MOUNT +#endif + +#ifdef _KERNEL +#include +#else + +/* from libkern.h */ +#define container_of(PTR, TYPE, FIELD) \ + ((TYPE *)(((char *)(PTR)) - offsetof(TYPE, FIELD))) + +#endif +#define __RWLOCK_PRIVATE +#include +#include + +#include + +#define GET(src) db_get_value((db_addr_t)&(src), sizeof(src), true) +#define GETQ(src) db_get_qvalue((db_addr_t)&(src), sizeof(src), true) +#define GETP(src) ((db_addr_t)db_get_qvalue((db_addr_t)&(src), sizeof(src), false)) + +/* XXX copy from vfs_fstrans.c */ +enum fstrans_lock_type { + FSTRANS_LAZY, /* Granted while not suspended */ + FSTRANS_SHARED /* Granted while not suspending */ +}; + +struct fstrans_lwp_info { + struct fstrans_lwp_info *fli_succ; + struct lwp *fli_self; + struct mount *fli_mount; + struct fstrans_lwp_info *fli_alias; + struct fstrans_mount_info *fli_mountinfo; + int fli_trans_cnt; + int fli_alias_cnt; + int fli_cow_cnt; + enum fstrans_lock_type fli_lock_type; + LIST_ENTRY(fstrans_lwp_info) fli_list; +}; +struct fstrans_mount_info { + enum fstrans_state fmi_state; + unsigned int fmi_ref_cnt; + bool fmi_gone; + bool fmi_cow_change; + SLIST_ENTRY(fstrans_mount_info) fmi_hash; + LIST_HEAD(, fscow_handler) fmi_cow_handler; + struct mount *fmi_mount; + struct lwp *fmi_owner; +}; + +#define FSTRANS_MOUNT_HASHSIZE 32 + +static db_addr_t +db_fstrans_mount_get(db_addr_t addr) +{ + struct mount *mp = (struct mount *)addr; + struct fstrans_mount_info *fmi, *tab; + uint32_t indx; + + tab = (struct fstrans_mount_info *)db_read_ptr("fstrans_mount_hashtab"); + + for (indx = 0; indx < FSTRANS_MOUNT_HASHSIZE; ++indx) { + for (fmi = GETP( + } +} + +static db_addr_t +db_fstrans_fli_next(db_addr_t addr) +{ + struct fstrans_lwp_info FLI, *fli; + + fli = (struct fstrans_lwp_info *)db_read_ptr("fstrans_fli_head"); + if (addr != 0) { + } + + while (fli != NULL) { + db_read_bytes((db_addr_t)fli, sizeof(FLI), (char*)&FLI); + fli = FLI.fli_list.tqe_next; + } + + return (db_addr_t)(fli ? FLI. : NULL); +} + +static void +db_fstrans_print_lwp(struct lwp *l, const char *prefix, bool verbose, void (*pr)(const char *, ...)) +{ + struct fstrans_lwp_info FLI, *fli = &FLI; + struct *amp; + char sbuf[_VFS_MNAMELEN+1]; + + for (addr = db_fstrans_fli_next(0); addr; addr = db_fstrans_fli_next(addr)) { + db_read_bytes(addr, sizeof(*fli), (char *)fli); + if (fli->fli_self != l) + continue; + if (fli->fli_trans_cnt == 0 && fli->fli_cow_cnt == 0) { + if (! verbose) + continue; + } + (*pr)("%-8s", prefix); + if (verbose) + (*pr)(" @%p", fli); + if (fli->fli_mount == dead_rootmount) + (*pr)(" "); + else if (fli->fli_mount != NULL) + (*pr)(" (%s)", fli->fli_mount->mnt_stat.f_mntonname); + else + (*pr)(" NULL"); + if (fli->fli_alias != NULL) { + amp = GETP(fli->fli_alias->fli_mount); + printf(" alias"); + if (verbose) + (*pr)(" @%p", fli->fli_alias); + if (amp == NULL) + (*pr)(" NULL"); + else { + sbuf[_VFS_MNAMELEN] = '\0'; + db_read_string(&->mnt_stat.f_mntonname[0], _VFS_MNAMELEN, sbuf); + (*pr)(" (%s)", sbuf); + } + } + if (fli->fli_mountinfo && fli->fli_mountinfo->fmi_gone) + (*pr)(" gone"); + if (fli->fli_trans_cnt == 0) { + (*pr)(" -"); + } else { + switch (fli->fli_lock_type) { + case FSTRANS_LAZY: + (*pr)(" lazy"); + break; + case FSTRANS_SHARED: + (*pr)(" shared"); + break; + default: + (*pr)(" %#x", fli->fli_lock_type); + break; + } + } + (*pr)(" %d cow %d alias %d\n", + fli->fli_trans_cnt, fli->fli_cow_cnt, fli->fli_alias_cnt); + prefix[0] = '\0'; + } +} + +void +db_fstrans_print_proc(db_addr_t addr, bool verbose, void (*pr)(const char *, ...)) +{ + proc_t P; + lwp_t L; + char prefix[16]; + + db_read_bytes((db_addr_t)addr, sizeof(L), (char *)&L); + db_read_bytes((db_addr_t)L.l_proc, sizeof(P), (char *)&P); + + snprintf(prefix, sizeof(prefix), "%d.%d", P.p_pid, L.l_lid); + db_fstrans_print_lwp(&L, prefix, verbose, pr); +} + +void +db_fstrans_print_mount(db_addr_t addr, bool verbose, void (*pr)(const char *, ...)) +{ + struct mount *mp = (struct mount *)addr; + uint32_t indx; + struct fstrans_mount_info *fmi; + char sbuf[_VFS_MNAMELEN+1]; + + indx = fstrans_mount_hash(mp); + SLIST_FOREACH(fmi, &fstrans_mount_hashtab[indx], fmi_hash) + if (fmi->fmi_mount == mp) + break; + + if (!verbose && (fmi == NULL || fmi->fmi_state == FSTRANS_NORMAL)) + return; + + sbuf[_VFS_MNAMELEN] = '\0'; + db_read_string(&mp->mnt_stat.f_mntonname[0], _VFS_MNAMELEN, sbuf); + (+pr)("%-16s ", sbuf); + if (fmi == NULL) { + printf("(null)\n"); + return; + } + (+pr)("owner %p ", fmi->fmi_owner); + switch (fmi->fmi_state) { + case FSTRANS_NORMAL: + (+pr)("state normal\n"); + break; + case FSTRANS_SUSPENDING: + (+pr)("state suspending\n"); + break; + case FSTRANS_SUSPENDED: + (+pr)("state suspended\n"); + break; + default: + (+pr)("state %#x\n", fmi->fmi_state); + break; + } +} + +void +db_fstrans_print_all(bool verbose, void (*pr)(const char *, ...)) +{ + const struct proclist_desc *pd; + proc_t p, *pp; + struct lwp l, *lp; + db_addr_t addr; + + (*pr)("Fstrans locks by lwp:\n"); + + for (pd = db_proclist_first(); pd != NULL; pd = db_proclist_next(pd)) { + for (p = db_proclist_proc_first(pd); p != NULL; p = db_proc_next(p)) { + db_fstrans_print_proc(p, verbose, pr); + for (l = db_lwp_first(p); l; l = db_lwp_next(l)) { + db_read_bytes((db_addr_t)l, sizeof(L), (char *)&L); + snprintf(prefix, sizeof(prefix), "%d.%d", p->p_pid, L.l_lid); + db_fstrans_print_lwp(l, prefix); + } + } + } + + (*pr)("Fstrans state by mount:\n"); + + for (addr = db_mountlist_next(0); addr; addr = db_mountlist_next(addr)) + db_fstrans_print_mount((struct mount *)addr, verbose, pr); +} + Index: sys/ddb/db_interface.h =================================================================== RCS file: /cvsroot/src/sys/ddb/db_interface.h,v retrieving revision 1.42 diff -p -u -r1.42 db_interface.h --- sys/ddb/db_interface.h 13 Oct 2023 19:07:08 -0000 1.42 +++ sys/ddb/db_interface.h 28 Oct 2023 05:11:17 -0000 @@ -45,6 +45,42 @@ void db_kgdb_cmd(db_expr_t, bool, db_ex void db_show_files_cmd(db_expr_t, bool, db_expr_t, const char *); void db_show_panic(db_expr_t, bool, db_expr_t, const char *); +/* ddb/db_iostat.c */ +db_addr_t db_iostat_next(db_addr_t); +void db_iostat_print(db_addr_t, bool); +void db_iostat_print_all(bool); + +/* ddb/db_vfs.c */ +db_addr_t db_mountlist_next(db_addr_t); +void db_mount_print(db_addr_t, bool, + void (*)(const char *, ...) __printflike(1,2)); +void db_mount_print_all(bool, + void (*)(const char *, ...) __printflike(1,2)); +void db_buf_print(db_addr_t, bool, + void (*)(const char *, ...) __printflike(1,2)); +void db_vnode_print(db_addr_t, bool, + void (*)(const char *, ...) __printflike(1,2)); +void db_vnode_lock_print(db_addr_t, bool, + void (*)(const char *, ...) __printflike(1,2)); +void db_fstrans_print_lwp(db_addr_t, bool, + void (*)(const char *, ...) __printflike(1,2)); +void db_fstrans_print_mount(db_addr_t, bool, + void (*)(const char *, ...) __printflike(1,2)); +void db_fstrans_print_all(bool, + void (*)(const char *, ...) __printflike(1,2)); + +/* ddb/db_uvm.c */ +void db_uvmobject_print(db_addr_t, bool, + void (*)(const char *, ...) __printflike(1,2)); +void db_uvm_whatis(db_addr_t, + void (*)(const char *, ...) __printflike(1,2)); +void db_uvm_map_print(db_addr_t, bool, + void (*)(const char *, ...) __printflike(1,2)); +void db_uvmexp_print( + void (*)(const char *, ...) __printflike(1,2)); +void db_page_printit(db_addr_t, bool, + void (*)(const char *, ...) __printflike(1,2)); + /* kern/kern_proc.c */ void db_kill_proc(db_expr_t, bool, db_expr_t, const char *); void db_show_proc(db_expr_t, bool, db_expr_t, const char *); Index: sys/ddb/db_iostat.c =================================================================== RCS file: sys/ddb/db_iostat.c diff -N sys/ddb/db_iostat.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/ddb/db_iostat.c 28 Oct 2023 05:11:17 -0000 @@ -0,0 +1,200 @@ +/* $NetBSD: $ */ + +/*- + * Copyright (c) 2022 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: $"); + +#ifndef _KERNEL +#include +#include +#define __EXPOSE_MOUNT +#endif + +#include +#include + +#include + +/* + * Unlocked variant to traverse the iostatlist. + * To be used from DDB only. + */ +db_addr_t +db_iostat_next(db_addr_t addr) +{ + db_expr_t e1; + struct io_stats *stats; + TAILQ_HEAD(, io_stats) h; + TAILQ_ENTRY(io_stats) e; + + stats = (struct io_stats *)addr; + + if (stats == 0) { + if (!db_value_of_name("iostatlist", &e1)) { + db_printf("db_iostat_next: cannot find `iostatlist'\n"); + db_error(NULL); + /* NOTREACHED */ + } + db_read_bytes((db_addr_t)e1, sizeof(h), (char*)&h); + stats = h.tqh_first; + } else { + db_read_bytes((db_addr_t)&stats->io_link, sizeof(e), (char*)&e); + stats = e.tqe_next; + } + + return (db_addr_t)stats; +} + +#define GET(src) db_get_value((db_addr_t)&(src), sizeof(src), true) +#define GETQ(src) db_get_qvalue((db_addr_t)&(src), sizeof(src), true) +#define GETP(src) ((db_addr_t)db_get_qvalue((db_addr_t)&(src), sizeof(src), false)) + +static const char * +iostat_type_name(int type) +{ + const char *s; + + switch (type) { + case IOSTAT_DISK: + s = "DISK"; + break; + case IOSTAT_TAPE: + s = "TAPE"; + break; + case IOSTAT_NFS: + s = "NFS"; + break; + default: + s = "???"; + break; + } + + return s; +} + +void +db_iostat_print(db_addr_t addr, bool full) +{ + struct io_stats *io; + char sbuf[IOSTATNAMELEN+1]; + + io = (struct io_stats *)addr; + + sbuf[IOSTATNAMELEN] = '\0'; + db_read_string(&io->io_name[0], sizeof(io->io_name), sbuf); + db_printf("%"PRIxPTR" %s\n", (uintptr_t)io, sbuf); + + db_printf("\tparent = %"PRIxPTR"\n", + (uintptr_t)GETP(io->io_parent)); + db_printf("\tnext = %"PRIxPTR"\n", + (uintptr_t)GETP(io->io_link.tqe_next)); + + db_printf("\ttype = %s\n", iostat_type_name(GET(io->io_type))); + + db_printf("\tbusy = %d\n", (int)GET(io->io_busy)); + db_printf("\twait = %d\n", (int)GET(io->io_wait)); + + db_printf("\trxfer = %"PRIu64"\n", (u_quad_t)GET(io->io_rxfer)); + db_printf("\twxfer = %"PRIu64"\n", (u_quad_t)GET(io->io_wxfer)); + db_printf("\tseek = %"PRIu64"\n", (u_quad_t)GET(io->io_seek)); + db_printf("\trbytes = %"PRIu64"\n", (u_quad_t)GET(io->io_rbytes)); + db_printf("\twbytes = %"PRIu64"\n", (u_quad_t)GET(io->io_wbytes)); + + if (full) { + db_printf("\tattachtime = %"PRIu64".%06"PRIu64"\n", + (u_quad_t)GETQ(io->io_attachtime.tv_sec), + (u_quad_t)GETQ(io->io_attachtime.tv_usec)); + db_printf("\twaitstamp = %"PRIu64".%06"PRIu64"\n", + (u_quad_t)GETQ(io->io_waitstamp.tv_sec), + (u_quad_t)GETQ(io->io_waitstamp.tv_usec)); + db_printf("\tbusystamp = %"PRIu64".%06"PRIu64"\n", + (u_quad_t)GETQ(io->io_busystamp.tv_sec), + (u_quad_t)GETQ(io->io_busystamp.tv_usec)); + db_printf("\ttimestamp = %"PRIu64".%06"PRIu64"\n", + (u_quad_t)GETQ(io->io_timestamp.tv_sec), + (u_quad_t)GETQ(io->io_timestamp.tv_usec)); + + db_printf("\tbusysum = %"PRIu64".%06"PRIu64"\n", + (u_quad_t)GETQ(io->io_busysum.tv_sec), + (u_quad_t)GETQ(io->io_busysum.tv_usec)); + db_printf("\twaitsum = %"PRIu64".%06"PRIu64"\n", + (u_quad_t)GETQ(io->io_waitsum.tv_sec), + (u_quad_t)GETQ(io->io_waitsum.tv_usec)); + + db_printf("\twaittime = %"PRIu64".%06"PRIu64"\n", + (u_quad_t)GETQ(io->io_waittime.tv_sec), + (u_quad_t)GETQ(io->io_waittime.tv_usec)); + + db_printf("\tbusytime = %"PRIu64".%06"PRIu64"\n", + (u_quad_t)GETQ(io->io_busytime.tv_sec), + (u_quad_t)GETQ(io->io_busytime.tv_usec)); + } +} + +static void +db_iostat_print_one(db_addr_t addr, bool full) +{ + struct io_stats *io; + char sbuf[IOSTATNAMELEN+1]; + const char *typ; + + io = (struct io_stats *)addr; + + sbuf[IOSTATNAMELEN] = '\0'; + db_read_string(&io->io_name[0], sizeof(io->io_name), sbuf); + + typ = iostat_type_name(GET(io->io_type)); + + db_printf("%-18"PRIxPTR" %-18"PRIxPTR" %-4s %8d %8d %s\n", + (uintptr_t)io, + (uintptr_t)GETP(io->io_parent), + typ, + (int)GET(io->io_busy), + (int)GET(io->io_wait), + sbuf); +} + +void +db_iostat_print_all(bool full) +{ + db_addr_t addr; + + if (full) { + for (addr = db_iostat_next(0); addr; + addr = db_iostat_next(addr)) { + db_iostat_print(addr, full); + } + return; + } + + db_printf("%-18s %-18s %-4s %8s %8s %s\n", + "ADDR","PARENT","TYPE","BUSY","WAIT","NAME"); + + for (addr = db_iostat_next(0); addr; addr = db_iostat_next(addr)) + db_iostat_print_one(addr, full); +} Index: sys/ddb/db_proc.c =================================================================== RCS file: /cvsroot/src/sys/ddb/db_proc.c,v retrieving revision 1.14 diff -p -u -r1.14 db_proc.c --- sys/ddb/db_proc.c 11 Jan 2021 07:49:04 -0000 1.14 +++ sys/ddb/db_proc.c 28 Oct 2023 05:11:17 -0000 @@ -76,6 +76,41 @@ __KERNEL_RCSID(0, "$NetBSD: db_proc.c,v #include +struct proclist_desc * +db_proclist_first(void) +{ + + return db_read_ptr("proclists"); +} + +struct proclist_desc * +db_proclist_next(struct proclist_desc *pd) +{ + struct proclist *pl; + + if (pd == NULL) + return NULL; + + pd += 1; + db_read_bytes((db_addr_t)&pd->pd_list, sizeof(pl), (char *)&pl); + + if (pl == NULL) + return NULL; + + return pd; +} + +proc_t * +db_proclist_proc_first(struct proclist_desc *pd) +{ + struct proclist *pp; + proc_t *p; + + db_read_bytes((db_addr_t)&pd->pd_list, sizeof(pp), (char *)&pp); + db_read_bytes((db_addr_t)&pp->lh_first, sizeof(p), (char *)&p); + return p; +} + proc_t * db_proc_first(void) { @@ -107,18 +142,6 @@ db_proc_find(pid_t pid) return NULL; } -static void -db_read_string(const char *src, size_t len, char *dst) -{ - size_t i; - - for (i = 0; i < len; i++) { - db_read_bytes((db_addr_t)&src[i], 1, &dst[i]); - if (dst[i] == '\0') - break; - } -} - void db_show_all_procs(db_expr_t addr, bool haddr, db_expr_t count, const char *modif) @@ -127,23 +150,40 @@ db_show_all_procs(db_expr_t addr, bool h static proc_t p; static lwp_t l; const char *mode, *ename; + bool running, tstiled; proc_t *pp; lwp_t *lp; char db_nbuf[MAXCOMLEN + 1], wbuf[MAXCOMLEN + 1]; - bool run; + bool run, tstile; int cpuno; - if (modif[0] == 0) - mode = "l"; /* default == lwp mode */ - else - mode = strchr("mawln", modif[0]); + running = false; + tstiled = false; + if (modif[0] == 0) { + mode = "l"; + } else { + mode = NULL; + while (*modif) { + if (mode == NULL) + mode = strchr("mawln", *modif); + if (*modif == 'R') + running = true; + if (*modif == 'T') + tstiled = true; + ++modif; + } + if (mode == NULL && (running || tstiled)) + mode = "l"; + } if (mode == NULL || *mode == 'm') { - db_printf("usage: show all procs [/a] [/l] [/n] [/w]\n"); + db_printf("usage: show all procs [/a] [/l] [/n] [/w] [/R] [/T]\n"); db_printf("\t/a == show process address info\n"); db_printf("\t/l == show LWP info [default]\n"); db_printf("\t/n == show normal process info\n"); db_printf("\t/w == show process wait/emul info\n"); + db_printf("\t/R == show processes on cpu\n"); + db_printf("\t/T == show processes waiting for mutex\n"); return; } @@ -153,15 +193,15 @@ db_show_all_procs(db_expr_t addr, bool h "COMMAND", "STRUCT PROC *", "UAREA *", "VMSPACE/VM_MAP"); break; case 'l': - db_printf("PID %4s S %3s %9s %18s %18s %-8s\n", + db_printf("PID %5s S %3s %9s %18s %18s %-8s\n", "LID", "CPU", "FLAGS", "STRUCT LWP *", "NAME", "WAIT"); break; case 'n': - db_printf("PID %8s %8s %10s S %7s %4s %16s %7s\n", + db_printf("PID %8s %8s %10s S %7s %4s %16s %7s\n", "PPID", "PGRP", "UID", "FLAGS", "LWPS", "COMMAND", "WAIT"); break; case 'w': - db_printf("PID %4s %16s %8s %4s %-12s%s\n", + db_printf("PID %5s %16s %8s %4s %-12s %s\n", "LID", "COMMAND", "EMUL", "PRI", "WAIT-MSG", "WAIT-CHANNEL"); break; @@ -176,12 +216,11 @@ db_show_all_procs(db_expr_t addr, bool h if (lp != NULL) { db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l); } - db_printf("%-5d", p.p_pid); switch (*mode) { case 'a': - db_printf(" %-16.16s %18lx %18lx %18lx\n", - p.p_comm, (long)pp, + db_printf("%-5d %-16.16s %18lx %18lx %18lx\n", + p.p_pid, p.p_comm, (long)pp, (long)(lp != NULL ? l.l_addr : 0), (long)p.p_vmspace); break; @@ -195,8 +234,6 @@ db_show_all_procs(db_expr_t addr, bool h strlcpy(db_nbuf, p.p_comm, sizeof(db_nbuf)); } - run = (l.l_stat == LSONPROC || - (l.l_pflag & LP_RUNNING) != 0); if (l.l_cpu != NULL) { db_read_bytes((db_addr_t) &l.l_cpu->ci_data.cpu_index, @@ -210,13 +247,20 @@ db_show_all_procs(db_expr_t addr, bool h } else { wbuf[0] = '\0'; } - db_printf("%c%4d %d %3d %9x %18lx %18s %-8s\n", - (run ? '>' : ' '), l.l_lid, - l.l_stat, cpuno, l.l_flag, (long)lp, - db_nbuf, wbuf); + tstile = (l.l_stat == LSSLEEP && + strcmp(wbuf, "tstile") == 0); + run = (l.l_stat == LSONPROC || + (l.l_pflag & LP_RUNNING) != 0); + if (!(running || tstiled) || + (running && run) || + (tstiled && tstile)) { + db_printf("%-5d%c%5d %d %3d %9x %18lx %18s %-8s\n", + p.p_pid, (run ? '>' : ' '), l.l_lid, + l.l_stat, cpuno, l.l_flag, (long)lp, + db_nbuf, wbuf); + } lp = LIST_NEXT((&l), l_sibling); if (lp != NULL) { - db_printf("%-5d", p.p_pid); db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l); } @@ -232,7 +276,8 @@ db_show_all_procs(db_expr_t addr, bool h } else { wbuf[0] = '\0'; } - db_printf("%8d %8d %10d %d %#7x %4d %16s %7.7s\n", + db_printf("%-5d%8d %8d %10d %d %#7x %4d %16s %7.7s\n", + p.p_pid, p.p_pptr != NULL ? p.p_pptr->p_pid : -1, pgrp.pg_id, #ifdef _KERNEL kauth_cred_getuid(p.p_cred), @@ -253,6 +298,8 @@ db_show_all_procs(db_expr_t addr, bool h } else { wbuf[0] = '\0'; } + tstile = (l.l_stat == LSSLEEP && + strcmp(wbuf, "tstile") == 0); run = (l.l_stat == LSONPROC || (l.l_pflag & LP_RUNNING) != 0); db_read_bytes((db_addr_t)&p.p_emul->e_name, @@ -261,14 +308,19 @@ db_show_all_procs(db_expr_t addr, bool h db_read_string(ename, sizeof(db_nbuf), db_nbuf); db_nbuf[MAXCOMLEN] = '\0'; - db_printf( - "%c%4d %16s %8s %4d %-12s %-18lx\n", - (run ? '>' : ' '), l.l_lid, - p.p_comm, db_nbuf, - l.l_priority, wbuf, (long)l.l_wchan); + if (!(running || tstiled) || + (running && run) || + (tstiled && tstile)) { + db_printf( + "%-5d%c%5d %16s %8s %4d %-12s %-18lx\n", + p.p_pid, + (run ? '>' : ' '), l.l_lid, + p.p_comm, db_nbuf, + l.l_priority, wbuf, + (long)l.l_wchan); + } lp = LIST_NEXT((&l), l_sibling); if (lp != NULL) { - db_printf("%-5d", p.p_pid); db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l); } Index: sys/ddb/db_proc.h =================================================================== RCS file: /cvsroot/src/sys/ddb/db_proc.h,v retrieving revision 1.1 diff -p -u -r1.1 db_proc.h --- sys/ddb/db_proc.h 7 Mar 2009 22:02:17 -0000 1.1 +++ sys/ddb/db_proc.h 28 Oct 2023 05:11:17 -0000 @@ -32,6 +32,10 @@ #ifndef _DDB_DB_PROC_H_ #define _DDB_DB_PROC_H_ +struct proclist_desc *db_proclist_first(void); +struct proclist_desc *db_proclist_next(struct proclist_desc *); +struct proc *db_proclist_proc_first(struct proclist_desc *); + struct proc *db_proc_first(void); struct proc *db_proc_next(struct proc *); struct proc *db_proc_find(pid_t); Index: sys/ddb/db_uvm.c =================================================================== RCS file: sys/ddb/db_uvm.c diff -N sys/ddb/db_uvm.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/ddb/db_uvm.c 28 Oct 2023 05:11:17 -0000 @@ -0,0 +1,458 @@ +/* $NetBSD: $ */ + +/*- + * Copyright (c) 2022 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: $"); + +#ifndef _KERNEL +#include +#include +#endif + +#ifdef _KERNEL +#include +#include +#endif + +#define __RWLOCK_PRIVATE +#include + +#include +#include +#ifdef _KERNEL +#include +#endif + +#include + +/* + * kern_rwlock.c + */ +static int +db_rw_write_held(krwlock_t *rw) +{ + krwlock_t RW; + + db_read_bytes((db_addr_t)rw, sizeof(RW), (char *)&RW); + return (RW.rw_owner & RW_WRITE_LOCKED) != 0; +} + +static void +db_uvm_pagearray_print(struct uvm_object *uobj, void (*pr)(const char *, ...)) +{ +#ifdef _KERNEL + struct uvm_page_array a; + struct vm_page *pg; + int cnt = 0; + voff_t off; + + (*pr)(" PAGES :\n "); + uvm_page_array_init(&a, uobj, 0); + off = 0; + while ((pg = uvm_page_array_fill_and_peek(&a, off, 0)) != NULL) { + cnt++; + (*pr)("<%p,0x%llx> ", pg, (long long)pg->offset); + if ((cnt % 3) == 0) { + (*pr)("\n "); + } + off = pg->offset + PAGE_SIZE; + uvm_page_array_advance(&a); + } + if ((cnt % 3) != 0) { + (*pr)("\n"); + } + uvm_page_array_fini(&a); +#endif +} + +void +db_uvmobject_print(db_addr_t addr, bool full, void (*pr)(const char *, ...)) +{ + struct uvm_object *uobj, U; + + uobj = (struct uvm_object *) addr; + db_read_bytes(addr, sizeof(U), (char *)&U); + + (*pr)("OBJECT %p: locked=%d, pgops=%p, npages=%d, ", + uobj, db_rw_write_held(U.vmobjlock), U.pgops, U.uo_npages); + + if (UVM_OBJ_IS_KERN_OBJECT(&U)) + (*pr)("refs=\n"); + else + (*pr)("refs=%d\n", U.uo_refs); + + db_uvm_pagearray_print(uobj, pr); +} + +#define ROOT_ENTRY(map, e) db_read_bytes((db_addr_t)&(map)->rb_tree.rbt_root, sizeof(e), (char *)&(e)) +#define LEFT_ENTRY(n, e) db_read_bytes((db_addr_t)&(n)->rb_node.rb_left, sizeof(e), (char *)&(e)) +#define RIGHT_ENTRY(n, e) db_read_bytes((db_addr_t)&(n)->rb_node.rb_right, sizeof(e), (char *)&(e)) + +static bool +db_uvm_map_lookup_entry_bytree(struct vm_map *map, vaddr_t address, + struct vm_map_entry **entry) +{ + struct vm_map_entry CUR, *prev, *cur; + + prev = &map->header; + ROOT_ENTRY(map, cur); + + while (cur) { + db_read_bytes((db_addr_t)cur, sizeof(CUR), (char *)&CUR); + if (address >= CUR.start) { + if (address < CUR.end) { + *entry = cur; + return true; + } + prev = cur; + RIGHT_ENTRY(cur, cur); + } else + LEFT_ENTRY(cur, cur); + } + *entry = prev; + return false; +} + +void +db_uvm_whatis(db_addr_t addr, void (*pr)(const char *, ...)) +{ + struct vm_map *map; + + for (map = (struct vm_map*)db_read_ptr("kernel_map");;) { + struct vm_map_entry E, *entry; + + if (!db_uvm_map_lookup_entry_bytree(map, (vaddr_t)addr, &entry)) { + break; + } + db_read_bytes((db_addr_t)entry, sizeof(E), (char *)&E); + + (*pr)("%p is %p+%zu from VMMAP %p\n", + (void *)addr, (void *)E.start, + (size_t)(addr - (uintptr_t)E.start), map); + /* !UVM_ET_ISSUBMAP(entry) */ + if ((E.etype & UVM_ET_SUBMAP) == 0) { + break; + } + map = E.object.sub_map; + } +} + +void +db_uvm_map_print(db_addr_t addr, bool full, void (*pr)(const char *, ...)) +{ + struct vm_map M, *map; + struct vm_map_entry E, *entry; + + map = (struct vm_map *)addr; + + db_read_bytes(addr, sizeof(M), (char *)&M); + + (*pr)("MAP %p: [%#lx->%#lx]\n", map, vm_map_min(&M), + vm_map_max(&M)); + (*pr)("\t#ent=%d, sz=%lu, ref=%d, version=%d, flags=%#x\n", + M.nentries, (unsigned long)M.size, M.ref_count, M.timestamp, + M.flags); +#if defined(_KERNEL) + (*pr)("\tpmap=%p(resident=%ld, wired=%ld)\n", M.pmap, + pmap_resident_count(M.pmap), pmap_wired_count(M.pmap)); +#else + (*pr)("\tpmap=%p(resident=?, wired=?)\n", M.pmap); +#endif + if (!full) + return; + + db_read_bytes((db_addr_t)&map->header, sizeof(E), (char *)&E); + for (entry = E.next; entry != &map->header; + entry = E.next) { + db_read_bytes((db_addr_t)entry, sizeof(E), (char *)&E); + + (*pr)(" - %p: %#lx->%#lx: obj=%p/%#llx, amap=%p/%d\n", + entry, E.start, E.end, E.object.uvm_obj, + (long long)E.offset, E.aref.ar_amap, + E.aref.ar_pageoff); + (*pr)( + "\tsubmap=%c, cow=%c, nc=%c, prot(max)=%d/%d, inh=%d, " + "wc=%d, adv=%d%s\n", + (E.etype & UVM_ET_SUBMAP) ? 'T' : 'F', + (E.etype & UVM_ET_COPYONWRITE) ? 'T' : 'F', + (E.etype & UVM_ET_NEEDSCOPY) ? 'T' : 'F', + E.protection, E.max_protection, + E.inheritance, E.wired_count, E.advice, + entry == M.first_free ? " (first_free)" : ""); + } +} + +void +db_uvmexp_print(void (*pr)(const char *, ...)) +{ + int64_t anonpg, execpg, filepg; + int active, inactive; + int poolpages, freepg; + db_expr_t e1; + struct uvmexp U; + + if (!db_value_of_name("uvmexp", &e1)) { + db_printf("db_uvmexp_print: cannot find `uvmexp'\n"); + db_error(NULL); + /* NOTREACHED */ + } + db_read_bytes((db_addr_t)e1, sizeof(U), (char*)&U); + +#ifdef _KERNEL + + uvm_estimatepageable(&active, &inactive); + poolpages = pool_totalpages_locked(); + + /* this will sync all counters. */ + freepg = uvm_availmem(false); + + anonpg = cpu_count_get(CPU_COUNT_ANONCLEAN) + + cpu_count_get(CPU_COUNT_ANONDIRTY) + + cpu_count_get(CPU_COUNT_ANONUNKNOWN); + execpg = cpu_count_get(CPU_COUNT_EXECPAGES); + filepg = cpu_count_get(CPU_COUNT_FILECLEAN) + + cpu_count_get(CPU_COUNT_FILEDIRTY) + + cpu_count_get(CPU_COUNT_FILEUNKNOWN) - + execpg; + +#else + + active = inactive = 0; + poolpages = 0; + freepg = U.free; + anonpg = U.anonpages; + execpg = U.execpages; + filepg = U.filepages; + +#endif + + (*pr)("Current UVM status:\n"); + (*pr)(" pagesize=%d (0x%x), pagemask=0x%x, pageshift=%d, ncolors=%d\n", + U.pagesize, U.pagesize, U.pagemask, + U.pageshift, U.ncolors); + (*pr)(" %d VM pages: %d active, %d inactive, %d wired, %d free\n", + U.npages, active, inactive, U.wired, freepg); + (*pr)(" pages %" PRId64 " anon, %" PRId64 " file, %" PRId64 " exec\n", + anonpg, filepg, execpg); + (*pr)(" freemin=%d, free-target=%d, wired-max=%d\n", + U.freemin, U.freetarg, U.wiredmax); + (*pr)(" resv-pg=%d, resv-kernel=%d\n", + U.reserve_pagedaemon, U.reserve_kernel); + (*pr)(" bootpages=%d, poolpages=%d\n", + U.bootpages, poolpages); + +#ifdef _KERNEL + + (*pr)(" faults=%" PRId64 ", traps=%" PRId64 ", " + "intrs=%" PRId64 ", ctxswitch=%" PRId64 "\n", + cpu_count_get(CPU_COUNT_NFAULT), + cpu_count_get(CPU_COUNT_NTRAP), + cpu_count_get(CPU_COUNT_NINTR), + cpu_count_get(CPU_COUNT_NSWTCH)); + (*pr)(" softint=%" PRId64 ", syscalls=%" PRId64 "\n", + cpu_count_get(CPU_COUNT_NSOFT), + cpu_count_get(CPU_COUNT_NSYSCALL)); + + (*pr)(" fault counts:\n"); + (*pr)(" noram=%" PRId64 ", noanon=%" PRId64 ", pgwait=%" PRId64 + ", pgrele=%" PRId64 "\n", + cpu_count_get(CPU_COUNT_FLTNORAM), + cpu_count_get(CPU_COUNT_FLTNOANON), + cpu_count_get(CPU_COUNT_FLTPGWAIT), + cpu_count_get(CPU_COUNT_FLTPGRELE)); + (*pr)(" ok relocks(total)=%" PRId64 "(%" PRId64 "), " + "anget(retrys)=%" PRId64 "(%" PRId64 "), amapcopy=%" PRId64 "\n", + cpu_count_get(CPU_COUNT_FLTRELCKOK), + cpu_count_get(CPU_COUNT_FLTRELCK), + cpu_count_get(CPU_COUNT_FLTANGET), + cpu_count_get(CPU_COUNT_FLTANRETRY), + cpu_count_get(CPU_COUNT_FLTAMCOPY)); + (*pr)(" neighbor anon/obj pg=%" PRId64 "/%" PRId64 + ", gets(lock/unlock)=%" PRId64 "/%" PRId64 "\n", + cpu_count_get(CPU_COUNT_FLTNAMAP), + cpu_count_get(CPU_COUNT_FLTNOMAP), + cpu_count_get(CPU_COUNT_FLTLGET), + cpu_count_get(CPU_COUNT_FLTGET)); + (*pr)(" cases: anon=%" PRId64 ", anoncow=%" PRId64 ", obj=%" PRId64 + ", prcopy=%" PRId64 ", przero=%" PRId64 "\n", + cpu_count_get(CPU_COUNT_FLT_ANON), + cpu_count_get(CPU_COUNT_FLT_ACOW), + cpu_count_get(CPU_COUNT_FLT_OBJ), + cpu_count_get(CPU_COUNT_FLT_PRCOPY), + cpu_count_get(CPU_COUNT_FLT_PRZERO)); + +#else + + (*pr)(" faults=%" PRId64 ", traps=%" PRId64 ", " + "intrs=%" PRId64 ", ctxswitch=%" PRId64 "\n", + U.faults, U.traps, U.intrs, U.swtch); + (*pr)(" softint=%" PRId64 ", syscalls=%" PRId64 "\n", + U.softs, U.syscalls); + + (*pr)(" fault counts:\n"); + (*pr)(" noram=%" PRId64 ", noanon=%" PRId64 ", pgwait=%" PRId64 + ", pgrele=%" PRId64 "\n", + U.fltnoram, U.fltnoanon, U.fltpgwait, U.fltpgrele); + (*pr)(" ok relocks(total)=%" PRId64 "(%" PRId64 "), " + "anget(retrys)=%" PRId64 "(%" PRId64 "), amapcopy=%" PRId64 "\n", + U.fltrelckok, U.fltrelck, U.fltanget, U.fltanretry, U.fltamcopy); + (*pr)(" neighbor anon/obj pg=%" PRId64 "/%" PRId64 + ", gets(lock/unlock)=%" PRId64 "/%" PRId64 "\n", + U.fltnamap, U.fltnomap, U.fltlget, U.fltget); + (*pr)(" cases: anon=%" PRId64 ", anoncow=%" PRId64 ", obj=%" PRId64 + ", prcopy=%" PRId64 ", przero=%" PRId64 "\n", + U.flt_anon, U.flt_acow, U.flt_obj, U.flt_prcopy, U.flt_przero); + +#endif + + (*pr)(" daemon and swap counts:\n"); + (*pr)(" woke=%d, revs=%d, scans=%d, obscans=%d, anscans=%d\n", + U.pdwoke, U.pdrevs, U.pdscans, U.pdobscan, + U.pdanscan); + (*pr)(" busy=%d, freed=%d, reactivate=%d, deactivate=%d\n", + U.pdbusy, U.pdfreed, U.pdreact, U.pddeact); + (*pr)(" pageouts=%d, pending=%d, nswget=%d\n", U.pdpageouts, + U.pdpending, U.nswget); + (*pr)(" nswapdev=%d, swpgavail=%d\n", + U.nswapdev, U.swpgavail); + (*pr)(" swpages=%d, swpginuse=%d, swpgonly=%d, paging=%d\n", + U.swpages, U.swpginuse, U.swpgonly, U.paging); +} + +/* from uvm_page.h */ + +#define UVM_PHYSADDR_BUCKET __BITS(5,9) +#define UVM_PHYSADDR_FREELIST __BITS(0,4) + +static int +db_page_get_bucket(struct vm_page *pg) +{ + + return __SHIFTOUT(pg->phys_addr, UVM_PHYSADDR_BUCKET); +} + +static int +db_page_get_freelist(struct vm_page *pg) +{ + + return __SHIFTOUT(pg->phys_addr, UVM_PHYSADDR_FREELIST); +} + +static paddr_t +db_vm_page_to_phys(const struct vm_page *pg) +{ + + return pg->phys_addr & ~(PAGE_SIZE - 1); +} + +#define DB_VM_PAGE_TO_PHYS(entry) db_vm_page_to_phys(entry) + +static const char page_flagbits[] = UVM_PGFLAGBITS; +static const char page_pqflagbits[] = UVM_PQFLAGBITS; + +void +db_page_printit(db_addr_t addr, bool full, void (*pr)(const char *, ...)) +{ + struct vm_page *pg, PG; +#ifdef _KERNEL + struct vm_page *tpg; + struct uvm_object *uobj; + struct pgflbucket *pgb; + struct pgflist *pgl; +#endif + char pgbuf[128]; + + pg = (struct vm_page *) addr; + db_read_bytes(addr, sizeof(PG), (char *)&PG); + + (*pr)("PAGE %p:\n", pg); + snprintb(pgbuf, sizeof(pgbuf), page_flagbits, PG.flags); + (*pr)(" flags=%s\n", pgbuf); + snprintb(pgbuf, sizeof(pgbuf), page_pqflagbits, PG.pqflags); + (*pr)(" pqflags=%s\n", pgbuf); + (*pr)(" uobject=%p, uanon=%p, offset=0x%llx\n", + PG.uobject, PG.uanon, (long long)PG.offset); + (*pr)(" loan_count=%d wire_count=%d bucket=%d freelist=%d\n", + PG.loan_count, PG.wire_count, db_page_get_bucket(&PG), + db_page_get_freelist(&PG)); + (*pr)(" pa=0x%lx\n", (long)DB_VM_PAGE_TO_PHYS(&PG)); +#if defined(UVM_PAGE_TRKOWN) + if (PG.flags & PG_BUSY) + (*pr)(" owning process = %d.%d, tag=%s\n", + PG.owner, PG.lowner, PG.owner_tag); + else + (*pr)(" page not busy, no owner\n"); +#else + (*pr)(" [page ownership tracking disabled]\n"); +#endif + + if (!full) + return; + +#ifdef _KERNEL + /* cross-verify object/anon */ + if ((pg->flags & PG_FREE) == 0) { + if (pg->flags & PG_ANON) { + if (pg->uanon == NULL || pg->uanon->an_page != pg) + (*pr)(" >>> ANON DOES NOT POINT HERE <<< (%p)\n", + (pg->uanon) ? pg->uanon->an_page : NULL); + else + (*pr)(" anon backpointer is OK\n"); + } else { + uobj = PG.uobject; + if (uobj) { + (*pr)(" checking object list\n"); + tpg = uvm_pagelookup(uobj, pg->offset); + if (tpg) + (*pr)(" page found on object list\n"); + else + (*pr)(" >>> PAGE NOT FOUND ON OBJECT LIST! <<<\n"); + } + } + } + + /* cross-verify page queue */ + if (PG.flags & PG_FREE) { + int fl = db_page_get_freelist(pg); + int b = db_page_get_bucket(pg); + pgb = uvm.page_free[fl].pgfl_buckets[b]; + pgl = &pgb->pgb_colors[VM_PGCOLOR(pg)]; + (*pr)(" checking pageq list\n"); + LIST_FOREACH(tpg, pgl, pageq.list) { + if (tpg == pg) { + break; + } + } + if (tpg) + (*pr)(" page found on pageq list\n"); + else + (*pr)(" >>> PAGE NOT FOUND ON PAGEQ LIST! <<<\n"); + } +#endif +} + Index: sys/ddb/db_variables.c =================================================================== RCS file: /cvsroot/src/sys/ddb/db_variables.c,v retrieving revision 1.47 diff -p -u -r1.47 db_variables.c --- sys/ddb/db_variables.c 10 Mar 2020 15:58:37 -0000 1.47 +++ sys/ddb/db_variables.c 28 Oct 2023 05:11:17 -0000 @@ -324,6 +324,15 @@ db_set_cmd(db_expr_t addr, bool have_add int t; t = db_read_token(); + if (t == tEOL) { + for (vp = db_vars; vp < db_evars; vp++) { + db_read_variable(vp, &value); + db_printf("$%s\t\t= %s\n", vp->name, + db_num_to_str(value)); + } + return; + } + if (t != tDOLLAR) { db_error("Unknown variable\n"); /*NOTREACHED*/ Index: sys/ddb/db_vfs.c =================================================================== RCS file: sys/ddb/db_vfs.c diff -N sys/ddb/db_vfs.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/ddb/db_vfs.c 28 Oct 2023 05:11:17 -0000 @@ -0,0 +1,495 @@ +/* $NetBSD: $ */ + +/*- + * Copyright (c) 2022 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: $"); + +#ifndef _KERNEL +#include +#include +#define __EXPOSE_MOUNT +#endif + +#ifdef _KERNEL +#include +#else + +/* from libkern.h */ +#define container_of(PTR, TYPE, FIELD) \ + ((TYPE *)(((char *)(PTR)) - offsetof(TYPE, FIELD))) + +#endif +#define __RWLOCK_PRIVATE +#include +#include +#include +#include +#include + +/* + * like struct vfsops in sys/mount.h + * - exposes only the name field + */ +struct db_vfsops { + const char *vfs_name; +}; + +#include + +/* XXX copy from vfs_mount.c */ +enum mountlist_type { + ME_MOUNT, + ME_MARKER +}; +struct mountlist_entry { + TAILQ_ENTRY(mountlist_entry) me_list; /* Mount list. */ + struct mount *me_mount; /* Actual mount if ME_MOUNT, + current mount else. */ + enum mountlist_type me_type; /* Mount or marker. */ +}; + +/* + * Unlocked variant to traverse the mountlist. + * To be used from DDB only. + */ +db_addr_t +db_mountlist_next(db_addr_t addr) +{ + struct mountlist_entry ME, *me; + + me = (struct mountlist_entry *)db_read_ptr("mountlist"); + if (addr != 0) { + while (me != NULL) { + db_read_bytes((db_addr_t)me, sizeof(ME), (char*)&ME); + if (ME.me_type == ME_MOUNT + && ((db_addr_t)ME.me_mount) == addr) + break; + me = ME.me_list.tqe_next; + } + if (me != NULL) + me = ME.me_list.tqe_next; + } + + while (me != NULL) { + db_read_bytes((db_addr_t)me, sizeof(ME), (char*)&ME); + if (ME.me_type == ME_MOUNT) + break; + me = ME.me_list.tqe_next; + } + + return (db_addr_t)(me ? ME.me_mount : NULL); +} + +/* + * kern_rwlock.c + */ +static int +db_rw_read_held(krwlock_t *rw) +{ + krwlock_t RW; + + db_read_bytes((db_addr_t)rw, sizeof(RW), (char *)&RW); + return (RW.rw_owner & RW_WRITE_LOCKED) == 0 + && (RW.rw_owner & RW_THREAD) != 0; +} + +static int +db_rw_write_held(krwlock_t *rw) +{ + krwlock_t RW; + + db_read_bytes((db_addr_t)rw, sizeof(RW), (char *)&RW); + return (RW.rw_owner & RW_WRITE_LOCKED) != 0; +} + +/* + * genfs_vnops.c + */ +static int +db_genfs_islocked(struct vnode *vp) +{ + vnode_impl_t *vip = VNODE_TO_VIMPL(vp); + + if (db_rw_write_held(&vip->vi_lock)) + return LK_EXCLUSIVE; + + if (db_rw_read_held(&vip->vi_lock)) + return LK_SHARED; + + return 0; +} + +/* + * vfs_vnode.c + */ +#define VUSECOUNT_MASK 0x3fffffff +static int +db_vrefcnt(struct vnode *vp) +{ + + return vp->v_usecount & VUSECOUNT_MASK; +} + +static const char * +db_vstate_name(enum vnode_state state) +{ + + switch (state) { + case VS_ACTIVE: + return "ACTIVE"; + case VS_MARKER: + return "MARKER"; + case VS_LOADING: + return "LOADING"; + case VS_LOADED: + return "LOADED"; + case VS_BLOCKED: + return "BLOCKED"; + case VS_RECLAIMING: + return "RECLAIMING"; + case VS_RECLAIMED: + return "RECLAIMED"; + default: + return "ILLEGAL"; + } +} + +#define GET(src) db_get_value((db_addr_t)&(src), sizeof(src), true) +#define GETQ(src) db_get_qvalue((db_addr_t)&(src), sizeof(src), true) +#define GETP(src) ((db_addr_t)db_get_qvalue((db_addr_t)&(src), sizeof(src), false)) + +void +db_mount_print(db_addr_t addr, bool full, void (*pr)(const char *, ...)) +{ + struct mount *mp; + db_expr_t e1, e2; + char sbuf[_VFS_MNAMELEN+1]; + + /* even number of pointers to print on a line */ + const unsigned columns = (db_max_width / ( + (sizeof(struct vnode *) <= 4 ? 12 : 24) + ) - 1) / 2 * 2; + + mp = (struct mount *)addr; + + (*pr)("vnodecovered = %"PRIxPTR" lower = %"PRIxPTR"\n", + (uintptr_t)GETP(mp->mnt_vnodecovered), + (uintptr_t)GETP(mp->mnt_lower)); + + (*pr)("data = %"PRIxPTR"\n", + (uintptr_t)GETP(mp->mnt_data)); + + (*pr)("fs_bshift %ld dev_bshift = %ld\n", + (long)GET(mp->mnt_fs_bshift), + (long)GET(mp->mnt_dev_bshift)); + + e1 = GET(mp->mnt_flag); + snprintb(sbuf, sizeof(sbuf), __MNT_FLAG_BITS, e1); + (*pr)("flag = %s\n", sbuf); + + e2 = GET(mp->mnt_iflag); + snprintb(sbuf, sizeof(sbuf), __IMNT_FLAG_BITS, e2); + (*pr)("iflag = %s\n", sbuf); + + (*pr)("refcnt = %ld updating @ %"PRIxPTR"\n", + (long)GET(mp->mnt_refcnt), + (uintptr_t)GETP(mp->mnt_updating)); + + (*pr)("statvfs cache:\n"); + (*pr)("\tbsize = %lu\n", + (unsigned long)GET(mp->mnt_stat.f_bsize)); + (*pr)("\tfrsize = %lu\n", + (unsigned long)GET(mp->mnt_stat.f_frsize)); + (*pr)("\tiosize = %lu\n", + (unsigned long)GET(mp->mnt_stat.f_iosize)); + + (*pr)("\tblocks = %"PRIu64"\n", + (u_quad_t)GETQ(mp->mnt_stat.f_blocks)); + (*pr)("\tbfree = %"PRIu64"\n", + (u_quad_t)GETQ(mp->mnt_stat.f_bfree)); + (*pr)("\tbavail = %"PRIu64"\n", + (u_quad_t)GETQ(mp->mnt_stat.f_bavail)); + (*pr)("\tbresvd = %"PRIu64"\n", + (u_quad_t)GETQ(mp->mnt_stat.f_bresvd)); + + (*pr)("\tfiles = %"PRIu64"\n", + (u_quad_t)GETQ(mp->mnt_stat.f_files)); + (*pr)("\tffree = %"PRIu64"\n", + (u_quad_t)GETQ(mp->mnt_stat.f_ffree)); + (*pr)("\tfavail = %"PRIu64"\n", + (u_quad_t)GETQ(mp->mnt_stat.f_favail)); + (*pr)("\tfresvd = %"PRIu64"\n", + (u_quad_t)GETQ(mp->mnt_stat.f_fresvd)); + + e1 = GET(mp->mnt_stat.f_fsidx.__fsid_val[0]); + e2 = GET(mp->mnt_stat.f_fsidx.__fsid_val[1]); + (*pr)("\tf_fsidx = { 0x%lx, 0x%lx }\n", (long)e1, (long)e2); + + (*pr)("\towner = %lu\n", + (unsigned long)GET(mp->mnt_stat.f_owner)); + (*pr)("\tnamemax = %lu\n", + (unsigned long)GET(mp->mnt_stat.f_namemax)); + + e1 = GET(mp->mnt_stat.f_flag); + snprintb(sbuf, sizeof(sbuf), __MNT_FLAG_BITS, e1); + (*pr)("\tflag = %s\n",sbuf); + + (*pr)("\tsyncwrites = %" PRIu64 "\n", + (u_quad_t)GETQ(mp->mnt_stat.f_syncwrites)); + (*pr)("\tasyncwrites = %" PRIu64 "\n", + (u_quad_t)GETQ(mp->mnt_stat.f_asyncwrites)); + (*pr)("\tsyncreads = %" PRIu64 "\n", + (u_quad_t)GETQ(mp->mnt_stat.f_syncreads)); + (*pr)("\tasyncreads = %" PRIu64 "\n", + (u_quad_t)GETQ(mp->mnt_stat.f_asyncreads)); + + sbuf[_VFS_MNAMELEN] = '\0'; + db_read_string(&mp->mnt_stat.f_fstypename[0], sizeof(mp->mnt_stat.f_fstypename), sbuf); + (*pr)("\tfstypename = %s\n",sbuf); + db_read_string(&mp->mnt_stat.f_mntonname[0], _VFS_MNAMELEN, sbuf); + (*pr)("\tmntonname = %s\n",sbuf); + db_read_string(&mp->mnt_stat.f_mntfromname[0], _VFS_MNAMELEN, sbuf); + (*pr)("\tmntfromname = %s\n",sbuf); + + { + int cnt = 0; + vnode_impl_t *mntvip, *vip; + struct vnode *vp; + const char *sep = ""; + + (*pr)("locked vnodes ="); + + db_read_bytes((db_addr_t)&mp->mnt_vnodelist.tqh_first, + sizeof(mntvip), (char *)&mntvip); + + for (vip = mntvip; vip != NULL; + vip = (vnode_impl_t *)GETP(vip->vi_mntvnodes.tqe_next)) { + vp = VIMPL_TO_VNODE(vip); + + /* XXX VOP_ISLOCKED(vp) */ + if (db_genfs_islocked(vp)) { + if ((cnt++ % columns) == 0) { + (*pr)("%s\n\t%p", sep, vp); + } else { + (*pr)("%s\t%p", sep, vp); + } + sep = ","; + } + } + (*pr)("\n"); + } + + if (full) { + int cnt = 0; + vnode_impl_t *mntvip, *vip; + struct vnode *vp; + const char *sep = ""; + const char *tag; + + (*pr)("all vnodes ="); + + db_read_bytes((db_addr_t)&mp->mnt_vnodelist.tqh_first, + sizeof(mntvip), (char *)&mntvip); + + for (vip = mntvip; vip != NULL; + vip = (vnode_impl_t *)GETP(vip->vi_mntvnodes.tqe_next)) { + vp = VIMPL_TO_VNODE(vip); + + tag = GET(vp->v_numoutput) ? "*" : ""; + + if ((cnt++ % columns) == 0) { + (*pr)("%s\n %p%s", sep, vp, tag); + } else { + (*pr)("%s %p%s", sep, vp, tag); + } + sep = ","; + } + (*pr)("\n"); + } +} + +static void +db_mount_print_one(db_addr_t addr, bool full, void (*pr)(const char *, ...)) +{ + db_addr_t name; + struct mount *mp; + struct db_vfsops *op; + char fsname[9]; + + mp = (struct mount *)addr; + + op = (struct db_vfsops *)GETP(mp->mnt_op); + if (op != NULL) { + name = GETP(op->vfs_name); + db_read_string((char *)name, sizeof(fsname)-1, fsname); + } else + strcpy(fsname, "???"); + + (*pr)("%-18" PRIxPTR, (uintptr_t)addr); + (*pr)(" %-18" PRIxPTR, + (uintptr_t)GETP(mp->mnt_vnodecovered)); + (*pr)(" %8ld", (long)GET(mp->mnt_refcnt)); + (*pr)(" %-8s", fsname); + (*pr)(" %-18" PRIxPTR, + (uintptr_t)GETP(mp->mnt_data)); + (*pr)("\n"); +} + +void +db_mount_print_all(bool full, void (*pr)(const char *, ...)) +{ + db_addr_t addr; + + (*pr)("%-18s %-18s %8s %-8s %-18s\n", + "ADDR","COVERED","REFCNT","NAME","DATA"); + + for (addr = db_mountlist_next(0); addr; addr = db_mountlist_next(addr)) + db_mount_print_one(addr, full, pr); +} + +void +db_buf_print(db_addr_t addr, bool full, void (*pr)(const char *, ...)) +{ + struct buf B; + static const char buf_flagbits[] = BUF_FLAGBITS; + char bf[1024]; /* XXX */ + + db_read_bytes(addr, sizeof(B), (char *)&B); + + snprintb(bf, sizeof(bf), + buf_flagbits, B.b_flags | B.b_oflags | B.b_cflags); + + (*pr)(" error %d flags %s\n", B.b_error, bf); + + (*pr)(" bufsize 0x%lx bcount 0x%lx resid 0x%lx\n", + (long)B.b_bufsize, (long)B.b_bcount, (long)B.b_resid); + (*pr)(" data %p saveaddr %p\n", + B.b_data, B.b_saveaddr); + (*pr)(" iodone %p objlock %p\n", B.b_iodone, B.b_objlock); +} + +void +db_vnode_print(db_addr_t addr, bool full, void (*pr)(const char *, ...)) +{ + struct vnode *vp; + int n; + char bf[96]; /* XXX */ + const uint8_t *cp; + uint8_t C; + vnode_impl_t *vip, VI; + const char * const vnode_tags[] = { VNODE_TAGS }; + const char * const vnode_types[] = { VNODE_TYPES }; + const char vnode_flagbits[] = VNODE_FLAGBITS; + struct buf *bp; + const char *prefix = "\t"; + + vp = (struct vnode *)addr; + + db_uvmobject_print((db_addr_t)&vp->v_uobj, full, pr); + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) +#define ARRAY_PRINT(idx, arr) \ + ((unsigned int)(idx) < ARRAY_SIZE(arr) ? (arr)[(idx)] : "UNKNOWN") + + vip = VNODE_TO_VIMPL(vp); + + db_read_bytes((db_addr_t)vip, sizeof(VI), (char *)&VI); + + vp = VIMPL_TO_VNODE(&VI); + + snprintb(bf, sizeof(bf), + vnode_flagbits, vp->v_iflag | vp->v_vflag | vp->v_uflag); + + (*pr)("vnode %p flags %s\n", vp, bf); + (*pr)("%stag %s(%d) type %s(%d) mount %p typedata %p\n", prefix, + ARRAY_PRINT(vp->v_tag, vnode_tags), vp->v_tag, + ARRAY_PRINT(vp->v_type, vnode_types), vp->v_type, + vp->v_mount, vp->v_mountedhere); + (*pr)("%susecount %d writecount %d holdcount %d\n", prefix, + db_vrefcnt(vp), vp->v_writecount, vp->v_holdcnt); + (*pr)("%ssize %" PRIx64 " writesize %" PRIx64 " numoutput %d\n", + prefix, vp->v_size, vp->v_writesize, vp->v_numoutput); + (*pr)("%sdata %p lock %p\n", prefix, vp->v_data, &vip->vi_lock); + + (*pr)("%sstate %s key(%p %zd)", prefix, db_vstate_name(VI.vi_state), + VI.vi_key.vk_mount, VI.vi_key.vk_key_len); + n = VI.vi_key.vk_key_len; + cp = VI.vi_key.vk_key; + while (n-- > 0) { + db_read_bytes((db_addr_t)cp++, sizeof(C), (char *)&C); + (*pr)(" %02x", C); + } + (*pr)("\n"); + (*pr)("%slrulisthd %p\n", prefix, VI.vi_lrulisthd); + +#undef ARRAY_PRINT +#undef ARRAY_SIZE + + if (full) { + (*pr)("clean bufs\n"); + for (bp = (struct buf *)vp->v_cleanblkhd.lh_first; + bp != NULL; + bp = (struct buf *)GETP(bp->b_vnbufs.le_next)) { + db_buf_print((db_addr_t)bp, full, pr); + } + + (*pr)("dirty bufs\n"); + for (bp = (struct buf *)vp->v_dirtyblkhd.lh_first; + bp != NULL; + bp = (struct buf *)GETP(bp->b_vnbufs.le_next)) { + db_buf_print((db_addr_t)bp, full, pr); + } + } +} + +void +db_vnode_lock_print(db_addr_t addr, bool full, void (*pr)(const char *, ...)) +{ + void *vlock; + struct mount *mp; + vnode_impl_t *mntvip, *vip; + + vlock = (void *)addr; + + for (addr = db_mountlist_next(0); addr; + addr = db_mountlist_next(addr)) { + + mp = (struct mount *)addr; + + db_read_bytes((db_addr_t)&mp->mnt_vnodelist.tqh_first, + sizeof(mntvip), (char *)&mntvip); + + for (vip = mntvip; vip != NULL; + vip = (vnode_impl_t *)GETP(vip->vi_mntvnodes.tqe_next)) { + if ((void*)&vip->vi_lock == vlock) { + db_vnode_print((db_addr_t)VIMPL_TO_VNODE(vip), + full, pr); + } + } + } +} Index: sys/ddb/db_xxx.c =================================================================== RCS file: /cvsroot/src/sys/ddb/db_xxx.c,v retrieving revision 1.79 diff -p -u -r1.79 db_xxx.c --- sys/ddb/db_xxx.c 15 Oct 2023 10:40:52 -0000 1.79 +++ sys/ddb/db_xxx.c 28 Oct 2023 05:11:17 -0000 @@ -189,7 +189,7 @@ db_show_files_cmd(db_expr_t addr, bool h if (fp != NULL && fp->f_type == DTYPE_VNODE && fp->f_vnode != NULL) { vp = fp->f_vnode; - vfs_vnode_print(vp, full, db_printf); + db_vnode_print((db_addr_t)vp, full, db_printf); #ifdef LOCKDEBUG db_printf("\nv_uobj.vmobjlock lock details:\n"); Index: sys/ddb/files.ddb =================================================================== RCS file: /cvsroot/src/sys/ddb/files.ddb,v retrieving revision 1.16 diff -p -u -r1.16 files.ddb --- sys/ddb/files.ddb 9 Jul 2023 17:10:47 -0000 1.16 +++ sys/ddb/files.ddb 28 Oct 2023 05:11:17 -0000 @@ -27,6 +27,8 @@ file ddb/db_cpu.c ddb file ddb/db_examine.c ddb file ddb/db_expr.c ddb file ddb/db_input.c ddb +file ddb/db_iostat.c ddb +#file ddb/db_fstrans.c ddb file ddb/db_kernel.c ddb file ddb/db_lex.c ddb file ddb/db_lwp.c ddb @@ -38,7 +40,9 @@ file ddb/db_run.c ddb | kgdb # XXX kgd file ddb/db_sym.c ddb file ddb/db_syncobj.c ddb file ddb/db_trap.c ddb +file ddb/db_uvm.c ddb file ddb/db_variables.c ddb +file ddb/db_vfs.c ddb file ddb/db_watch.c ddb file ddb/db_write_cmd.c ddb file ddb/db_xxx.c ddb