Create a pgdat command for KDB.
This displays the 'pg_data_t' structure associated
with a NUMA node id.
pgdat <node_id>
When CONFIG_NUMA is disabled, the node_id parameter
is ignored if it is specified, and the one pg_data_t
structure is output. When CONFIG_NUMA is enabled, the
user may optionally specify a node_id of the pg_data_t
structure to be output. If not specified, then the node
0 structure is output.
The output includes a decoding of the node's zonelists.
Author: John Blackwood <[EMAIL PROTECTED]>
Signed-off-by: Joe Korty <[EMAIL PROTECTED]>
Index: 2.6.26-rc9/kdb/modules/kdbm_vm.c
===================================================================
--- 2.6.26-rc9.orig/kdb/modules/kdbm_vm.c 2008-07-10 13:36:59.000000000
-0400
+++ 2.6.26-rc9/kdb/modules/kdbm_vm.c 2008-07-10 13:37:56.000000000 -0400
@@ -218,6 +218,98 @@
#endif /* CONFIG_NUMA */
/*
+ * kdbm_pgdat
+ *
+ * This function implements the 'pgdat' command.
+ * Print a struct pglist_data (pg_dat_t).
+ *
+ * pgdat <node_id> Print struct pglist_data for node <node_id>.
+ *
+ * Print pglist_data for node 0 if node_id not specified,
+ * or print the one pglist_data structure if !CONFIG_NUMA.
+ */
+static int
+kdbm_pgdat(int argc, const char **argv)
+{
+ int err = 0, node_id = 0, i;
+ pg_data_t *pgdatp = NULL;
+
+#ifdef CONFIG_NUMA
+ if (argc > 1)
+ return KDB_ARGCOUNT;
+ if (argc == 1) {
+ int nextarg;
+ long offset = 0;
+ unsigned long node_id_ul;
+
+ nextarg = 1;
+ if ((err = kdbgetaddrarg(argc, argv, &nextarg, &node_id_ul,
+ &offset, NULL)) != 0) {
+ return(err);
+ }
+ node_id = (int)node_id_ul;
+ }
+#endif
+ for_each_online_pgdat(pgdatp) {
+ if (pgdatp->node_id == node_id)
+ break;
+ }
+ if (!pgdatp) {
+ kdb_printf("%s: specified node not found\n", __FUNCTION__);
+ return 0;
+ }
+ kdb_printf("struct pglist_data at 0x%p node_id = %d\n",
+ pgdatp, pgdatp->node_id);
+
+ for (i = 0; i < MAX_ZONELISTS; i++) {
+ int zr;
+ struct zoneref *zonerefp;
+ struct zone *zonep;
+
+ zonerefp = pgdatp->node_zonelists[i]._zonerefs;
+ kdb_printf(" _zonerefs[%d] at 0x%p\n", i, zonerefp);
+
+ for (zr = 0; zr <= MAX_ZONES_PER_ZONELIST; zr++, zonerefp++) {
+ int z;
+ pg_data_t *tmp_pgdatp;
+
+ zonep = zonelist_zone(zonerefp);
+ if (!zonep)
+ break;
+
+ kdb_printf(" 0x%p", zonep);
+
+ for_each_online_pgdat(tmp_pgdatp) {
+ for (z = 0; z < MAX_NR_ZONES; z++) {
+ if (zonep ==
&tmp_pgdatp->node_zones[z]) {
+ kdb_printf (" (node %d
node_zones[%d])",
+ tmp_pgdatp->node_id, z);
+ break;
+ }
+ }
+ if (z != MAX_NR_ZONES)
+ break; /* found it */
+ }
+ kdb_printf("\n");
+ }
+ }
+
+ kdb_printf(" nr_zones = %d", pgdatp->nr_zones);
+#ifdef CONFIG_FLAT_NODE_MEM_MAP
+ kdb_printf(" node_mem_map = 0x%p\n", pgdatp->node_mem_map);
+#endif
+ kdb_printf(" bdata = 0x%p", pgdatp->bdata);
+ kdb_printf(" node_start_pfn = 0x%lx\n", pgdatp->node_start_pfn);
+ kdb_printf(" node_present_pages = %ld (0x%lx)\n",
+ pgdatp->node_present_pages, pgdatp->node_present_pages);
+ kdb_printf(" node_spanned_pages = %ld (0x%lx)\n",
+ pgdatp->node_spanned_pages, pgdatp->node_spanned_pages);
+ kdb_printf(" kswapd = 0x%p\n", pgdatp->kswapd);
+
+ return err;
+}
+
+/*
* kdbm_vm
*
* This function implements the 'vm' command. Print a vm_area_struct.
@@ -904,6 +996,9 @@
kdb_register("vmp", kdbm_vm, "[-v] <pid>", "Display all vm_area_struct
for <pid>", 0);
#ifdef CONFIG_NUMA
kdb_register("mempolicy", kdbm_mpol, "<vaddr>", "Display mempolicy
structure", 0);
+ kdb_register("pgdat", kdbm_pgdat, "<node_id>", "Display pglist_data
node structure", 0);
+#else
+ kdb_register("pgdat", kdbm_pgdat, "", "Display pglist_data node
structure", 0);
#endif
kdb_register("pte", kdbm_pte, "( -m <mm> | -p <pid> ) <vaddr>
[<nbytes>]", "Display pte_t for mm_struct or pid", 0);
kdb_register("rpte", kdbm_rpte, "( -m <mm> | -p <pid> ) <pfn>
[<npages>]", "Find pte_t containing pfn for mm_struct or pid", 0);
@@ -925,6 +1020,7 @@
#ifdef CONFIG_NUMA
kdb_unregister("mempolicy");
#endif
+ kdb_unregister("pgdat");
kdb_unregister("pte");
kdb_unregister("rpte");
kdb_unregister("dentry");
---------------------------
Use http://oss.sgi.com/ecartis to modify your settings or to unsubscribe.