const char *modifier;
        /** The expression to parse, for example, "instructions/cycles". */
        const char *metric_expr;
+       /** Optional threshold expression where zero value is green, otherwise red. */
+       const char *metric_threshold;
        /**
         * The "ScaleUnit" that scales and adds a unit to the metric during
         * output.
                        goto out_err;
        }
        m->metric_expr = pm->metric_expr;
+       m->metric_threshold = pm->metric_threshold;
        m->metric_unit = pm->unit;
        m->pctx->sctx.user_requested_cpu_list = NULL;
        if (user_requested_cpu_list) {
        const struct visited_metric *vm;
        int ret;
        bool is_root = !root_metric;
+       const char *expr;
        struct visited_metric visited_node = {
                .name = pm->metric_name,
                .parent = visited,
         * For both the parent and referenced metrics, we parse
         * all the metric's IDs and add it to the root context.
         */
-       if (expr__find_ids(pm->metric_expr, NULL, root_metric->pctx) < 0) {
+       ret = 0;
+       expr = pm->metric_expr;
+       if (is_root && pm->metric_threshold) {
+               /*
+                * Threshold expressions are built off the actual metric. Switch
+                * to use that in case of additional necessary events. Change
+                * the visited node name to avoid this being flagged as
+                * recursion.
+                */
+               assert(strstr(pm->metric_threshold, pm->metric_name));
+               expr = pm->metric_threshold;
+               visited_node.name = "__threshold__";
+       }
+       if (expr__find_ids(expr, NULL, root_metric->pctx) < 0) {
                /* Broken metric. */
                ret = -EINVAL;
-       } else {
+       }
+       if (!ret) {
                /* Resolve referenced metrics. */
                ret = resolve_metric(metric_list, modifier, metric_no_group,
                                     user_requested_cpu_list, system_wide,
                                     root_metric, &visited_node, table);
        }
-
        if (ret) {
                if (is_root)
                        metric__free(root_metric);
                        free(metric_events);
                        goto out;
                }
+               expr->metric_threshold = m->metric_threshold;
                expr->metric_unit = m->metric_unit;
                expr->metric_events = metric_events;
                expr->runtime = m->pctx->sctx.runtime;
 
 
 static void generic_metric(struct perf_stat_config *config,
                           const char *metric_expr,
+                          const char *metric_threshold,
                           struct evsel **metric_events,
                           struct metric_ref *metric_refs,
                           char *name,
 {
        print_metric_t print_metric = out->print_metric;
        struct expr_parse_ctx *pctx;
-       double ratio, scale;
+       double ratio, scale, threshold;
        int i;
        void *ctxp = out->ctx;
+       const char *color = NULL;
 
        pctx = expr__ctx_new();
        if (!pctx)
                        char *unit;
                        char metric_bf[64];
 
+                       if (metric_threshold &&
+                           expr__parse(&threshold, pctx, metric_threshold) == 0) {
+                               color = fpclassify(threshold) == FP_ZERO
+                                       ? PERF_COLOR_GREEN : PERF_COLOR_RED;
+                       }
+
                        if (metric_unit && metric_name) {
                                if (perf_pmu__convert_scale(metric_unit,
                                        &unit, &scale) >= 0) {
                                        scnprintf(metric_bf, sizeof(metric_bf),
                                          "%s  %s", unit, metric_name);
 
-                               print_metric(config, ctxp, NULL, "%8.1f",
+                               print_metric(config, ctxp, color, "%8.1f",
                                             metric_bf, ratio);
                        } else {
-                               print_metric(config, ctxp, NULL, "%8.2f",
+                               print_metric(config, ctxp, color, "%8.2f",
                                        metric_name ?
                                        metric_name :
                                        out->force_header ?  name : "",
                                        ratio);
                        }
                } else {
-                       print_metric(config, ctxp, NULL, NULL,
+                       print_metric(config, ctxp, color, /*unit=*/NULL,
                                     out->force_header ?
                                     (metric_name ? metric_name : name) : "", 0);
                }
        } else {
-               print_metric(config, ctxp, NULL, NULL,
+               print_metric(config, ctxp, color, /*unit=*/NULL,
                             out->force_header ?
                             (metric_name ? metric_name : name) : "", 0);
        }
                list_for_each_entry (mexp, &me->head, nd) {
                        if (num++ > 0)
                                out->new_line(config, ctxp);
-                       generic_metric(config, mexp->metric_expr, mexp->metric_events,
-                                      mexp->metric_refs, evsel->name, mexp->metric_name,
-                                      mexp->metric_unit, mexp->runtime,
+                       generic_metric(config, mexp->metric_expr, mexp->metric_threshold,
+                                      mexp->metric_events, mexp->metric_refs, evsel->name,
+                                      mexp->metric_name, mexp->metric_unit, mexp->runtime,
                                       map_idx, out, st);
                }
        }