From patchwork Tue Mar 28 13:52:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alban Crequy X-Patchwork-Id: 744284 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3vssqT64wCz9s7K for ; Wed, 29 Mar 2017 00:55:49 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="neef3qiP"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755270AbdC1NzI (ORCPT ); Tue, 28 Mar 2017 09:55:08 -0400 Received: from mail-wr0-f195.google.com ([209.85.128.195]:34031 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752531AbdC1NzE (ORCPT ); Tue, 28 Mar 2017 09:55:04 -0400 Received: by mail-wr0-f195.google.com with SMTP id w43so20125558wrb.1; Tue, 28 Mar 2017 06:54:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id; bh=q3L7VZ05Wt5BcXobY6iVCvsH9Qie3TeSRxN3TVwqGdk=; b=neef3qiPjW8tf+yPrDecGik/evZEuvZepPIvMes+5ZOX4lzH+0mlaZIj91FFklkaXi tU2KyOEXNgVfcbf/lH1splBbb3Lv3fBwu8qxgNRkktPwM4bgzRjiI4pljjQjlp7PjKQz lwI5V3QCrg+jcg63wif3H+NFf5xVUCQ1UU/ZD9Pb37yJ2cBowgTSRY0ClXXfGXExurhp 0ltR1dZJorSuLI/I9QZ8F7HN3KZVx22jJwG7JC3TeMPzEsVCoJrm5up82CwZquGN3WOu Obhja8+TUlUp0WIiDRWRzqcdeOLFx8bpmWLOUxPwabZVOb9JQYb3bHv/oBuKrbPFT81p 0fUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=q3L7VZ05Wt5BcXobY6iVCvsH9Qie3TeSRxN3TVwqGdk=; b=acV5OdmN2GU8SjSSX/NjLDvRyqYsNOdfdwLHEliIgImET3O1pNmc9SVq5A5BxuV/Zr kmDe+dRNQYmtMrYajommodh/2Ju2XtaepJOs08DkgNazCY2nvXHIdyHKiN4QTDarF3M9 uLK/FMdHIbCPvwch7s8n+rm5VtlnUHrF/MbMtMXRNH8P0wuBQIwYY1Kr7k8sv8KEXchZ r1pts0gZ5xtJcQQjpMmTe/mBjiEtZkI9b05ftoIvuVtA/fL0KFyaHfa3Lqt5PeKYJ4aQ 6NbEFXfxX9dmQODQg7ztEHHY5KQdmoE0qKpq2UYg0cMB2pX8j4+csP84vLDW94jWNjpb F2IQ== X-Gm-Message-State: AFeK/H05bX2zaB3P4t2/HWWIYj+gwzXgyElN+22glVPGDfYNcxwe6a21rROmVSqt05dg4w== X-Received: by 10.28.0.136 with SMTP id 130mr14929919wma.126.1490709286843; Tue, 28 Mar 2017 06:54:46 -0700 (PDT) Received: from neptune.localdomain ([178.19.216.175]) by smtp.gmail.com with ESMTPSA id s17sm5025189wrc.25.2017.03.28.06.54.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Mar 2017 06:54:46 -0700 (PDT) From: Alban Crequy X-Google-Original-From: Alban Crequy To: Alban Crequy , Alexei Starovoitov , Jonathan Corbet , Steven Rostedt , Ingo Molnar Cc: Masami Hiramatsu , Arnaldo Carvalho de Melo , Omar Sandoval , linux-doc@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, iago@kinvolk.io, michael@kinvolk.io Subject: [PATCH v1] tracing/kprobes: expose maxactive for kretprobe in kprobe_events Date: Tue, 28 Mar 2017 15:52:22 +0200 Message-Id: <1490709142-8856-1-git-send-email-alban@kinvolk.io> X-Mailer: git-send-email 2.7.4 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When a kretprobe is installed on a kernel function, there is a maximum limit of how many calls in parallel it can catch (aka "maxactive"). A kernel module could call register_kretprobe() and initialize maxactive (see example in samples/kprobes/kretprobe_example.c). But that is not exposed to userspace and it is currently not possible to choose maxactive when writing to /sys/kernel/debug/tracing/kprobe_events The default maxactive can be as low as 1 on single-core with a non-preemptive kernel. This is too low and we need to increase it not only for recursive functions, but for functions that sleep or resched. This patch updates the format of the command that can be written to kprobe_events so that maxactive can be optionally specified. I need this for a bpf program attached to the kretprobe of inet_csk_accept, which can sleep for a long time. BugLink: https://github.com/iovisor/bcc/issues/1072 Signed-off-by: Alban Crequy --- Documentation/trace/kprobetrace.txt | 4 +++- kernel/trace/trace_kprobe.c | 34 +++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Documentation/trace/kprobetrace.txt b/Documentation/trace/kprobetrace.txt index 41ef9d8..655ca7e 100644 --- a/Documentation/trace/kprobetrace.txt +++ b/Documentation/trace/kprobetrace.txt @@ -23,7 +23,7 @@ current_tracer. Instead of that, add probe points via Synopsis of kprobe_events ------------------------- p[:[GRP/]EVENT] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS] : Set a probe - r[:[GRP/]EVENT] [MOD:]SYM[+0] [FETCHARGS] : Set a return probe + r[MAXACTIVE][:[GRP/]EVENT] [MOD:]SYM[+0] [FETCHARGS] : Set a return probe -:[GRP/]EVENT : Clear a probe GRP : Group name. If omitted, use "kprobes" for it. @@ -32,6 +32,8 @@ Synopsis of kprobe_events MOD : Module name which has given SYM. SYM[+offs] : Symbol+offset where the probe is inserted. MEMADDR : Address where the probe is inserted. + MAXACTIVE : Maximum number of instances of the specified function that + can be probed simultaneously, or 0 for the default.(*) FETCHARGS : Arguments. Each probe can have up to 128 args. %REG : Fetch register REG diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 5f688cc..807e01c 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -282,6 +282,7 @@ static struct trace_kprobe *alloc_trace_kprobe(const char *group, void *addr, const char *symbol, unsigned long offs, + int maxactive, int nargs, bool is_return) { struct trace_kprobe *tk; @@ -309,6 +310,8 @@ static struct trace_kprobe *alloc_trace_kprobe(const char *group, else tk->rp.kp.pre_handler = kprobe_dispatcher; + tk->rp.maxactive = maxactive; + if (!event || !is_good_name(event)) { ret = -EINVAL; goto error; @@ -598,8 +601,10 @@ static int create_trace_kprobe(int argc, char **argv) { /* * Argument syntax: - * - Add kprobe: p[:[GRP/]EVENT] [MOD:]KSYM[+OFFS]|KADDR [FETCHARGS] - * - Add kretprobe: r[:[GRP/]EVENT] [MOD:]KSYM[+0] [FETCHARGS] + * - Add kprobe: + * p[:[GRP/]EVENT] [MOD:]KSYM[+OFFS]|KADDR [FETCHARGS] + * - Add kretprobe: + * r[MAXACTIVE][:[GRP/]EVENT] [MOD:]KSYM[+0] [FETCHARGS] * Fetch args: * $retval : fetch return value * $stack : fetch stack address @@ -619,6 +624,7 @@ static int create_trace_kprobe(int argc, char **argv) int i, ret = 0; bool is_return = false, is_delete = false; char *symbol = NULL, *event = NULL, *group = NULL; + int maxactive = 0; char *arg; unsigned long offset = 0; void *addr = NULL; @@ -637,8 +643,26 @@ static int create_trace_kprobe(int argc, char **argv) return -EINVAL; } - if (argv[0][1] == ':') { + if (is_return && isdigit(argv[0][1]) && strchr(&argv[0][1], ':')) { + event = strchr(&argv[0][1], ':') + 1; + event[-1] = '\0'; + ret = kstrtouint(&argv[0][1], 0, &maxactive); + if (ret) { + pr_info("Failed to parse maxactive.\n"); + return ret; + } + /* kretprobes instances are iterated over via a list. The + * maximum should stay reasonable. + */ + if (maxactive > 1024) { + pr_info("Maxactive is too big.\n"); + return -EINVAL; + } + } else if (argv[0][1] == ':') { event = &argv[0][2]; + } + + if (event) { if (strchr(event, '/')) { group = event; event = strchr(group, '/') + 1; @@ -718,8 +742,8 @@ static int create_trace_kprobe(int argc, char **argv) is_return ? 'r' : 'p', addr); event = buf; } - tk = alloc_trace_kprobe(group, event, addr, symbol, offset, argc, - is_return); + tk = alloc_trace_kprobe(group, event, addr, symbol, offset, maxactive, + argc, is_return); if (IS_ERR(tk)) { pr_info("Failed to allocate trace_probe.(%d)\n", (int)PTR_ERR(tk));