Received: by 2002:a05:7412:b10a:b0:f3:1519:9f41 with SMTP id az10csp680467rdb; Thu, 30 Nov 2023 15:42:40 -0800 (PST) X-Google-Smtp-Source: AGHT+IGfAviUzuXG/UNJqYdZKDMiOJ+kh/XJxQ/gnxyacsyqaYjDyRKeifdVAn7k1y8mxyo6x6PO X-Received: by 2002:a05:6a00:3926:b0:690:c75e:25c8 with SMTP id fh38-20020a056a00392600b00690c75e25c8mr27176119pfb.7.1701387760336; Thu, 30 Nov 2023 15:42:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701387760; cv=none; d=google.com; s=arc-20160816; b=EcZpnrk4pJaK+A2vDhS7zDG+9NYyVad8XYEkkLUyN50D2SlI1Neml4MlE/VOYlZX5f WvOteCs05j4UjhYBZGS1w6BJdwU4FzbmPdswNgDgyaxSJaaVN+c8ShOjE7fVtVpFzceU n0KmG4XDEAPc6wMD5TTR7NmIKHu+pylisuK4TSg+cdiuLziLaM84zEI1+K+479scPZJF BH8vW177GhqMHRhN2UIRaEpWretMF45o7bZcVtM/I/Gsjey1yBihJWPZBaeAvXTTCgWB 2hvHq9dykLih4Bl7v6iF65DG+LagnU+C/6eT9cXHJvcaGklEQhdp+tLp3EPyqvojmzgB O7NQ== 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=pbG5LyFeXhU+t73dZalR5ZvW0pWNtNjpv2RI0v041So=; fh=Xr9EZaLbYspLudo3lCz3I6iQD6BKril0MIzT5DobTXc=; b=ubnNSljDiHRkhIHX8Ly8XrDfvuMpnuYf5F98A9typoKuGkJuZN7WOLp5xdp/0ZUgy4 HMiPnpCUc28pP+ryQdV8UcKdLciGWokFuC8nWFCb+RZPMa0CgHslkK9RTx6TY78wek02 j9JPjO1S95O3+Lb1pJu3MmE3FKnkNs3+5Xrud163xmFVFmYY8dBBeIErb/uLTruGnMmN iTKhETx19YDrEMpB1FER/k4q9bLyi153B4zXqTs8/7xX8M9oVLIuBQhBUpuxAxDry5Ei j44D4edMbPc7oJ8SJSZrmgVVdUUEtOAybt3Z45XwGBOWdbN4f1gam5nbzdPejrO2taHL MKMw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@semihalf.com header.s=google header.b=MI5jhd1V; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=semihalf.com Return-Path: Received: from fry.vger.email (fry.vger.email. [2620:137:e000::3:8]) by mx.google.com with ESMTPS id ck24-20020a056a02091800b005acba4c9bf4si2259761pgb.2.2023.11.30.15.42.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Nov 2023 15:42:40 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) client-ip=2620:137:e000::3:8; Authentication-Results: mx.google.com; dkim=pass header.i=@semihalf.com header.s=google header.b=MI5jhd1V; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=semihalf.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by fry.vger.email (Postfix) with ESMTP id B7CC380F6D08; Thu, 30 Nov 2023 15:42:35 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at fry.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377410AbjK3XmE (ORCPT + 99 others); Thu, 30 Nov 2023 18:42:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35502 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377438AbjK3Xl6 (ORCPT ); Thu, 30 Nov 2023 18:41:58 -0500 Received: from mail-ej1-x62c.google.com (mail-ej1-x62c.google.com [IPv6:2a00:1450:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4BD3A19B6 for ; Thu, 30 Nov 2023 15:41:54 -0800 (PST) Received: by mail-ej1-x62c.google.com with SMTP id a640c23a62f3a-a186e5d1056so189226266b.0 for ; Thu, 30 Nov 2023 15:41:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf.com; s=google; t=1701387712; x=1701992512; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=pbG5LyFeXhU+t73dZalR5ZvW0pWNtNjpv2RI0v041So=; b=MI5jhd1Vfz06GV4aL23OTdh640xToqHdObCXts6urMD8ldzyn74kgOzvuOsDT4LjuQ Bpqpn7O1tKXBNhM/AE/Dav8tQ9Ire2j1v0UgiaNxwCASg6FcHDXJtET6qArVKV3DUp4D Y+SAwteT5a2O2rqV8+adbZDHvwcCCeKbKvX2ZWz7zmhjB2CfOJDIUaTAmWq8aA7P9JWk QMjjL8+8jyGTOpSHiDKIgBRu5BBZtqgW1w1woIr72C/mGj0jii5TtDOVj8350k1V0h0T h8zi0szM5zE2ErPSx+i1V/b55llFCIT3U8kLjnRA+mj2TB5ugQf/V1yNpnjh9m4Iuiad yL3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701387712; x=1701992512; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pbG5LyFeXhU+t73dZalR5ZvW0pWNtNjpv2RI0v041So=; b=GXDa0kNhxmyTi8nHssvW1fPamiwaVmQIV/1J2A3IUWb4ggwL96ye8rUpBswTorKBKB GdJmwsFdLhLIdi9DFcn9fefuzy9xn1KCKKDX/hSE08Y7/sVmVmXSxqSKHxjHwD3pw8wd ZErpRS+d1EL/LFRM2SloTEHtDHhee4YYUSoQ1JqkqZhO7EVuRIxFQHxXnq3ZPMB1r/X2 p/tlUPOhcf2WryIKUeVtm55Vy3DyLb3MpgwbErrI6aDuoUEbPchNASKTTPSwWD45QKfD qn7Apko8kYX3oMGB8lqrd9cmldRtBxuRae3VMH8imLeFKDXMhNIk4Kqqa1z4Sp/h540L iKaA== X-Gm-Message-State: AOJu0Yyj2/Lhmsea/Vs5tz5hucn2AdK1w1tHjAk9DsevvKeVYhMc9eD0 8jt2iwJBY46d3RYLX8nM8p61 X-Received: by 2002:a17:906:1347:b0:a17:d57f:a851 with SMTP id x7-20020a170906134700b00a17d57fa851mr211812ejb.61.1701387712674; Thu, 30 Nov 2023 15:41:52 -0800 (PST) Received: from ukaszb-l.semihalf.net (public-gprs368940.centertel.pl. [37.47.72.109]) by smtp.gmail.com with ESMTPSA id 9-20020a170906100900b009ddaf5ebb6fsm1210175ejm.177.2023.11.30.15.41.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Nov 2023 15:41:52 -0800 (PST) From: =?UTF-8?q?=C5=81ukasz=20Bartosik?= To: Jason Baron , Jim Cromie , Andrew Morton , Kees Cook , Douglas Anderson Cc: Guenter Roeck , Yaniv Tzoreff , Benson Leung , Steven Rostedt , Vincent Whitchurch , Pekka Paalanen , Sean Paul , Daniel Vetter , linux-kernel@vger.kernel.org, upstream@semihalf.com Subject: [PATCH v2 10/15] dyndbg: add open and close commands for trace Date: Fri, 1 Dec 2023 00:40:43 +0100 Message-ID: <20231130234048.157509-11-lb@semihalf.com> X-Mailer: git-send-email 2.43.0.rc2.451.g8631bc7472-goog In-Reply-To: <20231130234048.157509-1-lb@semihalf.com> References: <20231130234048.157509-1-lb@semihalf.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on fry.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (fry.vger.email [0.0.0.0]); Thu, 30 Nov 2023 15:42:35 -0800 (PST) Add open and close commands for opening and closing trace instances. The open command has to be mandatory followed by a trace instance name. If a trace instance already exists in /tracing/instances directory then the open command will reuse it otherwise a new trace instance with a name provided to the open will be created. Close command closes previously opened trace instance. The close will fail if a user tries to close non-existent trace instances or an instance which was not previously opened. For example the following command will open (create or reuse existing) trace instance located in /tracing/instances/usbcore: echo "open usbcore" > /dynamic_debug/control Signed-off-by: Ɓukasz Bartosik --- lib/Kconfig.debug | 1 + lib/dynamic_debug.c | 193 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 5bc56c7247a2..f184c3c91ba3 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -181,6 +181,7 @@ config DYNAMIC_DEBUG_CORE bool "Enable core function of dynamic debug support" depends on PRINTK depends on (DEBUG_FS || PROC_FS) + depends on TRACING help Enable core functional support of dynamic debug. It is useful when you want to tie dynamic debug to your kernel modules with diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 0dc9ec76b867..43e94023a4eb 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -36,6 +36,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -73,6 +74,25 @@ struct flag_settings { unsigned int mask; }; +#define DD_OPEN_CMD "open" +#define DD_CLOSE_CMD "close" +#define DD_TR_EVENT "0" + +struct ddebug_trace_inst { + const char *name; + struct trace_array *arr; +}; + +/* + * TRACE_DST_MAX value is reserved for writing + * debug logs to trace events (prdbg, devdbg) + */ +struct ddebug_trace { + struct ddebug_trace_inst inst[TRACE_DST_MAX-1]; + DECLARE_BITMAP(bmap, TRACE_DST_MAX-1); + int bmap_size; +}; + static DEFINE_MUTEX(ddebug_lock); static LIST_HEAD(ddebug_tables); static int verbose; @@ -80,6 +100,8 @@ module_param(verbose, int, 0644); MODULE_PARM_DESC(verbose, " dynamic_debug/control processing " "( 0 = off (default), 1 = module add/rm, 2 = >control summary, 3 = parsing, 4 = per-site changes)"); +static struct ddebug_trace tr = { .bmap_size = TRACE_DST_MAX-1 }; + static inline struct dd_ctrl *get_ctrl(struct _ddebug *desc) { return &desc->ctrl; @@ -171,6 +193,148 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg) query->first_lineno, query->last_lineno, query->class_string); } +static bool is_ddebug_cmd(const char *str) +{ + if (!strcmp(str, DD_OPEN_CMD) || + !strcmp(str, DD_CLOSE_CMD)) + return true; + + return false; +} + +static bool validate_tr_name(const char *str) +{ + /* "0" is reserved for writing debug logs to trace events (prdbg, devdbg) */ + if (!strcmp(str, DD_TR_EVENT)) + return false; + + /* we allow trace instance names to include ^\w+ and underscore */ + while (*str != '\0') { + if (!isalnum(*str) && *str != '_') + return false; + str++; + } + + return true; +} + +static int find_tr_instance(const char *name) +{ + int idx; + + for_each_set_bit(idx, tr.bmap, tr.bmap_size) + if (!strcmp(tr.inst[idx].name, name)) + return idx; + + return -ENOENT; +} + +static int handle_tr_opend_cmd(const char *arg) +{ + struct ddebug_trace_inst *inst; + int idx, ret = 0; + + mutex_lock(&ddebug_lock); + + idx = find_first_zero_bit(tr.bmap, tr.bmap_size); + if (idx == tr.bmap_size) { + ret = -ENOSPC; + goto end; + } + + if (!validate_tr_name(arg)) { + pr_err("invalid instance name:%s\n", arg); + ret = -EINVAL; + goto end; + } + + if (find_tr_instance(arg) >= 0) { + pr_err("instance is already opened name:%s\n ", arg); + ret = -EEXIST; + goto end; + } + + inst = &tr.inst[idx]; + inst->name = kstrdup(arg, GFP_KERNEL); + if (!inst->name) { + ret = -ENOMEM; + goto end; + } + + inst->arr = trace_array_get_by_name(inst->name); + if (!inst->arr) { + ret = -EINVAL; + goto end; + } + + ret = trace_array_init_printk(inst->arr); + if (ret) { + trace_array_put(inst->arr); + trace_array_destroy(inst->arr); + goto end; + } + + set_bit(idx, tr.bmap); + v3pr_info("opened trace instance idx=%d, name=%s\n", idx, arg); +end: + mutex_unlock(&ddebug_lock); + return ret; +} + +static int handle_tr_close_cmd(const char *arg) +{ + struct ddebug_trace_inst *inst; + int idx, ret = 0; + + mutex_lock(&ddebug_lock); + + idx = find_tr_instance(arg); + if (idx < 0) { + ret = idx; + goto end; + } + + inst = &tr.inst[idx]; + + trace_array_put(inst->arr); + /* + * don't destroy trace instance but let user do it manually + * with rmdir command at a convenient time later, if it is + * destroyed here all debug logs will be lost + * + * trace_array_destroy(inst->arr); + */ + inst->arr = NULL; + + kfree(inst->name); + inst->name = NULL; + + clear_bit(idx, tr.bmap); + v3pr_info("closed trace instance idx=%d, name=%s\n", idx, arg); +end: + mutex_unlock(&ddebug_lock); + return ret; +} + +static int ddebug_parse_cmd(char *words[], int nwords) +{ + int ret; + + if (nwords != 1) + return -EINVAL; + + if (!strcmp(words[0], DD_OPEN_CMD)) + ret = handle_tr_opend_cmd(words[1]); + else if (!strcmp(words[0], DD_CLOSE_CMD)) + ret = handle_tr_close_cmd(words[1]); + else { + pr_err("invalid command %s\n", words[0]); + ret = -EINVAL; + } + + return ret; +} + static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table const *dt, const char *class_string, int *class_id) { @@ -567,6 +731,11 @@ static int ddebug_exec_query(char *query_string, const char *modname) pr_err("tokenize failed\n"); return -EINVAL; } + + /* check for open, close commands */ + if (is_ddebug_cmd(words[0])) + return ddebug_parse_cmd(words, nwords-1); + /* check flags 1st (last arg) so query is pairs of spec,val */ if (ddebug_parse_flags(words[nwords-1], &modifiers)) { pr_err("flags parse failed\n"); @@ -1191,6 +1360,20 @@ static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter) return &iter->table->ddebugs[iter->idx]; } +/* + * Check if the iterator points to the last _ddebug object + * to traverse. + */ +static bool ddebug_iter_is_last(struct ddebug_iter *iter) +{ + if (iter->table == NULL) + return false; + if (iter->idx-1 < 0 && + list_is_last(&iter->table->link, &ddebug_tables)) + return true; + return false; +} + /* * Seq_ops start method. Called at the start of every * read() call from userspace. Takes the ddebug_lock and @@ -1281,6 +1464,16 @@ static int ddebug_proc_show(struct seq_file *m, void *p) } seq_puts(m, "\n"); + if (ddebug_iter_is_last(iter) && + !bitmap_empty(tr.bmap, tr.bmap_size)) { + int idx; + + seq_puts(m, "\n"); + seq_puts(m, "Opened trace instances:\n"); + for_each_set_bit(idx, tr.bmap, tr.bmap_size) + seq_printf(m, "%s\n", tr.inst[idx].name); + } + return 0; } -- 2.43.0.rc2.451.g8631bc7472-goog