The btf pretty print is added to percpu arraymap,
percpu hashmap and percpu lru hashmap.
For each <key, value> pair, the following will be
added to plain/json output:

   {
       "key": <pretty_print_key>,
       "values": [{
             "cpu": 0,
             "value": <pretty_print_value_on_cpu0>
          },{
             "cpu": 1,
             "value": <pretty_print_value_on_cpu1>
          },{
          ....
          },{
             "cpu": n,
             "value": <pretty_print_value_on_cpun>
          }
       ]
   }

For example, the following could be part of plain or json formatted
output:
    {
        "key": 0,
        "values": [{
                "cpu": 0,
                "value": {
                    "ui32": 0,
                    "ui16": 0,
                }
            },{
                "cpu": 1,
                "value": {
                    "ui32": 1,
                    "ui16": 0,
                }
            },{
                "cpu": 2,
                "value": {
                    "ui32": 2,
                    "ui16": 0,
                }
            },{
                "cpu": 3,
                "value": {
                    "ui32": 3,
                    "ui16": 0,
                }
            }
        ]
    }

Signed-off-by: Yonghong Song <y...@fb.com>
---
 tools/bpf/bpftool/map.c | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index b2ec20e562bd..df175bc33c5d 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -169,9 +169,28 @@ static int do_dump_btf(const struct btf_dumper *d,
        if (ret)
                goto err_end_obj;
 
-       jsonw_name(d->jw, "value");
+       if (!map_is_per_cpu(map_info->type)) {
+               jsonw_name(d->jw, "value");
+               ret = btf_dumper_type(d, map_info->btf_value_type_id, value);
+       } else {
+               unsigned int i, n, step;
 
-       ret = btf_dumper_type(d, map_info->btf_value_type_id, value);
+               jsonw_name(d->jw, "values");
+               jsonw_start_array(d->jw);
+               n = get_possible_cpus();
+               step = round_up(map_info->value_size, 8);
+               for (i = 0; i < n; i++) {
+                       jsonw_start_object(d->jw);
+                       jsonw_int_field(d->jw, "cpu", i);
+                       jsonw_name(d->jw, "value");
+                       ret = btf_dumper_type(d, map_info->btf_value_type_id,
+                                             value + i * step);
+                       jsonw_end_object(d->jw);
+                       if (ret)
+                               break;
+               }
+               jsonw_end_array(d->jw);
+       }
 
 err_end_obj:
        /* end of key-value pair */
@@ -298,6 +317,16 @@ static void print_entry_json(struct bpf_map_info *info, 
unsigned char *key,
                        jsonw_end_object(json_wtr);
                }
                jsonw_end_array(json_wtr);
+               if (btf) {
+                       struct btf_dumper d = {
+                               .btf = btf,
+                               .jw = json_wtr,
+                               .is_plain_text = false,
+                       };
+
+                       jsonw_name(json_wtr, "formatted");
+                       do_dump_btf(&d, info, key, value);
+               }
        }
 
        jsonw_end_object(json_wtr);
-- 
2.14.3

Reply via email to