From patchwork Fri Jun 9 15:03:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Schneider X-Patchwork-Id: 105698 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6358:3046:b0:115:7a1d:dabb with SMTP id p6csp1064462rwl; Fri, 9 Jun 2023 08:10:12 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5wOrOkuFYwbppxP8uDrb0CWPd94Kr+j0kFGqqcLGB9iq0SzQHH+GaHFp191fWkaptY7loQ X-Received: by 2002:a17:90a:bd90:b0:256:b190:2733 with SMTP id z16-20020a17090abd9000b00256b1902733mr1146050pjr.33.1686323412337; Fri, 09 Jun 2023 08:10:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686323412; cv=none; d=google.com; s=arc-20160816; b=nALvF305w/AjIvXgWsoQgpeRyviWeuj19xJ5u7DOg/Gxf5b3iSEVfHGGvT7b85u9WQ Rr2hoEb8AwfPcaT5itoxpRGJn1jk+nwqSooI7C2Ha4dHB9fV4WBKWiABI7+WskdU/zfE PDTa7T/bZskh9aPL8Sgun/i3GgFMB50AhIB0VdrG1QcJObNmviMzO4FEUHPf6wOM2sfu SY+vfJqMfbAQaGa/L9BkB2Tm4J3RekUYXqtBiKaMe96wm/cB7r676L1dbaKXp7JHaUsy RYCfkxZ3aPaRh2hgCyqnY+P3zm+hrxeGPoTQOSd0uepVryN0fvrxJkTgpdosqu9akbDN I4nw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=BTFUs8gxr9moRkZBUGlN4k/3c1CssODo/4E7AM+Boo0=; b=skMceilbK/SE5E6LfIg3npIDTZEeL9ep6War3b97inCqZcxCtZhDgfvYj3mrGPH2bY Fweo3Hy/JF6BA3d03oYzolOYLe5EdyuXLkoHcp6EussCOsRyPnMF7vtdpBfIVsxMUxEP +x/u6LaTdBCJNXf8ZU3iu3CQX9RleVXwXsvftsh2saS9X18bpB+Sxld0ipFwDCW1tU9+ Cb2rmM8KZCdRVdeHjfHd/GOJGdkrXNhT/mgnQ7jozpihEnq1X3noso2wFNj4F7huPqqJ KcEcMIXn/MY0FDY5zmU1H5xpfqt+RChsyvQTTfM7o7TAc0esEF5JKBJyZfGn+BqrMAG2 WYmA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=SjyG5SK5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id a21-20020a170902b59500b001ac83d19265si2740647pls.291.2023.06.09.08.09.58; Fri, 09 Jun 2023 08:10:12 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=SjyG5SK5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241822AbjFIPF0 (ORCPT + 99 others); Fri, 9 Jun 2023 11:05:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44714 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241737AbjFIPFI (ORCPT ); Fri, 9 Jun 2023 11:05:08 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2D80130E4 for ; Fri, 9 Jun 2023 08:04:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1686323058; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BTFUs8gxr9moRkZBUGlN4k/3c1CssODo/4E7AM+Boo0=; b=SjyG5SK5fCa1O9gr1DsjMuwVuiXGPn109aVpGxNjqFCKHDSra/m2Nihbs/lc1F/qJ831LV aYeJWl5XpTxYdmrxHq9W9Y9KQo+FbtgzUJ4ghRbifL5Dy/xmGEChfbZ8rNXso9APvVqtcD DOUC1FyCr0GHJSzPmbzdCPkQ0AXVX5I= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-157-vuAZu9-eP4-7JP3ypZOA8g-1; Fri, 09 Jun 2023 11:04:17 -0400 X-MC-Unique: vuAZu9-eP4-7JP3ypZOA8g-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 83AEB101A53B; Fri, 9 Jun 2023 15:04:16 +0000 (UTC) Received: from vschneid.remote.csb (unknown [10.42.28.16]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 17BEE4087C67; Fri, 9 Jun 2023 15:04:14 +0000 (UTC) From: Valentin Schneider To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org Cc: Steven Rostedt , Masami Hiramatsu , Jonathan Corbet , Juri Lelli , Daniel Bristot de Oliveira , Marcelo Tosatti , Leonardo Bras , Frederic Weisbecker Subject: [RFC PATCH 3/5] tracing/filters: Enable filtering a scalar field by a cpumask Date: Fri, 9 Jun 2023 16:03:22 +0100 Message-Id: <20230609150324.143538-4-vschneid@redhat.com> In-Reply-To: <20230609150324.143538-1-vschneid@redhat.com> References: <20230609150324.143538-1-vschneid@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1768238258174316243?= X-GMAIL-MSGID: =?utf-8?q?1768238258174316243?= Several events use a scalar field to denote a CPU: o sched_wakeup.target_cpu o sched_migrate_task.orig_cpu,dest_cpu o sched_move_numa.src_cpu,dst_cpu o ipi_send_cpu.cpu o ... Filtering these currently requires using arithmetic comparison functions, which can be tedious when dealing with interleaved SMT or NUMA CPU ids. Allow these to be filtered by a user-provided cpumask, which enables e.g.: $ trace-cmd record -e 'sched_wakeup' -f 'target_cpu & MASK{2,4,6,8-32}' Signed-off-by: Valentin Schneider --- NOTE: I went with an implicit cpumask conversion of the event field, as AFAICT predicate_parse() does not support parsing the application of a function to a field (e.g. 'MASK(target_cpu) & MASK{2,4,6,8-32}') --- kernel/trace/trace_events_filter.c | 92 ++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 12 deletions(-) diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 8af00caa363f7..99e111c237a93 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -46,15 +46,19 @@ static const char * ops[] = { OPS }; enum filter_pred_fn { FILTER_PRED_FN_NOP, FILTER_PRED_FN_64, + FILTER_PRED_FN_64_CPUMASK, FILTER_PRED_FN_S64, FILTER_PRED_FN_U64, FILTER_PRED_FN_32, + FILTER_PRED_FN_32_CPUMASK, FILTER_PRED_FN_S32, FILTER_PRED_FN_U32, FILTER_PRED_FN_16, + FILTER_PRED_FN_16_CPUMASK, FILTER_PRED_FN_S16, FILTER_PRED_FN_U16, FILTER_PRED_FN_8, + FILTER_PRED_FN_8_CPUMASK, FILTER_PRED_FN_S8, FILTER_PRED_FN_U8, FILTER_PRED_FN_COMM, @@ -641,6 +645,37 @@ predicate_parse(const char *str, int nr_parens, int nr_preds, return ERR_PTR(ret); } +static inline int +do_filter_cpumask(int op, const struct cpumask *mask, const struct cpumask *cmp) +{ + switch (op) { + case OP_EQ: + return cpumask_equal(mask, cmp); + case OP_NE: + return !cpumask_equal(mask, cmp); + case OP_BAND: + return cpumask_intersects(mask, cmp); + default: + return 0; + } +} + +/* Optimisation of do_filter_cpumask() for scalar values */ +static inline int +do_filter_cpumask_scalar(int op, unsigned int cpu, const struct cpumask *mask) +{ + switch (op) { + case OP_EQ: + return cpumask_equal(mask, cpumask_of(cpu)); + case OP_NE: + return !cpumask_equal(mask, cpumask_of(cpu)); + case OP_BAND: + return cpumask_test_cpu(cpu, mask); + default: + return 0; + } +} + enum pred_cmp_types { PRED_CMP_TYPE_NOP, PRED_CMP_TYPE_LT, @@ -684,6 +719,18 @@ static int filter_pred_##type(struct filter_pred *pred, void *event) \ } \ } +#define DEFINE_CPUMASK_COMPARISON_PRED(size) \ +static int filter_pred_##size##_cpumask(struct filter_pred *pred, void *event) \ +{ \ + u##size *addr = (u##size *)(event + pred->offset); \ + unsigned int cpu = *addr; \ + \ + if (cpu >= nr_cpu_ids) \ + return 0; \ + \ + return do_filter_cpumask_scalar(pred->op, cpu, pred->mask); \ +} + #define DEFINE_EQUALITY_PRED(size) \ static int filter_pred_##size(struct filter_pred *pred, void *event) \ { \ @@ -705,6 +752,11 @@ DEFINE_COMPARISON_PRED(u16); DEFINE_COMPARISON_PRED(s8); DEFINE_COMPARISON_PRED(u8); +DEFINE_CPUMASK_COMPARISON_PRED(64); +DEFINE_CPUMASK_COMPARISON_PRED(32); +DEFINE_CPUMASK_COMPARISON_PRED(16); +DEFINE_CPUMASK_COMPARISON_PRED(8); + DEFINE_EQUALITY_PRED(64); DEFINE_EQUALITY_PRED(32); DEFINE_EQUALITY_PRED(16); @@ -889,16 +941,7 @@ static int filter_pred_cpumask(struct filter_pred *pred, void *event) const struct cpumask *mask = (event + loc); const struct cpumask *cmp = pred->mask; - switch (pred->op) { - case OP_EQ: - return cpumask_equal(mask, cmp); - case OP_NE: - return !cpumask_equal(mask, cmp); - case OP_BAND: - return cpumask_intersects(mask, cmp); - default: - return 0; - } + return do_filter_cpumask(pred->op, mask, cmp); } /* Filter predicate for COMM. */ @@ -1349,24 +1392,32 @@ static int filter_pred_fn_call(struct filter_pred *pred, void *event) switch (pred->fn_num) { case FILTER_PRED_FN_64: return filter_pred_64(pred, event); + case FILTER_PRED_FN_64_CPUMASK: + return filter_pred_64_cpumask(pred, event); case FILTER_PRED_FN_S64: return filter_pred_s64(pred, event); case FILTER_PRED_FN_U64: return filter_pred_u64(pred, event); case FILTER_PRED_FN_32: return filter_pred_32(pred, event); + case FILTER_PRED_FN_32_CPUMASK: + return filter_pred_32_cpumask(pred, event); case FILTER_PRED_FN_S32: return filter_pred_s32(pred, event); case FILTER_PRED_FN_U32: return filter_pred_u32(pred, event); case FILTER_PRED_FN_16: return filter_pred_16(pred, event); + case FILTER_PRED_FN_16_CPUMASK: + return filter_pred_16_cpumask(pred, event); case FILTER_PRED_FN_S16: return filter_pred_s16(pred, event); case FILTER_PRED_FN_U16: return filter_pred_u16(pred, event); case FILTER_PRED_FN_8: return filter_pred_8(pred, event); + case FILTER_PRED_FN_8_CPUMASK: + return filter_pred_8_cpumask(pred, event); case FILTER_PRED_FN_S8: return filter_pred_s8(pred, event); case FILTER_PRED_FN_U8: @@ -1602,7 +1653,8 @@ static int parse_pred(const char *str, void *data, unsigned int maskstart; char *tmp; - if (field->filter_type != FILTER_CPUMASK) { + if (field->filter_type != FILTER_CPUMASK && + field->filter_type != FILTER_OTHER) { parse_error(pe, FILT_ERR_ILLEGAL_FIELD_OP, pos + i); goto err_free; } @@ -1644,8 +1696,24 @@ static int parse_pred(const char *str, void *data, /* Move along */ i++; - if (field->filter_type == FILTER_CPUMASK) + if (field->filter_type == FILTER_CPUMASK) { pred->fn_num = FILTER_PRED_FN_CPUMASK; + } else { + switch (field->size) { + case 8: + pred->fn_num = FILTER_PRED_FN_64_CPUMASK; + break; + case 4: + pred->fn_num = FILTER_PRED_FN_32_CPUMASK; + break; + case 2: + pred->fn_num = FILTER_PRED_FN_16_CPUMASK; + break; + case 1: + pred->fn_num = FILTER_PRED_FN_8_CPUMASK; + break; + } + } /* This is either a string, or an integer */ } else if (str[i] == '\'' || str[i] == '"') {