24 */
25
26 #include <mdb/mdb_param.h>
27 #include <mdb/mdb_modapi.h>
28 #include <mdb/mdb_ks.h>
29 #include <sys/types.h>
30 #include <sys/memlist.h>
31 #include <sys/swap.h>
32 #include <sys/systm.h>
33 #include <sys/thread.h>
34 #include <vm/anon.h>
35 #include <vm/as.h>
36 #include <vm/page.h>
37 #include <sys/thread.h>
38 #include <sys/swap.h>
39 #include <sys/memlist.h>
40 #include <sys/vnode.h>
41 #include <vm/seg_map.h>
42 #include <vm/seg_vn.h>
43 #include <vm/seg_hole.h>
44 #if defined(__i386) || defined(__amd64)
45 #include <sys/balloon_impl.h>
46 #endif
47
48 #include "avl.h"
49 #include "memory.h"
50
51 /*
52 * Page walker.
53 * By default, this will walk all pages in the system. If given an
54 * address, it will walk all pages belonging to the vnode at that
55 * address.
56 */
57
58 /*
59 * page_walk_data
60 *
61 * pw_hashleft is set to -1 when walking a vnode's pages, and holds the
62 * number of hash locations remaining in the page hash table when
63 * walking all pages.
64 *
65 * The astute reader will notice that pw_hashloc is only used when
66 * reading all pages (to hold a pointer to our location in the page
492 stats->ms_exec++;
493 else
494 stats->ms_vnode++;
495
496 stats->ms_total++;
497
498 return (WALK_NEXT);
499 }
500
501 /* ARGSUSED */
502 int
503 memstat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
504 {
505 pgcnt_t total_pages, physmem;
506 ulong_t freemem;
507 memstat_t stats;
508 GElf_Sym sym;
509 vn_htable_t ht;
510 struct vnode *kvps;
511 uintptr_t vn_size = 0;
512 #if defined(__i386) || defined(__amd64)
513 bln_stats_t bln_stats;
514 ssize_t bln_size;
515 #endif
516
517 bzero(&stats, sizeof (memstat_t));
518
519 /*
520 * -s size, is an internal option. It specifies the size of vn_htable.
521 * Hash table size is set in the following order:
522 * If user has specified the size that is larger than VN_LARGE: try it,
523 * but if malloc failed default to VN_SMALL. Otherwise try VN_LARGE, if
524 * failed to allocate default to VN_SMALL.
525 * For a better efficiency of hash table it is highly recommended to
526 * set size to a prime number.
527 */
528 if ((flags & DCMD_ADDRSPEC) || mdb_getopts(argc, argv,
529 's', MDB_OPT_UINTPTR, &vn_size, NULL) != argc)
530 return (DCMD_USAGE);
531
532 /* Initialize vnode hash list and queue */
533 vn_htable_init(&ht, vn_size);
534 stats.ms_vn_htable = &ht;
535
614 (uint64_t)stats.ms_exec * PAGESIZE / (1024 * 1024),
615 MS_PCT_TOTAL(stats.ms_exec));
616 mdb_printf("Page cache %16llu %16llu %3lu%%\n",
617 stats.ms_vnode,
618 (uint64_t)stats.ms_vnode * PAGESIZE / (1024 * 1024),
619 MS_PCT_TOTAL(stats.ms_vnode));
620 mdb_printf("Free (cachelist) %16llu %16llu %3lu%%\n",
621 stats.ms_cachelist,
622 (uint64_t)stats.ms_cachelist * PAGESIZE / (1024 * 1024),
623 MS_PCT_TOTAL(stats.ms_cachelist));
624
625 /*
626 * occasionally, we double count pages above. To avoid printing
627 * absurdly large values for freemem, we clamp it at zero.
628 */
629 if (physmem > stats.ms_total)
630 freemem = physmem - stats.ms_total;
631 else
632 freemem = 0;
633
634 #if defined(__i386) || defined(__amd64)
635 /* Are we running under Xen? If so, get balloon memory usage. */
636 if ((bln_size = mdb_readvar(&bln_stats, "bln_stats")) != -1) {
637 if (freemem > bln_stats.bln_hv_pages)
638 freemem -= bln_stats.bln_hv_pages;
639 else
640 freemem = 0;
641 }
642 #endif
643
644 mdb_printf("Free (freelist) %16lu %16llu %3lu%%\n", freemem,
645 (uint64_t)freemem * PAGESIZE / (1024 * 1024),
646 MS_PCT_TOTAL(freemem));
647
648 #if defined(__i386) || defined(__amd64)
649 if (bln_size != -1) {
650 mdb_printf("Balloon %16lu %16llu %3lu%%\n",
651 bln_stats.bln_hv_pages,
652 (uint64_t)bln_stats.bln_hv_pages * PAGESIZE / (1024 * 1024),
653 MS_PCT_TOTAL(bln_stats.bln_hv_pages));
654 }
655 #endif
656
657 mdb_printf("\nTotal %16lu %16lu\n",
658 physmem,
659 (uint64_t)physmem * PAGESIZE / (1024 * 1024));
660
661 if (physmem != total_pages) {
662 mdb_printf("Physical %16lu %16lu\n",
663 total_pages,
664 (uint64_t)total_pages * PAGESIZE / (1024 * 1024));
665 }
666
667 #undef MS_PCT_TOTAL
668
669 return (DCMD_OK);
670 }
671
672 void
673 pagelookup_help(void)
674 {
675 mdb_printf(
676 "Finds the page with name { %<b>vp%</b>, %<b>offset%</b> }.\n"
|
24 */
25
26 #include <mdb/mdb_param.h>
27 #include <mdb/mdb_modapi.h>
28 #include <mdb/mdb_ks.h>
29 #include <sys/types.h>
30 #include <sys/memlist.h>
31 #include <sys/swap.h>
32 #include <sys/systm.h>
33 #include <sys/thread.h>
34 #include <vm/anon.h>
35 #include <vm/as.h>
36 #include <vm/page.h>
37 #include <sys/thread.h>
38 #include <sys/swap.h>
39 #include <sys/memlist.h>
40 #include <sys/vnode.h>
41 #include <vm/seg_map.h>
42 #include <vm/seg_vn.h>
43 #include <vm/seg_hole.h>
44
45 #include "avl.h"
46 #include "memory.h"
47
48 /*
49 * Page walker.
50 * By default, this will walk all pages in the system. If given an
51 * address, it will walk all pages belonging to the vnode at that
52 * address.
53 */
54
55 /*
56 * page_walk_data
57 *
58 * pw_hashleft is set to -1 when walking a vnode's pages, and holds the
59 * number of hash locations remaining in the page hash table when
60 * walking all pages.
61 *
62 * The astute reader will notice that pw_hashloc is only used when
63 * reading all pages (to hold a pointer to our location in the page
489 stats->ms_exec++;
490 else
491 stats->ms_vnode++;
492
493 stats->ms_total++;
494
495 return (WALK_NEXT);
496 }
497
498 /* ARGSUSED */
499 int
500 memstat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
501 {
502 pgcnt_t total_pages, physmem;
503 ulong_t freemem;
504 memstat_t stats;
505 GElf_Sym sym;
506 vn_htable_t ht;
507 struct vnode *kvps;
508 uintptr_t vn_size = 0;
509
510 bzero(&stats, sizeof (memstat_t));
511
512 /*
513 * -s size, is an internal option. It specifies the size of vn_htable.
514 * Hash table size is set in the following order:
515 * If user has specified the size that is larger than VN_LARGE: try it,
516 * but if malloc failed default to VN_SMALL. Otherwise try VN_LARGE, if
517 * failed to allocate default to VN_SMALL.
518 * For a better efficiency of hash table it is highly recommended to
519 * set size to a prime number.
520 */
521 if ((flags & DCMD_ADDRSPEC) || mdb_getopts(argc, argv,
522 's', MDB_OPT_UINTPTR, &vn_size, NULL) != argc)
523 return (DCMD_USAGE);
524
525 /* Initialize vnode hash list and queue */
526 vn_htable_init(&ht, vn_size);
527 stats.ms_vn_htable = &ht;
528
607 (uint64_t)stats.ms_exec * PAGESIZE / (1024 * 1024),
608 MS_PCT_TOTAL(stats.ms_exec));
609 mdb_printf("Page cache %16llu %16llu %3lu%%\n",
610 stats.ms_vnode,
611 (uint64_t)stats.ms_vnode * PAGESIZE / (1024 * 1024),
612 MS_PCT_TOTAL(stats.ms_vnode));
613 mdb_printf("Free (cachelist) %16llu %16llu %3lu%%\n",
614 stats.ms_cachelist,
615 (uint64_t)stats.ms_cachelist * PAGESIZE / (1024 * 1024),
616 MS_PCT_TOTAL(stats.ms_cachelist));
617
618 /*
619 * occasionally, we double count pages above. To avoid printing
620 * absurdly large values for freemem, we clamp it at zero.
621 */
622 if (physmem > stats.ms_total)
623 freemem = physmem - stats.ms_total;
624 else
625 freemem = 0;
626
627 mdb_printf("Free (freelist) %16lu %16llu %3lu%%\n", freemem,
628 (uint64_t)freemem * PAGESIZE / (1024 * 1024),
629 MS_PCT_TOTAL(freemem));
630
631 mdb_printf("\nTotal %16lu %16lu\n",
632 physmem,
633 (uint64_t)physmem * PAGESIZE / (1024 * 1024));
634
635 if (physmem != total_pages) {
636 mdb_printf("Physical %16lu %16lu\n",
637 total_pages,
638 (uint64_t)total_pages * PAGESIZE / (1024 * 1024));
639 }
640
641 #undef MS_PCT_TOTAL
642
643 return (DCMD_OK);
644 }
645
646 void
647 pagelookup_help(void)
648 {
649 mdb_printf(
650 "Finds the page with name { %<b>vp%</b>, %<b>offset%</b> }.\n"
|