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.

Reply via email to