Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp775930pxb; Wed, 15 Sep 2021 12:56:45 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwHszEZwETlJmCF8HXHPdwrK0HZOm/oLL0YcRMTN7wKSdihE+UxMAopp8442XO7DmHUIh0A X-Received: by 2002:a92:d84f:: with SMTP id h15mr1348908ilq.42.1631735804813; Wed, 15 Sep 2021 12:56:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631735804; cv=none; d=google.com; s=arc-20160816; b=ahJSlQK5nk0FQHRhH7xq9DIhCaFnuf6/Ft3P3+majQ2lRKkeCXeGalP4XDAmnrEg1R ne6RYmN3aBV1hjhNr992kfxKe6P5Bhkj1xFsef8cyYRXn1K4SmsAGVe/haxzPkN50QGy uglhDNnzTOwXcmV5Qu5ALEXvpsDK/4wVi9E9SpS8vFcWeXPSIfQvljtTqoZ1+GzDzGia bvzLTWSJygEq1MLEJo0DnLWJLcR734J7eGJ99iKubqih3txfHjk3a2nbf/po7YExeryq tAFRoO97oVpfU8vJ3J+fFd0EwIE86j416HClYo+ELEuXGDOllIRcZVIqlMKDEV63Dfh4 brzQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:to:cc:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=aeNnN9xag+ICPAe0ffKzWBBB/Z6CmxOcYPRHh7D2frs=; b=pKKDCOAKlBBB3onNnQKmkKvAQpZPXz5BBQ5oL2WKmE66McjOWo/vJXrgwhSdHRZ81W bSixmlREpQu0bGa4ntQNnQXqkrcbbXtgyzE81C+MPehwK/iOSH3dlV9w63sZZwz45Fbm WYUGYnPXTcpxZb+naUehY0bnGJEX+4Oqkx0UlufhwAIyWVgta3lbqSOa+y/6cX1k7wQu J75prfwBZJwtrxgK9/sXcbBFKhOuJv2/Ets/iNsl6Hm5qixAdBFTaUauUzpMOJVj9pdk U9CEOCQ2G675n534lnOFfDo8G6EsLiyjYxYyv0VGtDNgLmRwxNRS7pa8/7xuN02yy7+C tYpg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=qIerQ+9u; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id 15si956101ilt.96.2021.09.15.12.56.33; Wed, 15 Sep 2021 12:56:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=qIerQ+9u; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231490AbhIOT4D (ORCPT + 99 others); Wed, 15 Sep 2021 15:56:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50656 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231487AbhIOT4C (ORCPT ); Wed, 15 Sep 2021 15:56:02 -0400 Received: from mail-qv1-xf49.google.com (mail-qv1-xf49.google.com [IPv6:2607:f8b0:4864:20::f49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB3B9C061764 for ; Wed, 15 Sep 2021 12:54:42 -0700 (PDT) Received: by mail-qv1-xf49.google.com with SMTP id ib9-20020a0562141c8900b003671c3a1243so7782950qvb.21 for ; Wed, 15 Sep 2021 12:54:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:cc; bh=aeNnN9xag+ICPAe0ffKzWBBB/Z6CmxOcYPRHh7D2frs=; b=qIerQ+9u8w+7e+qc1Pt4BEtWWL4xi9o8Z0pshF/NwvFawnX2spGgfsa9wOdgOOK9XQ RsJjzY7WGt/x7Wfs3fZPhK7HV2XBvzYQhv2bGfwblwPJ+AxlvEq944N7y6+C/zP6st/K twrstG4QdSPG3LQcpZ+dcCdMORJbjS3Ap/fnWfckbmFtO9pZm6gHHt2z+NsiRWTxOh3N i1JHv9yIrsHipRryQvgavJikwchYg2qHfdG7ep7gkYP6fB7Fx4+dOei0JgekEhb01/g+ AxBKKH+J4nWVjPfNEtTSPGqEoxCFWJegufYxQbs+ajtcOyaU0QEDGRnDFLlHFR9Muinr y2iA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:cc; bh=aeNnN9xag+ICPAe0ffKzWBBB/Z6CmxOcYPRHh7D2frs=; b=USXrSmhbUHU0jYqpT08X4JhCgVWdR4mO6pq58L1mWxV+6WFBxYK9ggpXjpdtOk2pgc Hc+AVPYSPncPp3HmXXWqRUVbTBvPlmCS4vqOKbJHdGqpX5bgQfhS0x55sEKtL0p1uUZC hMlWuQUTtKVTbJ1Nu3M2rHelY4OITPa6VuVxrNL9eIz3MuitoR9SK3gxzZfBIGS9A4E2 7Hai+Sc7c+JQISfSfjn1c93WlEveec/ClPO6HULZCm4QXqRi5ljst+rgd9qavgXS8jkY L0sLJetKuQdkdVdz8itmhu18Q/sDTAHKRsSC2v6TkivEyy+3GCRdRTAZkY5cMBEhX1wr qzVw== X-Gm-Message-State: AOAM532bCIhQY2o9YeAq7a5QWgKg/0J2xW9DHnCHVjB0nxqazh3/Vg45 Qil39nZ3zPOJyq4VnV16J4i93ZBVVyZYrNsEyQ== X-Received: from kaleshsingh.c.googlers.com ([fda3:e722:ac3:cc00:14:4d90:c0a8:2145]) (user=kaleshsingh job=sendgmr) by 2002:a0c:f58a:: with SMTP id k10mr1752710qvm.62.1631735681948; Wed, 15 Sep 2021 12:54:41 -0700 (PDT) Date: Wed, 15 Sep 2021 19:52:46 +0000 In-Reply-To: <20210915195306.612966-1-kaleshsingh@google.com> Message-Id: <20210915195306.612966-3-kaleshsingh@google.com> Mime-Version: 1.0 References: <20210915195306.612966-1-kaleshsingh@google.com> X-Mailer: git-send-email 2.33.0.309.g3052b89438-goog Subject: [PATCH 2/5] tracing: Add division and multiplication support for hist triggers From: Kalesh Singh Cc: surenb@google.com, hridya@google.com, namhyung@kernel.org, Kalesh Singh , Jonathan Corbet , Steven Rostedt , Ingo Molnar , Shuah Khan , Tom Zanussi , Masami Hiramatsu , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Content-Type: text/plain; charset="UTF-8" To: unlisted-recipients:; (no To-header on input) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Adds basic support for division and multiplication operations for hist trigger variable expressions. For simplicity this patch only supports, division and multiplication for a single operation expression (e.g. x=$a/$b), as currently expressions are always evaluated right to left. This can lead to some incorrect results: e.g. echo 'hist:keys=common_pid:x=8-4-2' >> event/trigger 8-4-2 should evaluate to 2 i.e. (8-4)-2 but currently x evaluate to 6 i.e. 8-(4-2) Multiplication and division in sub-expressions will work correctly, once correct operator precedence support is added (See next patch in this series). For the undefined case of division by 0, the histogram expression evaluates to (u64)(-1). Since this cannot be detected when the expression is created, it is the responsibility of the user to be aware and account for this possibility. Examples: echo 'hist:keys=common_pid:a=8,b=4,x=$a/$b' \ >> event/trigger echo 'hist:keys=common_pid:x=5*$b' \ >> event/trigger Signed-off-by: Kalesh Singh --- kernel/trace/trace_events_hist.c | 72 +++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 2802b211ccf3..dc28eb6fc73a 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -99,6 +99,8 @@ enum field_op_id { FIELD_OP_PLUS, FIELD_OP_MINUS, FIELD_OP_UNARY_MINUS, + FIELD_OP_DIV, + FIELD_OP_MULT, }; /* @@ -287,6 +289,40 @@ static u64 hist_field_minus(struct hist_field *hist_field, return val1 - val2; } +static u64 hist_field_div(struct hist_field *hist_field, + struct tracing_map_elt *elt, + struct trace_buffer *buffer, + struct ring_buffer_event *rbe, + void *event) +{ + struct hist_field *operand1 = hist_field->operands[0]; + struct hist_field *operand2 = hist_field->operands[1]; + + u64 val1 = operand1->fn(operand1, elt, buffer, rbe, event); + u64 val2 = operand2->fn(operand2, elt, buffer, rbe, event); + + /* Return -1 for the undefined case */ + if (!val2) + return -1; + + return val1 / val2; +} + +static u64 hist_field_mult(struct hist_field *hist_field, + struct tracing_map_elt *elt, + struct trace_buffer *buffer, + struct ring_buffer_event *rbe, + void *event) +{ + struct hist_field *operand1 = hist_field->operands[0]; + struct hist_field *operand2 = hist_field->operands[1]; + + u64 val1 = operand1->fn(operand1, elt, buffer, rbe, event); + u64 val2 = operand2->fn(operand2, elt, buffer, rbe, event); + + return val1 * val2; +} + static u64 hist_field_unary_minus(struct hist_field *hist_field, struct tracing_map_elt *elt, struct trace_buffer *buffer, @@ -1595,6 +1631,12 @@ static char *expr_str(struct hist_field *field, unsigned int level) case FIELD_OP_PLUS: strcat(expr, "+"); break; + case FIELD_OP_DIV: + strcat(expr, "/"); + break; + case FIELD_OP_MULT: + strcat(expr, "*"); + break; default: kfree(expr); return NULL; @@ -1610,7 +1652,7 @@ static int contains_operator(char *str) enum field_op_id field_op = FIELD_OP_NONE; char *op; - op = strpbrk(str, "+-"); + op = strpbrk(str, "+-/*"); if (!op) return FIELD_OP_NONE; @@ -1631,6 +1673,12 @@ static int contains_operator(char *str) case '+': field_op = FIELD_OP_PLUS; break; + case '/': + field_op = FIELD_OP_DIV; + break; + case '*': + field_op = FIELD_OP_MULT; + break; default: break; } @@ -2370,10 +2418,26 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, case FIELD_OP_PLUS: sep = "+"; break; + case FIELD_OP_DIV: + sep = "/"; + break; + case FIELD_OP_MULT: + sep = "*"; + break; default: goto free; } + /* + * Multiplication and division are only supported in single operator + * expressions, since the expression is always evaluated from right + * to left. + */ + if ((field_op == FIELD_OP_DIV || field_op == FIELD_OP_MULT) && level > 0) { + hist_err(file->tr, HIST_ERR_TOO_MANY_SUBEXPR, errpos(str)); + return ERR_PTR(-EINVAL); + } + operand1_str = strsep(&str, sep); if (!operand1_str || !str) goto free; @@ -2445,6 +2509,12 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, case FIELD_OP_PLUS: expr->fn = hist_field_plus; break; + case FIELD_OP_DIV: + expr->fn = hist_field_div; + break; + case FIELD_OP_MULT: + expr->fn = hist_field_mult; + break; default: ret = -EINVAL; goto free; -- 2.33.0.309.g3052b89438-goog