HIST_FIELD_FL_ALIAS             = 1 << 16,
        HIST_FIELD_FL_BUCKET            = 1 << 17,
        HIST_FIELD_FL_CONST             = 1 << 18,
+       HIST_FIELD_FL_PERCENT           = 1 << 19,
 };
 
 struct var_defs {
                flags_str = "buckets";
        else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP_USECS)
                flags_str = "usecs";
+       else if (hist_field->flags & HIST_FIELD_FL_PERCENT)
+               flags_str = "percent";
 
        return flags_str;
 }
                        if (ret || !(*buckets))
                                goto error;
                        *flags |= HIST_FIELD_FL_BUCKET;
+               } else if (strncmp(modifier, "percent", 7) == 0) {
+                       if (*flags & (HIST_FIELD_FL_VAR | HIST_FIELD_FL_KEY))
+                               goto error;
+                       *flags |= HIST_FIELD_FL_PERCENT;
                } else {
  error:
                        hist_err(tr, HIST_ERR_BAD_FIELD_MODIFIER, errpos(modifier));
        seq_puts(m, "}");
 }
 
+/* Get the 100 times of the percentage of @val in @total */
+static inline unsigned int __get_percentage(u64 val, u64 total)
+{
+       if (!total)
+               goto div0;
+
+       if (val < (U64_MAX / 10000))
+               return (unsigned int)div64_ul(val * 10000, total);
+
+       total = div64_u64(total, 10000);
+       if (!total)
+               goto div0;
+
+       return (unsigned int)div64_ul(val, total);
+div0:
+       return val ? UINT_MAX : 0;
+}
+
+static void hist_trigger_print_val(struct seq_file *m, unsigned int idx,
+                                  const char *field_name, unsigned long flags,
+                                  u64 *totals, struct tracing_map_elt *elt)
+{
+       u64 val = tracing_map_read_sum(elt, idx);
+       unsigned int pc;
+
+       if (flags & HIST_FIELD_FL_PERCENT) {
+               pc = __get_percentage(val, totals[idx]);
+               if (pc == UINT_MAX)
+                       seq_printf(m, " %s (%%):[ERROR]", field_name);
+               else
+                       seq_printf(m, " %s (%%): %3u.%02u", field_name,
+                                       pc / 100, pc % 100);
+       } else if (flags & HIST_FIELD_FL_HEX) {
+               seq_printf(m, " %s: %10llx", field_name, val);
+       } else {
+               seq_printf(m, " %s: %10llu", field_name, val);
+       }
+}
+
 static void hist_trigger_entry_print(struct seq_file *m,
                                     struct hist_trigger_data *hist_data,
+                                    u64 *totals,
                                     void *key,
                                     struct tracing_map_elt *elt)
 {
        const char *field_name;
-       unsigned int i;
+       unsigned int i = HITCOUNT_IDX;
+       unsigned long flags;
 
        hist_trigger_print_key(m, hist_data, key, elt);
 
-       seq_printf(m, " hitcount: %10llu",
-                  tracing_map_read_sum(elt, HITCOUNT_IDX));
+       /* At first, show the raw hitcount always */
+       hist_trigger_print_val(m, i, "hitcount", 0, totals, elt);
 
        for (i = 1; i < hist_data->n_vals; i++) {
                field_name = hist_field_name(hist_data->fields[i], 0);
+               flags = hist_data->fields[i]->flags;
 
-               if (hist_data->fields[i]->flags & HIST_FIELD_FL_VAR ||
-                   hist_data->fields[i]->flags & HIST_FIELD_FL_EXPR)
+               if (flags & HIST_FIELD_FL_VAR || flags & HIST_FIELD_FL_EXPR)
                        continue;
 
-               if (hist_data->fields[i]->flags & HIST_FIELD_FL_HEX) {
-                       seq_printf(m, "  %s: %10llx", field_name,
-                                  tracing_map_read_sum(elt, i));
-               } else {
-                       seq_printf(m, "  %s: %10llu", field_name,
-                                  tracing_map_read_sum(elt, i));
-               }
+               seq_puts(m, " ");
+               hist_trigger_print_val(m, i, field_name, flags, totals, elt);
        }
 
        print_actions(m, hist_data, elt);
 {
        struct tracing_map_sort_entry **sort_entries = NULL;
        struct tracing_map *map = hist_data->map;
-       int i, n_entries;
+       int i, j, n_entries;
+       u64 *totals = NULL;
 
        n_entries = tracing_map_sort_entries(map, hist_data->sort_keys,
                                             hist_data->n_sort_keys,
        if (n_entries < 0)
                return n_entries;
 
+       for (j = 0; j < hist_data->n_vals; j++) {
+               if (!(hist_data->fields[j]->flags & HIST_FIELD_FL_PERCENT))
+                       continue;
+               if (!totals) {
+                       totals = kcalloc(hist_data->n_vals, sizeof(u64),
+                                        GFP_KERNEL);
+                       if (!totals) {
+                               n_entries = -ENOMEM;
+                               goto out;
+                       }
+               }
+               for (i = 0; i < n_entries; i++)
+                       totals[j] += tracing_map_read_sum(
+                                       sort_entries[i]->elt, j);
+       }
+
        for (i = 0; i < n_entries; i++)
-               hist_trigger_entry_print(m, hist_data,
+               hist_trigger_entry_print(m, hist_data, totals,
                                         sort_entries[i]->key,
                                         sort_entries[i]->elt);
 
+       kfree(totals);
+out:
        tracing_map_destroy_sort_entries(sort_entries, n_entries);
 
        return n_entries;