----- Original Message -----
> Hi Dave,
> 
> Please share your thoughts on adding a -m option to kmem to display
> the free pages per migrate type.
> This is similar to /proc/pagetypeinfo.

OK, now there's two competing "kmem -m" patch requests out there -- neither
of which I'm particularly interested in maintaining.

Look, the crash utility could effectively mimic every file in the
/proc filesystem.  But that doesn't mean that it should -- somewhere
that has to be a line to be drawn.

Can you make it an extension module?  I'll host it on the extensions
web page, and if there becomes a consensus where people find that they
can't live without it, then it can be reconsidered for the base
crash utility.

Dave

 

> 
> Sample output (without formatting). Patch attached.
> 
> crash>
> Free pages count per migrate type at order  [0-10]:
> Node    0, zone   Normal, type    Unmovable    155    172     92
> 39     20      8     10     15      7      3      1
> Node    0, zone  HighMem, type    Unmovable      1      2      0
> 0      0      0      0      0      0      0      0
> Node    0, zone  Movable, type    Unmovable      0      0      0
> 0      0      0      0      0      0      0      0
> Node    0, zone   Normal, type  Reclaimable      9      3      0
> 0      1      1      0      0      0      0      0
> Node    0, zone  HighMem, type  Reclaimable      0      0      0
> 0      0      0      0      0      0      0      0
> Node    0, zone  Movable, type  Reclaimable      0      0      0
> 0      0      0      0      0      0      0      0
> Node    0, zone   Normal, type      Movable      7     68     35
> 253    137     38     16      4      0      0     66
> Node    0, zone  HighMem, type      Movable      0      1      0
> 0      0      0      0      0      0      0      0
> Node    0, zone  Movable, type      Movable      0      0      0
> 0      0      0      0      0      0      0      0
> Node    0, zone   Normal, type      Reserve      0      0      0
> 0      0      0      0      0      0      0      1
> Node    0, zone  HighMem, type      Reserve     11      7      5
> 1      0      0      0      0      0      0      0
> Node    0, zone  Movable, type      Reserve      0      0      0
> 0      0      0      0      0      0      0      0
> Node    0, zone   Normal, type      Isolate      0      0      0
> 0      0      0      0      0      0      0      0
> Node    0, zone  HighMem, type      Isolate      0      0      0
> 0      0      0      0      0      0      0      0
> Node    0, zone  Movable, type      Isolate      0      0      0
> 0      0      0      0      0      0      0      0
> 
> 
> diff --git a/crash-6.0.8/help.c b/crash-6.0.8/help.c
> index 6d6ac5e..9ad6c00 100755
> --- a/crash-6.0.8/help.c
> +++ b/crash-6.0.8/help.c
> @@ -5147,7 +5147,7 @@ NULL
>  char *help_kmem[] = {
>  "kmem",
>  "kernel memory",
> -"[-f|-F|-p|-c|-C|-i|-s|-S|-v|-V|-n|-z-o] [slab] [[-P] address]\n"
> +"[-f|-F|-p|-c|-C|-i|-s|-S|-v|-V|-n|-m|-z-o] [slab] [[-P] address]\n"
>  "       [-g [flags]]",
>  "  This command displays information about the use of kernel
>  memory.\n",
>  "        -f  displays the contents of the system free memory
>  headers.",
> @@ -5174,6 +5174,8 @@ char *help_kmem[] = {
>  "            values to translate them into kernel virtual
>  addresses.",
>  "        -g  displays the enumerator value of all bits in the page
> structure's",
>  "            \"flags\" field.",
> +"        -m  displays the number of pages per migrate type for all
> orders, for all",
> +"            nodes.",
>  "     flags  when used with -g, translates all bits in this
>  hexadecimal page",
>  "            structure flags value into its enumerator values.",
>  "      slab  when used with -s or -S, limits the command to only the
> slab cache",
> @@ -5605,6 +5607,24 @@ char *help_kmem[] = {
>  "      PG_slab            7  0000080",
>  "      PG_head           14  0004000",
>  "    %s>",
> +"\n  Display pages per migrate type for all orders, for all
> nodes:\n",
> +"    %s> kmem -m",
> +"    Free pages count per migrate type at order [0-10]:",
> +"    Node    0, zone   Normal, type    Unmovable    155    172
>     92
>     39     20      8     10     15      7      3      1",
> +"    Node    0, zone  HighMem, type    Unmovable      1      2
>      0
>      0      0      0      0      0      0      0      0",
> +"    Node    0, zone  Movable, type    Unmovable      0      0
>      0
>      0      0      0      0      0      0      0      0",
> +"    Node    0, zone   Normal, type  Reclaimable      9      3
>      0
>      0      1      1      0      0      0      0      0",
> +"    Node    0, zone  HighMem, type  Reclaimable      0      0
>      0
>      0      0      0      0      0      0      0      0",
> +"    Node    0, zone  Movable, type  Reclaimable      0      0
>      0
>      0      0      0      0      0      0      0      0",
> +"    Node    0, zone   Normal, type      Movable      7     68
>     35
>    253    137     38     16      4      0      0     66",
> +"    Node    0, zone  HighMem, type      Movable      0      1
>      0
>      0      0      0      0      0      0      0      0",
> +"    Node    0, zone  Movable, type      Movable      0      0
>      0
>      0      0      0      0      0      0      0      0",
> +"    Node    0, zone   Normal, type      Reserve      0      0
>      0
>      0      0      0      0      0      0      0      1",
> +"    Node    0, zone  HighMem, type      Reserve     11      7
>      5
>      1      0      0      0      0      0      0      0",
> +"    Node    0, zone  Movable, type      Reserve      0      0
>      0
>      0      0      0      0      0      0      0      0",
> +"    Node    0, zone   Normal, type      Isolate      0      0
>      0
>      0      0      0      0      0      0      0      0",
> +"    Node    0, zone  HighMem, type      Isolate      0      0
>      0
>      0      0      0      0      0      0      0      0",
> +"    Node    0, zone  Movable, type      Isolate      0      0
>      0
>      0      0      0      0      0      0      0      0",
>  NULL
>  };
> 
> diff --git a/crash-6.0.8/memory.c b/crash-6.0.8/memory.c
> index 02a6de1..e03db84 100755
> --- a/crash-6.0.8/memory.c
> +++ b/crash-6.0.8/memory.c
> @@ -264,6 +264,7 @@ static int verify_pfn(ulong);
>  static void dump_per_cpu_offsets(void);
>  static void dump_page_flags(ulonglong);
>  static ulong kmem_cache_nodelists(ulong);
> +static void dump_pgtype_info(void);
> 
>  /*
>   *  Memory display modes specific to this file.
> @@ -4044,6 +4045,8 @@ get_task_mem_usage(ulong task, struct
> task_mem_usage *tm)
>   *      -c  displays the number of pages in the page_hash_table.
>   *      -C  displays all entries in the page_hash_table.
>   *      -i  displays informational data shown by /proc/meminfo.
> + *      -m  displays information on the number of pages per migrate
> type
> + *          for all orders, for all nodes.
>   *
>   *      -P  forces address to be defined as a physical address
>   * address  when used with -f, the address can be either a page
>   pointer
> @@ -4090,7 +4093,7 @@ cmd_kmem(void)
>       int i;
>       int c;
>       int sflag, Sflag, pflag, fflag, Fflag, vflag, zflag, oflag, gflag;
> -     int nflag, cflag, Cflag, iflag, lflag, Lflag, Pflag, Vflag;
> +     int nflag, cflag, Cflag, iflag, lflag, Lflag, Pflag, Vflag, mflag;
>       struct meminfo meminfo;
>       ulonglong value[MAXARGS];
>       char buf[BUFSIZE];
> @@ -4100,12 +4103,12 @@ cmd_kmem(void)
>       spec_addr = 0;
>          sflag =      Sflag = pflag = fflag = Fflag = Pflag = zflag =
>          oflag = 0;
>       vflag = Cflag = cflag = iflag = nflag = lflag = Lflag = Vflag = 0;
> -     gflag = 0;
> +     gflag = mflag = 0;
>       escape = FALSE;
>       BZERO(&meminfo, sizeof(struct meminfo));
>       BZERO(&value[0], sizeof(ulonglong)*MAXARGS);
> 
> -        while ((c = getopt(argcnt, args, "gI:sSFfpvczCinl:L:PVo"))
> != EOF) {
> +        while ((c = getopt(argcnt, args, "gI:sSFfpvczCinml:L:PVo"))
> != EOF) {
>                  switch(c)
>               {
>               case 'V':
> @@ -4206,6 +4209,10 @@ cmd_kmem(void)
>                       gflag = 1;
>                       break;
> 
> +             case 'm':
> +                     mflag = 1;
> +                     break;
> +
>               default:
>                       argerrs++;
>                       break;
> @@ -4215,8 +4222,8 @@ cmd_kmem(void)
>       if (argerrs)
>               cmd_usage(pc->curcmd, SYNOPSIS);
> 
> -        if ((sflag + Sflag + pflag + fflag + Fflag + Vflag + oflag +
> -            vflag + Cflag + cflag + iflag + lflag + Lflag + gflag) >
> 1) {
> +        if ((sflag + Sflag + pflag + fflag + Fflag + Vflag + oflag +
> vflag +
> +             Cflag + cflag + iflag + lflag + Lflag + gflag + mflag) > 1) {
>               error(INFO, "only one flag allowed!\n");
>               cmd_usage(pc->curcmd, SYNOPSIS);
>       }
> @@ -4444,9 +4451,12 @@ cmd_kmem(void)
>       if (gflag == 1)
>               dump_page_flags(0);
> 
> +     if (mflag == 1)
> +             dump_pgtype_info();
> +
>       if (!(sflag + Sflag + pflag + fflag + Fflag + vflag +
>             Vflag + zflag + oflag + cflag + Cflag + iflag +
> -           nflag + lflag + Lflag + gflag + meminfo.calls))
> +           nflag + lflag + Lflag + gflag + mflag + meminfo.calls))
>               cmd_usage(pc->curcmd, SYNOPSIS);
> 
>  }
> @@ -7051,6 +7061,163 @@ bailout:
>       return total_free;
>  }
> 
> +static void dump_pgtype_info(void)
> +{
> +     int n, m, z, o;
> +     int list_count = 0;
> +     int free_cnt = 0;
> +     int mtype_sym = 0;
> +     int mtype_len = 0;
> +     ulong *mtypes;
> +     ulong node_zones;
> +     ulong temp;
> +     ulong freelist;
> +     ulong *free_ptr;
> +     char *free_list_buf;
> +     char name_buf[BUFSIZE];
> +     char buf[BUFSIZE];
> +     struct node_table *nt;
> +     struct list_data list_data;
> +
> +     if (!(vt->flags & (NODES|ZONES)))
> +             error(FATAL,
> +                     "dump_pgtype_info called without (NODES|ZONES)\n");
> +
> +     if (!VALID_STRUCT(zone))
> +             error(FATAL,
> +                     "zone struct not available in this kernel\n");
> +
> +     if (VALID_STRUCT(free_area)) {
> +             if (SIZE(free_area) == (3 * sizeof(ulong)))
> +                     error(FATAL,
> +                             "free_area type not supported by command\n");
> +             else
> +                     list_count = MEMBER_SIZE("free_area",
> +                                     "free_list")/SIZE(list_head);
> +     } else
> +             error(FATAL,
> +                     "free_area structure not found\n");
> +
> +     free_list_buf = GETBUF(SIZE(list_head));
> +
> +     do {
> +             if (symbol_exists("migratetype_names") &&
> +                     (get_symbol_type("migratetype_names",
> +                                      NULL, NULL) == TYPE_CODE_ARRAY)) {
> +
> +                     open_tmpfile();
> +                     sprintf(buf, "whatis migratetype_names");
> +                     if (!gdb_pass_through(buf, fp, GNU_RETURN_ON_ERROR)) {
> +                             close_tmpfile();
> +                             break;
> +                     }
> +
> +                     rewind(pc->tmpfile);
> +                     while (fgets(buf, BUFSIZE, pc->tmpfile)) {
> +                             if (STRNEQ(buf, "type = "))
> +                                     break;
> +                     }
> +                     close_tmpfile();
> +
> +                     if (!strstr(buf, "char *") ||
> +                             (count_chars(buf, '[') != 1) ||
> +                             (count_chars(buf, ']') != 1))
> +                             break;
> +
> +                     mtype_len = get_array_length("migratetype_names",
> +                                     NULL, 0);
> +
> +                     mtypes = (ulong *)GETBUF(mtype_len * sizeof(ulong));
> +
> +                     readmem(symbol_value("migratetype_names"),
> +                                     KVADDR, mtypes,
> +                                     (mtype_len * sizeof(ulong)),
> +                                     NULL, FAULT_ON_ERROR);
> +
> +                     mtype_sym = 1;
> +             }
> +     } while (0);
> +
> +     fprintf(fp, "%-43s [%d-%d]:",
> +                     "Free pages count per migrate type at order",
> +                     0, vt->nr_free_areas - 1);
> +
> +     fprintf(fp, "\n");
> +
> +     for (n = 0; n < vt->numnodes; n++) {
> +             nt = &vt->node_table[n];
> +             node_zones = nt->pgdat + OFFSET(pglist_data_node_zones);
> +
> +             for (m = 0; m < list_count; m++) {
> +
> +                     for (z = 0; z < vt->nr_zones; z++) {
> +                             readmem((node_zones + (z * SIZE(zone)))
> +                                     + OFFSET(zone_name), KVADDR, &temp,
> +                                     sizeof(void *), "node_zones name",
> +                                     FAULT_ON_ERROR);
> +                             read_string(temp, name_buf, BUFSIZE-1);
> +
> +                             fprintf(fp, "Node %4d, ", nt->node_id);
> +                             fprintf(fp, "zone %8s, ", name_buf);
> +
> +                             if (mtype_sym) {
> +                                     read_string(mtypes[m],
> +                                             name_buf, BUFSIZE-1);
> +                                     fprintf(fp, "type %12s ", name_buf);
> +                             } else
> +                                     fprintf(fp, "type %12d ", m);
> +
> +                             for (o = 0; o < vt->nr_free_areas; o++) {
> +                                     freelist =
> +                                     (node_zones + (z * SIZE(zone)))
> +                                     + (OFFSET(zone_free_area) +
> +                                     (o * SIZE(free_area))) +
> +                                     (m * SIZE(list_head));
> +
> +                                     readmem(freelist, KVADDR, free_list_buf,
> +                                             SIZE(list_head),
> +                                             "free_area free_list",
> +                                             FAULT_ON_ERROR);
> +
> +                                     free_ptr = (ulong *)free_list_buf;
> +
> +                                     if (!(*free_ptr) ||
> +                                             (*free_ptr == freelist)) {
> +                                             fprintf(fp, "%6lu ", 0);
> +                                             continue;
> +                                     }
> +
> +                                     BZERO(&list_data,
> +                                             sizeof(struct list_data));
> +                                     list_data.flags = RETURN_ON_DUPLICATE;
> +                                     list_data.start = *free_ptr;
> +                                     list_data.end = freelist;
> +                                     list_data.list_head_offset =
> +                                             OFFSET(page_lru) +
> +                                             OFFSET(list_head_next);
> +
> +                                     free_cnt = do_list(&list_data);
> +                                     if (free_cnt < 0) {
> +                                             error(pc->curcmd_flags &
> +                                             IGNORE_ERRORS ? INFO : FATAL,
> +                                             "corrupted free list\n");
> +                                             free_cnt = 0;
> +                                     }
> +
> +                                     fprintf(fp, "%6lu ", free_cnt);
> +                             }
> +                             fprintf(fp, "\n");
> +                     }
> +             }
> +             node_zones + OFFSET(zone_free_area);
> +     }
> +
> +     FREEBUF(free_list_buf);
> +
> +     if (mtype_sym)
> +             FREEBUF(mtypes);
> +}
> +
>  /*
>   *  dump_kmeminfo displays basic memory use information typically
>   shown
>   *  by /proc/meminfo, and then some...
> --
> 1.7.6
> 

--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to