From patchwork Wed Mar 10 10:41:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Elver X-Patchwork-Id: 12127669 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 18540C43331 for ; Wed, 10 Mar 2021 10:42:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EBB6A64F77 for ; Wed, 10 Mar 2021 10:42:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232503AbhCJKmX (ORCPT ); Wed, 10 Mar 2021 05:42:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38582 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232519AbhCJKly (ORCPT ); Wed, 10 Mar 2021 05:41:54 -0500 Received: from mail-wr1-x449.google.com (mail-wr1-x449.google.com [IPv6:2a00:1450:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 62FC2C061761 for ; Wed, 10 Mar 2021 02:41:54 -0800 (PST) Received: by mail-wr1-x449.google.com with SMTP id m9so7804386wrx.6 for ; Wed, 10 Mar 2021 02:41:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=JNI5Tf6KKGhkGniIZ5cU47CifTg2LZA5JMDRp5Vdgq4=; b=U/F3Fdi9Xrysxyu01Jy30XoAyPRhEX+3vDUdNMjOm7dIVG2DHhU72lAaBvBhkE9yrZ VOzKe1ZEpDfNb0hR2ksuCFVTja5hCLZwcroB+PK+N9hpkimZmjslooPo8ld4Vy+LeA2/ MG5/roSaELFmoquzWZ6cncBEyZB1umoe3wZFz/ICpoU64POFS8ItvjAbsdz2BhkX+wJh 2bYkH25XVcT4JN0n+OCchUTgbtTWRGYcpOq6MhQsetfP96kLkFgBOGcLHDCU5OqrHUIa uLA0gRr/TvN8q/75dy+Tkx0sVvG+663GP/UZvoIU6NWI7p3sWN3RDIjwyspDDvAm05QI AuQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=JNI5Tf6KKGhkGniIZ5cU47CifTg2LZA5JMDRp5Vdgq4=; b=dkvJLV8eN9yI8mBfdul5MpjDZFfzdT4b5epb+3CxIY8BFadkwVqhC3miRtl0T9UEfJ C8kQSAPaCMYAraaIZBgKhVFclkTTWq9v1Ugq65wPCpBLUymgWY1YG86YDJPUnEvZxnNQ KQ/EOH1yPMrTIgJYygvvWt4ej+iz9TYe5hMsQHOzAH8Sf+RZP4qdzKYfcZE4FJA12NxZ b90eb6kWM0r6S8pfPCSWeS7uLUChMJixyW/FraZK4VwUhKIM2W1SvllKFoVwbRFffhgf 275ybdjODoAL4I/OT79wxFWwDE15kRBIrg9YluHnB4xQTs5YeDKzP0UrfZrkAKG0rmeH q32w== X-Gm-Message-State: AOAM5311z/G+8DLJNip+cdE3nLxSo0RI9nwX3SAOllbp5MDtakYNxw5n T0YbHWxJrh3WSbNGei5nwJKvG7J6SA== X-Google-Smtp-Source: ABdhPJxh8boYmWup7xVABan/lqZvFVU3ZuX3Cf8erA2PUSW5aM45Fv/PW2DBnvnPpCf+kQnMcOhuRT0joA== X-Received: from elver.muc.corp.google.com ([2a00:79e0:15:13:e995:ac0b:b57c:49a4]) (user=elver job=sendgmr) by 2002:a05:600c:608:: with SMTP id o8mr2806133wmm.42.1615372913037; Wed, 10 Mar 2021 02:41:53 -0800 (PST) Date: Wed, 10 Mar 2021 11:41:32 +0100 In-Reply-To: <20210310104139.679618-1-elver@google.com> Message-Id: <20210310104139.679618-2-elver@google.com> Mime-Version: 1.0 References: <20210310104139.679618-1-elver@google.com> X-Mailer: git-send-email 2.30.1.766.gb4fecdf3b7-goog Subject: [PATCH RFC v2 1/8] perf/core: Apply PERF_EVENT_IOC_MODIFY_ATTRIBUTES to children From: Marco Elver To: elver@google.com, peterz@infradead.org, alexander.shishkin@linux.intel.com, acme@kernel.org, mingo@redhat.com, jolsa@redhat.com, mark.rutland@arm.com, namhyung@kernel.org, tglx@linutronix.de Cc: glider@google.com, viro@zeniv.linux.org.uk, arnd@arndb.de, christian@brauner.io, dvyukov@google.com, jannh@google.com, axboe@kernel.dk, mascasa@google.com, pcc@google.com, irogers@google.com, kasan-dev@googlegroups.com, linux-arch@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, x86@kernel.org, linux-kselftest@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org As with other ioctls (such as PERF_EVENT_IOC_{ENABLE,DISABLE}), fix up handling of PERF_EVENT_IOC_MODIFY_ATTRIBUTES to also apply to children. Link: https://lkml.kernel.org/r/YBqVaY8aTMYtoUnX@hirez.programming.kicks-ass.net Suggested-by: Dmitry Vyukov Reviewed-by: Dmitry Vyukov Signed-off-by: Marco Elver --- kernel/events/core.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 0aeca5f3c0ac..bff498766065 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3179,16 +3179,36 @@ static int perf_event_modify_breakpoint(struct perf_event *bp, static int perf_event_modify_attr(struct perf_event *event, struct perf_event_attr *attr) { + int (*func)(struct perf_event *, struct perf_event_attr *); + struct perf_event *child; + int err; + if (event->attr.type != attr->type) return -EINVAL; switch (event->attr.type) { case PERF_TYPE_BREAKPOINT: - return perf_event_modify_breakpoint(event, attr); + func = perf_event_modify_breakpoint; + break; default: /* Place holder for future additions. */ return -EOPNOTSUPP; } + + WARN_ON_ONCE(event->ctx->parent_ctx); + + mutex_lock(&event->child_mutex); + err = func(event, attr); + if (err) + goto out; + list_for_each_entry(child, &event->child_list, child_list) { + err = func(child, attr); + if (err) + goto out; + } +out: + mutex_unlock(&event->child_mutex); + return err; } static void ctx_sched_out(struct perf_event_context *ctx, From patchwork Wed Mar 10 10:41:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Elver X-Patchwork-Id: 12127667 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 953F5C43381 for ; Wed, 10 Mar 2021 10:42:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 51A2B64FF4 for ; Wed, 10 Mar 2021 10:42:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231897AbhCJKmY (ORCPT ); Wed, 10 Mar 2021 05:42:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38598 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232537AbhCJKl4 (ORCPT ); Wed, 10 Mar 2021 05:41:56 -0500 Received: from mail-qt1-x84a.google.com (mail-qt1-x84a.google.com [IPv6:2607:f8b0:4864:20::84a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27A73C061761 for ; Wed, 10 Mar 2021 02:41:56 -0800 (PST) Received: by mail-qt1-x84a.google.com with SMTP id 16so12634346qtw.1 for ; Wed, 10 Mar 2021 02:41:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=LX0emKbgsHYtGpYyL1x1FnLQ5ewlS0gEm+vlZ3nascQ=; b=N/u3p5qkgkVCIorblwjlo0ALkDKW6OemYeWX+fR+AT8w6i0Gh/XvradEyaRC0Nmutk j3AGpbLlTACkVr5oi/De9Cf9L/VxHIbruSwuU7HfD6sKWBig/HP45lCrnKDX1aRSOhp6 ZgdsDxtOtDhrvcdiYBVzGE0Yz/2W3v0FmAEpbD1N+n6ggnT8qnl47gG7JmqqPv3PrAko qGwATz9jmqBUcMVHnIzIDgnkvckIW8Sp98YOu5u5o5EwKc4jVHB3aVNz+K9uwfv9Y1rQ WjLGhhIrjQcVepjxDJ+LjtV/n+fiN6L3yTzeRv74Ev9+ZDMb8KBoXkY739owMIXjSb+n Ursw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=LX0emKbgsHYtGpYyL1x1FnLQ5ewlS0gEm+vlZ3nascQ=; b=E4Fg7eVwOeDHtTIzx3d97VqAMx8avXBVAfa04gG/1OED7ez/fQ+3mAD+Tno/YV/VcO de3AqlkJjczO00dCurssjXh+MuH+i+glyWBgJmS00nDwo4bRV73z3C+NFfvDUX+cFAxY s3OLHZdFVlXu5wiR0DkVlO5FYbJqwInu/26mVxxpzuGouIA7QXtOSOTjRwKX3S3dXBzK jgv8w11lOf+uw3jyoLByLS5IKd8UB5cSxIF+ZUGPtf9UGv+/xwMkWV8kNRSKIdI1Xia0 jTZhw513KKVpd7a41iZ3twylAT5uow1Lai+Ie1E6QRXn0ggbuX4XIeAZ59XUVoku4Pms /wgQ== X-Gm-Message-State: AOAM53157I3l3oayEeIWPUks/qx8s1RxKYLY0827+2gtfQeh3KC/gJTR dq+Uc94kMCZYbN66MustIzQclEprUg== X-Google-Smtp-Source: ABdhPJymJDYxCT4IzRtfNhWaSFV/kqnhDLbM/p7NNyqwqrXyZsRP8XQdyy5hJ1tEInGdDs/E4CUY8BMuEw== X-Received: from elver.muc.corp.google.com ([2a00:79e0:15:13:e995:ac0b:b57c:49a4]) (user=elver job=sendgmr) by 2002:ad4:4d82:: with SMTP id cv2mr2356657qvb.6.1615372915311; Wed, 10 Mar 2021 02:41:55 -0800 (PST) Date: Wed, 10 Mar 2021 11:41:33 +0100 In-Reply-To: <20210310104139.679618-1-elver@google.com> Message-Id: <20210310104139.679618-3-elver@google.com> Mime-Version: 1.0 References: <20210310104139.679618-1-elver@google.com> X-Mailer: git-send-email 2.30.1.766.gb4fecdf3b7-goog Subject: [PATCH RFC v2 2/8] perf/core: Support only inheriting events if cloned with CLONE_THREAD From: Marco Elver To: elver@google.com, peterz@infradead.org, alexander.shishkin@linux.intel.com, acme@kernel.org, mingo@redhat.com, jolsa@redhat.com, mark.rutland@arm.com, namhyung@kernel.org, tglx@linutronix.de Cc: glider@google.com, viro@zeniv.linux.org.uk, arnd@arndb.de, christian@brauner.io, dvyukov@google.com, jannh@google.com, axboe@kernel.dk, mascasa@google.com, pcc@google.com, irogers@google.com, kasan-dev@googlegroups.com, linux-arch@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, x86@kernel.org, linux-kselftest@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Adds bit perf_event_attr::inherit_thread, to restricting inheriting events only if the child was cloned with CLONE_THREAD. This option supports the case where an event is supposed to be process-wide only (including subthreads), but should not propagate beyond the current process's shared environment. Link: https://lore.kernel.org/lkml/YBvj6eJR%2FDY2TsEB@hirez.programming.kicks-ass.net/ Suggested-by: Peter Zijlstra Signed-off-by: Marco Elver --- v2: * Add patch to series. --- include/linux/perf_event.h | 5 +++-- include/uapi/linux/perf_event.h | 3 ++- kernel/events/core.c | 21 ++++++++++++++------- kernel/fork.c | 2 +- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index fab42cfbd350..982ad61c653a 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -955,7 +955,7 @@ extern void __perf_event_task_sched_in(struct task_struct *prev, struct task_struct *task); extern void __perf_event_task_sched_out(struct task_struct *prev, struct task_struct *next); -extern int perf_event_init_task(struct task_struct *child); +extern int perf_event_init_task(struct task_struct *child, u64 clone_flags); extern void perf_event_exit_task(struct task_struct *child); extern void perf_event_free_task(struct task_struct *task); extern void perf_event_delayed_put(struct task_struct *task); @@ -1446,7 +1446,8 @@ perf_event_task_sched_in(struct task_struct *prev, static inline void perf_event_task_sched_out(struct task_struct *prev, struct task_struct *next) { } -static inline int perf_event_init_task(struct task_struct *child) { return 0; } +static inline int perf_event_init_task(struct task_struct *child, + u64 clone_flags) { return 0; } static inline void perf_event_exit_task(struct task_struct *child) { } static inline void perf_event_free_task(struct task_struct *task) { } static inline void perf_event_delayed_put(struct task_struct *task) { } diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index ad15e40d7f5d..813efb65fea8 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -389,7 +389,8 @@ struct perf_event_attr { cgroup : 1, /* include cgroup events */ text_poke : 1, /* include text poke events */ build_id : 1, /* use build id in mmap2 events */ - __reserved_1 : 29; + inherit_thread : 1, /* children only inherit if cloned with CLONE_THREAD */ + __reserved_1 : 28; union { __u32 wakeup_events; /* wakeup every n events */ diff --git a/kernel/events/core.c b/kernel/events/core.c index bff498766065..a8382e6c907c 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -11597,6 +11597,9 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, (attr->sample_type & PERF_SAMPLE_WEIGHT_STRUCT)) return -EINVAL; + if (!attr->inherit && attr->inherit_thread) + return -EINVAL; + out: return ret; @@ -12820,12 +12823,13 @@ static int inherit_task_group(struct perf_event *event, struct task_struct *parent, struct perf_event_context *parent_ctx, struct task_struct *child, int ctxn, - int *inherited_all) + u64 clone_flags, int *inherited_all) { int ret; struct perf_event_context *child_ctx; - if (!event->attr.inherit) { + if (!event->attr.inherit || + (event->attr.inherit_thread && !(clone_flags & CLONE_THREAD))) { *inherited_all = 0; return 0; } @@ -12857,7 +12861,8 @@ inherit_task_group(struct perf_event *event, struct task_struct *parent, /* * Initialize the perf_event context in task_struct */ -static int perf_event_init_context(struct task_struct *child, int ctxn) +static int perf_event_init_context(struct task_struct *child, int ctxn, + u64 clone_flags) { struct perf_event_context *child_ctx, *parent_ctx; struct perf_event_context *cloned_ctx; @@ -12897,7 +12902,8 @@ static int perf_event_init_context(struct task_struct *child, int ctxn) */ perf_event_groups_for_each(event, &parent_ctx->pinned_groups) { ret = inherit_task_group(event, parent, parent_ctx, - child, ctxn, &inherited_all); + child, ctxn, clone_flags, + &inherited_all); if (ret) goto out_unlock; } @@ -12913,7 +12919,8 @@ static int perf_event_init_context(struct task_struct *child, int ctxn) perf_event_groups_for_each(event, &parent_ctx->flexible_groups) { ret = inherit_task_group(event, parent, parent_ctx, - child, ctxn, &inherited_all); + child, ctxn, clone_flags, + &inherited_all); if (ret) goto out_unlock; } @@ -12955,7 +12962,7 @@ static int perf_event_init_context(struct task_struct *child, int ctxn) /* * Initialize the perf_event context in task_struct */ -int perf_event_init_task(struct task_struct *child) +int perf_event_init_task(struct task_struct *child, u64 clone_flags) { int ctxn, ret; @@ -12964,7 +12971,7 @@ int perf_event_init_task(struct task_struct *child) INIT_LIST_HEAD(&child->perf_event_list); for_each_task_context_nr(ctxn) { - ret = perf_event_init_context(child, ctxn); + ret = perf_event_init_context(child, ctxn, clone_flags); if (ret) { perf_event_free_task(child); return ret; diff --git a/kernel/fork.c b/kernel/fork.c index d3171e8e88e5..d090366d1206 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -2070,7 +2070,7 @@ static __latent_entropy struct task_struct *copy_process( if (retval) goto bad_fork_cleanup_policy; - retval = perf_event_init_task(p); + retval = perf_event_init_task(p, clone_flags); if (retval) goto bad_fork_cleanup_policy; retval = audit_alloc(p); From patchwork Wed Mar 10 10:41:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Elver X-Patchwork-Id: 12127671 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE0E5C4321A for ; Wed, 10 Mar 2021 10:42:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9000B64FE1 for ; Wed, 10 Mar 2021 10:42:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232582AbhCJKmY (ORCPT ); Wed, 10 Mar 2021 05:42:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38612 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232552AbhCJKl6 (ORCPT ); Wed, 10 Mar 2021 05:41:58 -0500 Received: from mail-qk1-x749.google.com (mail-qk1-x749.google.com [IPv6:2607:f8b0:4864:20::749]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4D5EFC061761 for ; Wed, 10 Mar 2021 02:41:58 -0800 (PST) Received: by mail-qk1-x749.google.com with SMTP id h134so12441194qke.1 for ; Wed, 10 Mar 2021 02:41:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=dOVfTFewU2OVBxfkqxI1NPon3rxqJk0MP/D8NHNSqQA=; b=q1jQ16YbsnqIDBn5nBGRtDoStGi+RN0sGNM2jXfR0WlnzZ0m1QJ+LuURos4FjT52Oj j5GJfLS9NZbPypEgX45w2ZaWBBIqOUxMg4w/QA7kuYIyM6DGtddI7j14cXsB1uOKooJR xlLaN3QhYFUnc8tqDxrGszVCHf4LntSANKCervuZRhsRtUNTLSQ1BRUG2wOJXiyZRqNT jZYMfmSKEODrH/cBBMftUMy1ScyCkdUUwpGw2QU3syBSWkCd+bFPsH53rNOacPywjo72 Azvh9Fk7EBMxvXkTblPINbobb5NEaGoZTrRk4PK32kIHSJtJgoINr+KfcHX+qfPyXaU5 6Vdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=dOVfTFewU2OVBxfkqxI1NPon3rxqJk0MP/D8NHNSqQA=; b=jTteWamHzsSJd51njOOW7BB+PBMUG2pFEEGeUM6U3nQ6MrfvKGuHwajolcG2V+c/KJ GJtZD6YbHGYCNVqisrDubBIBe5MjCGgcCW8O/jrEfwzhT6XwB+Pa4M8xDIa3zy4fssqV MREqd5ZLsUfoEiRnO2x4EV8oraEVaFTwukSmckazkYf5D/wHOv4CEjlPXMO7AMiD6+SY Kcp5o6WtjnGwfBlWjIsthccC6/3sfipqBVtD+qVEy3dupY8BuUcaP4bPcT4m9wJAbwEn yi1MzfRgssyxuuAIzU2+hVBNSY0THyGM7CAcmhFPG26bZ/O9yfdpBG4wnv7LJK7SaXhP gEwg== X-Gm-Message-State: AOAM53288dGTBDOl5xtfmEEgR7GRJA8vMGC3QofY/xqt1ezQKf0fPam5 MhqJUzSZ+Lfx6dKWU3lFYUUPqCQmDQ== X-Google-Smtp-Source: ABdhPJw2duZKZHANH9M/H/FlahCExA+5z683QS7WBEwd4bOLuqI3t5lqneYmFDDGv4KnW0XshRNEvwlpQg== X-Received: from elver.muc.corp.google.com ([2a00:79e0:15:13:e995:ac0b:b57c:49a4]) (user=elver job=sendgmr) by 2002:ad4:4991:: with SMTP id t17mr2036844qvx.33.1615372917507; Wed, 10 Mar 2021 02:41:57 -0800 (PST) Date: Wed, 10 Mar 2021 11:41:34 +0100 In-Reply-To: <20210310104139.679618-1-elver@google.com> Message-Id: <20210310104139.679618-4-elver@google.com> Mime-Version: 1.0 References: <20210310104139.679618-1-elver@google.com> X-Mailer: git-send-email 2.30.1.766.gb4fecdf3b7-goog Subject: [PATCH RFC v2 3/8] perf/core: Add support for event removal on exec From: Marco Elver To: elver@google.com, peterz@infradead.org, alexander.shishkin@linux.intel.com, acme@kernel.org, mingo@redhat.com, jolsa@redhat.com, mark.rutland@arm.com, namhyung@kernel.org, tglx@linutronix.de Cc: glider@google.com, viro@zeniv.linux.org.uk, arnd@arndb.de, christian@brauner.io, dvyukov@google.com, jannh@google.com, axboe@kernel.dk, mascasa@google.com, pcc@google.com, irogers@google.com, kasan-dev@googlegroups.com, linux-arch@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, x86@kernel.org, linux-kselftest@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Adds bit perf_event_attr::remove_on_exec, to support removing an event from a task on exec. This option supports the case where an event is supposed to be process-wide only, and should not propagate beyond exec, to limit monitoring to the original process image only. Signed-off-by: Marco Elver --- v2: * Add patch to series. --- include/uapi/linux/perf_event.h | 3 ++- kernel/events/core.c | 45 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index 813efb65fea8..8c5b9f5ad63f 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -390,7 +390,8 @@ struct perf_event_attr { text_poke : 1, /* include text poke events */ build_id : 1, /* use build id in mmap2 events */ inherit_thread : 1, /* children only inherit if cloned with CLONE_THREAD */ - __reserved_1 : 28; + remove_on_exec : 1, /* event is removed from task on exec */ + __reserved_1 : 27; union { __u32 wakeup_events; /* wakeup every n events */ diff --git a/kernel/events/core.c b/kernel/events/core.c index a8382e6c907c..bc9e6e35e414 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -4195,6 +4195,46 @@ static void perf_event_enable_on_exec(int ctxn) put_ctx(clone_ctx); } +static void perf_remove_from_owner(struct perf_event *event); +static void perf_event_exit_event(struct perf_event *child_event, + struct perf_event_context *child_ctx, + struct task_struct *child); + +/* + * Removes all events from the current task that have been marked + * remove-on-exec, and feeds their values back to parent events. + */ +static void perf_event_remove_on_exec(void) +{ + int ctxn; + + for_each_task_context_nr(ctxn) { + struct perf_event_context *ctx; + struct perf_event *event, *next; + + ctx = perf_pin_task_context(current, ctxn); + if (!ctx) + continue; + mutex_lock(&ctx->mutex); + + list_for_each_entry_safe(event, next, &ctx->event_list, event_entry) { + if (!event->attr.remove_on_exec) + continue; + + if (!is_kernel_event(event)) + perf_remove_from_owner(event); + perf_remove_from_context(event, DETACH_GROUP); + /* + * Remove the event and feed back its values to the + * parent event. + */ + perf_event_exit_event(event, ctx, current); + } + mutex_unlock(&ctx->mutex); + put_ctx(ctx); + } +} + struct perf_read_data { struct perf_event *event; bool group; @@ -7519,6 +7559,8 @@ void perf_event_exec(void) true); } rcu_read_unlock(); + + perf_event_remove_on_exec(); } struct remote_output { @@ -11600,6 +11642,9 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, if (!attr->inherit && attr->inherit_thread) return -EINVAL; + if (attr->remove_on_exec && attr->enable_on_exec) + return -EINVAL; + out: return ret; From patchwork Wed Mar 10 10:41:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Elver X-Patchwork-Id: 12127677 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E563BC43603 for ; Wed, 10 Mar 2021 10:42:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C81CE64FE1 for ; Wed, 10 Mar 2021 10:42:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232635AbhCJKm0 (ORCPT ); Wed, 10 Mar 2021 05:42:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38624 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232562AbhCJKmA (ORCPT ); Wed, 10 Mar 2021 05:42:00 -0500 Received: from mail-qt1-x84a.google.com (mail-qt1-x84a.google.com [IPv6:2607:f8b0:4864:20::84a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A546C06174A for ; Wed, 10 Mar 2021 02:42:00 -0800 (PST) Received: by mail-qt1-x84a.google.com with SMTP id o20so12562583qtx.22 for ; Wed, 10 Mar 2021 02:42:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=TJtkCAibz7hjjm1jVaTeeVhou55l9X9TvLV9OEul/NU=; b=Hl7F9vqabKzO1JpvAJxKoO0eKsrcLd75bjR7n6OK04UutFIdlrWoJNDywWph1TWQ9D 4/XH75IwjJvZxDCijI5dDOYaHqJIQi6lmFdqRoOrsyHhMTc4m4QCCGkjR1Io97dEiTi8 OndOpPezWItJNWZKuE4FAhaCbFHMaC/xf6u5n6ZU983LFxhVxApCxqRQTCMVHdBd1FOo Fxu/tnl802jTGtCqjapJ6XWBZMI+o0UT51ptRD3EqxNdfzm+UqZnwY9BLPhexchPimEs 23R4vDm+jHihsSKDuv1AkURDbZ0zj9t5EYhEijQyTyf5GJhZlj0mAsokco+r7kvN9UiE SthQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=TJtkCAibz7hjjm1jVaTeeVhou55l9X9TvLV9OEul/NU=; b=A2nXymGZK0Rf519/D6rERFSqpr/diIWTa2zjxvSydX3628rVC3uAkHc0sABwW2irx4 rxOKniL78XW+OzH7PBqK9DuvJc+T9OtF3Bd6x52Xs9HS0ZOgwl9YHqm2uhZhmcKoYVKa X5jbU5eQyO7HY6JmIM9tbK53md+Fv03w47l32WukzQNP/hUpZELJERBPwhmKXZFxZ5oc HgumcsERI4r1P27RYwigZKL9zBmPmiXaQIFQ1qPWPJbMghwZSfWa/eC6oLtLcBv/By/L v10dzkQYjydeF1SOM1WBbFtg07tWrsPS++b13QGWrtAnd0/GeSlhhj7A9FvykKUSHmUj +T8w== X-Gm-Message-State: AOAM533Weu3QTgJ9XjXvHIfhjtUc1DOfas/QqGIgnvBuInRSK3rPc4GJ NtX1yTRXA+sN/AXHyJKmC+Z+f3dexw== X-Google-Smtp-Source: ABdhPJw0lHjg5zwIAtMr6GblQojvjUWlevPqNsc+waoiHuzSZKERaPy1g/Wnbrm4g69+1jZNoe5plHpeKg== X-Received: from elver.muc.corp.google.com ([2a00:79e0:15:13:e995:ac0b:b57c:49a4]) (user=elver job=sendgmr) by 2002:a05:6214:90b:: with SMTP id dj11mr2130953qvb.52.1615372919806; Wed, 10 Mar 2021 02:41:59 -0800 (PST) Date: Wed, 10 Mar 2021 11:41:35 +0100 In-Reply-To: <20210310104139.679618-1-elver@google.com> Message-Id: <20210310104139.679618-5-elver@google.com> Mime-Version: 1.0 References: <20210310104139.679618-1-elver@google.com> X-Mailer: git-send-email 2.30.1.766.gb4fecdf3b7-goog Subject: [PATCH RFC v2 4/8] signal: Introduce TRAP_PERF si_code and si_perf to siginfo From: Marco Elver To: elver@google.com, peterz@infradead.org, alexander.shishkin@linux.intel.com, acme@kernel.org, mingo@redhat.com, jolsa@redhat.com, mark.rutland@arm.com, namhyung@kernel.org, tglx@linutronix.de Cc: glider@google.com, viro@zeniv.linux.org.uk, arnd@arndb.de, christian@brauner.io, dvyukov@google.com, jannh@google.com, axboe@kernel.dk, mascasa@google.com, pcc@google.com, irogers@google.com, kasan-dev@googlegroups.com, linux-arch@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, x86@kernel.org, linux-kselftest@vger.kernel.org, Geert Uytterhoeven Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Introduces the TRAP_PERF si_code, and associated siginfo_t field si_perf. These will be used by the perf event subsystem to send signals (if requested) to the task where an event occurred. Acked-by: Geert Uytterhoeven # m68k Acked-by: Arnd Bergmann # asm-generic Signed-off-by: Marco Elver --- arch/m68k/kernel/signal.c | 3 +++ arch/x86/kernel/signal_compat.c | 5 ++++- fs/signalfd.c | 4 ++++ include/linux/compat.h | 2 ++ include/linux/signal.h | 1 + include/uapi/asm-generic/siginfo.h | 6 +++++- include/uapi/linux/signalfd.h | 4 +++- kernel/signal.c | 11 +++++++++++ 8 files changed, 33 insertions(+), 3 deletions(-) diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index 349570f16a78..a4b7ee1df211 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -622,6 +622,9 @@ static inline void siginfo_build_tests(void) /* _sigfault._addr_pkey */ BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x12); + /* _sigfault._perf */ + BUILD_BUG_ON(offsetof(siginfo_t, si_perf) != 0x10); + /* _sigpoll */ BUILD_BUG_ON(offsetof(siginfo_t, si_band) != 0x0c); BUILD_BUG_ON(offsetof(siginfo_t, si_fd) != 0x10); diff --git a/arch/x86/kernel/signal_compat.c b/arch/x86/kernel/signal_compat.c index a5330ff498f0..0e5d0a7e203b 100644 --- a/arch/x86/kernel/signal_compat.c +++ b/arch/x86/kernel/signal_compat.c @@ -29,7 +29,7 @@ static inline void signal_compat_build_tests(void) BUILD_BUG_ON(NSIGFPE != 15); BUILD_BUG_ON(NSIGSEGV != 9); BUILD_BUG_ON(NSIGBUS != 5); - BUILD_BUG_ON(NSIGTRAP != 5); + BUILD_BUG_ON(NSIGTRAP != 6); BUILD_BUG_ON(NSIGCHLD != 6); BUILD_BUG_ON(NSIGSYS != 2); @@ -138,6 +138,9 @@ static inline void signal_compat_build_tests(void) BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x20); BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14); + BUILD_BUG_ON(offsetof(siginfo_t, si_perf) != 0x18); + BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf) != 0x10); + CHECK_CSI_OFFSET(_sigpoll); CHECK_CSI_SIZE (_sigpoll, 2*sizeof(int)); CHECK_SI_SIZE (_sigpoll, 4*sizeof(int)); diff --git a/fs/signalfd.c b/fs/signalfd.c index 456046e15873..040a1142915f 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c @@ -134,6 +134,10 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo, #endif new.ssi_addr_lsb = (short) kinfo->si_addr_lsb; break; + case SIL_PERF_EVENT: + new.ssi_addr = (long) kinfo->si_addr; + new.ssi_perf = kinfo->si_perf; + break; case SIL_CHLD: new.ssi_pid = kinfo->si_pid; new.ssi_uid = kinfo->si_uid; diff --git a/include/linux/compat.h b/include/linux/compat.h index 6e65be753603..c8821d966812 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -236,6 +236,8 @@ typedef struct compat_siginfo { char _dummy_pkey[__COMPAT_ADDR_BND_PKEY_PAD]; u32 _pkey; } _addr_pkey; + /* used when si_code=TRAP_PERF */ + compat_u64 _perf; }; } _sigfault; diff --git a/include/linux/signal.h b/include/linux/signal.h index 205526c4003a..1e98548d7cf6 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -43,6 +43,7 @@ enum siginfo_layout { SIL_FAULT_MCEERR, SIL_FAULT_BNDERR, SIL_FAULT_PKUERR, + SIL_PERF_EVENT, SIL_CHLD, SIL_RT, SIL_SYS, diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h index d2597000407a..d0bb9125c853 100644 --- a/include/uapi/asm-generic/siginfo.h +++ b/include/uapi/asm-generic/siginfo.h @@ -91,6 +91,8 @@ union __sifields { char _dummy_pkey[__ADDR_BND_PKEY_PAD]; __u32 _pkey; } _addr_pkey; + /* used when si_code=TRAP_PERF */ + __u64 _perf; }; } _sigfault; @@ -155,6 +157,7 @@ typedef struct siginfo { #define si_lower _sifields._sigfault._addr_bnd._lower #define si_upper _sifields._sigfault._addr_bnd._upper #define si_pkey _sifields._sigfault._addr_pkey._pkey +#define si_perf _sifields._sigfault._perf #define si_band _sifields._sigpoll._band #define si_fd _sifields._sigpoll._fd #define si_call_addr _sifields._sigsys._call_addr @@ -253,7 +256,8 @@ typedef struct siginfo { #define TRAP_BRANCH 3 /* process taken branch trap */ #define TRAP_HWBKPT 4 /* hardware breakpoint/watchpoint */ #define TRAP_UNK 5 /* undiagnosed trap */ -#define NSIGTRAP 5 +#define TRAP_PERF 6 /* perf event with sigtrap=1 */ +#define NSIGTRAP 6 /* * There is an additional set of SIGTRAP si_codes used by ptrace diff --git a/include/uapi/linux/signalfd.h b/include/uapi/linux/signalfd.h index 83429a05b698..7e333042c7e3 100644 --- a/include/uapi/linux/signalfd.h +++ b/include/uapi/linux/signalfd.h @@ -39,6 +39,8 @@ struct signalfd_siginfo { __s32 ssi_syscall; __u64 ssi_call_addr; __u32 ssi_arch; + __u32 __pad3; + __u64 ssi_perf; /* * Pad strcture to 128 bytes. Remember to update the @@ -49,7 +51,7 @@ struct signalfd_siginfo { * comes out of a read(2) and we really don't want to have * a compat on read(2). */ - __u8 __pad[28]; + __u8 __pad[16]; }; diff --git a/kernel/signal.c b/kernel/signal.c index ba4d1ef39a9e..f68351825e5e 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1199,6 +1199,7 @@ static inline bool has_si_pid_and_uid(struct kernel_siginfo *info) case SIL_FAULT_MCEERR: case SIL_FAULT_BNDERR: case SIL_FAULT_PKUERR: + case SIL_PERF_EVENT: case SIL_SYS: ret = false; break; @@ -2531,6 +2532,7 @@ static void hide_si_addr_tag_bits(struct ksignal *ksig) case SIL_FAULT_MCEERR: case SIL_FAULT_BNDERR: case SIL_FAULT_PKUERR: + case SIL_PERF_EVENT: ksig->info.si_addr = arch_untagged_si_addr( ksig->info.si_addr, ksig->sig, ksig->info.si_code); break; @@ -3333,6 +3335,10 @@ void copy_siginfo_to_external32(struct compat_siginfo *to, #endif to->si_pkey = from->si_pkey; break; + case SIL_PERF_EVENT: + to->si_addr = ptr_to_compat(from->si_addr); + to->si_perf = from->si_perf; + break; case SIL_CHLD: to->si_pid = from->si_pid; to->si_uid = from->si_uid; @@ -3413,6 +3419,10 @@ static int post_copy_siginfo_from_user32(kernel_siginfo_t *to, #endif to->si_pkey = from->si_pkey; break; + case SIL_PERF_EVENT: + to->si_addr = compat_ptr(from->si_addr); + to->si_perf = from->si_perf; + break; case SIL_CHLD: to->si_pid = from->si_pid; to->si_uid = from->si_uid; @@ -4593,6 +4603,7 @@ static inline void siginfo_buildtime_checks(void) CHECK_OFFSET(si_lower); CHECK_OFFSET(si_upper); CHECK_OFFSET(si_pkey); + CHECK_OFFSET(si_perf); /* sigpoll */ CHECK_OFFSET(si_band); From patchwork Wed Mar 10 10:41:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Elver X-Patchwork-Id: 12127675 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7FD4C433E9 for ; Wed, 10 Mar 2021 10:42:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 975F065051 for ; Wed, 10 Mar 2021 10:42:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232562AbhCJKm1 (ORCPT ); Wed, 10 Mar 2021 05:42:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38640 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232588AbhCJKmD (ORCPT ); Wed, 10 Mar 2021 05:42:03 -0500 Received: from mail-qk1-x74a.google.com (mail-qk1-x74a.google.com [IPv6:2607:f8b0:4864:20::74a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16DC3C061760 for ; Wed, 10 Mar 2021 02:42:03 -0800 (PST) Received: by mail-qk1-x74a.google.com with SMTP id h20so12410620qkj.18 for ; Wed, 10 Mar 2021 02:42:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=MwMG/Kl+Surl9jPDmtCK7rCt1fJ8HAEyxyLN1urbLCM=; b=mybq0plUmvYmI72EWYXiOTM/z+pmWe/T7eOI5ncxtQXULTQ/eIjS4yMr79NE5RLEoU BDqnmznSj/VfvFVMtKJs+1SSQpY6JPOBG8JS/bqL3OIMjVNE7suld3CaDuKskjM3ApjZ X/jhXLzlo3vYCNwFPkuw+B1u+9AEXl6/D8GVFvcQFq9cnr4jHSERZVbrx0o8m3MSbrMv SAOpqnUmeubvpYOTtcHrw1ynnvMgBNxZZgPJ7zlnpWr22vnRA6qMfuK6pPsMqZS/7Irn 497QpzekPMKfCwIG3l0DRSnRgxzQZRGF61/4ocpwSx3ZJU+Q0fepqNepcHpltjfNvb+b Ds7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=MwMG/Kl+Surl9jPDmtCK7rCt1fJ8HAEyxyLN1urbLCM=; b=JeNv2h/KHl9UkPz9Dk41lcuv2del4pGX4UOqRGDoOlxlVp9LYGb1j3bJdtFrnbnMz6 F2PTIQWn+iyZTgp+PeesTVK6OHrN/NFama1IJQ0Lb871CKo1+RMcAo0tDCrZyc1rFemJ W4VgwADQAnV1zzz0jCHAQ0IfRXDZ599DqzcWEXW/HF5PKA/N2SZJx0pYwRtm7eicd5j4 YuGmCU7LaKfG03b/I4ftHti8LsO+Dg1Z/PiVnma3ACgBSbxOtKZPlnIjflITRd5mr1Lk 9yKFTbSDqS23iMJmDyEyyxRVQQ8hreQ1bErzbNPA761wbZJuG5Rvv6+knfQhP2tg6c9M Wu6w== X-Gm-Message-State: AOAM533INDKdFcGVsQG0KrRaaT9tAGQB9UAXJ04gtawWuhiXBqhPhRfC G9utij0o15MQ9GsT+CtorsEIqYH7yg== X-Google-Smtp-Source: ABdhPJyh6J1KNJC8N7PIOcGv/D8kM2z9fZ1+ioUy4PGqKbYgUIWbpbWVJTzSZv3In2DrIJwc9zqYibtbPw== X-Received: from elver.muc.corp.google.com ([2a00:79e0:15:13:e995:ac0b:b57c:49a4]) (user=elver job=sendgmr) by 2002:ad4:5a14:: with SMTP id ei20mr2068906qvb.1.1615372922271; Wed, 10 Mar 2021 02:42:02 -0800 (PST) Date: Wed, 10 Mar 2021 11:41:36 +0100 In-Reply-To: <20210310104139.679618-1-elver@google.com> Message-Id: <20210310104139.679618-6-elver@google.com> Mime-Version: 1.0 References: <20210310104139.679618-1-elver@google.com> X-Mailer: git-send-email 2.30.1.766.gb4fecdf3b7-goog Subject: [PATCH RFC v2 5/8] perf/core: Add support for SIGTRAP on perf events From: Marco Elver To: elver@google.com, peterz@infradead.org, alexander.shishkin@linux.intel.com, acme@kernel.org, mingo@redhat.com, jolsa@redhat.com, mark.rutland@arm.com, namhyung@kernel.org, tglx@linutronix.de Cc: glider@google.com, viro@zeniv.linux.org.uk, arnd@arndb.de, christian@brauner.io, dvyukov@google.com, jannh@google.com, axboe@kernel.dk, mascasa@google.com, pcc@google.com, irogers@google.com, kasan-dev@googlegroups.com, linux-arch@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, x86@kernel.org, linux-kselftest@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Adds bit perf_event_attr::sigtrap, which can be set to cause events to send SIGTRAP (with si_code TRAP_PERF) to the task where the event occurred. To distinguish perf events and allow user space to decode si_perf (if set), the event type is set in si_errno. The primary motivation is to support synchronous signals on perf events in the task where an event (such as breakpoints) triggered. Link: https://lore.kernel.org/lkml/YBv3rAT566k+6zjg@hirez.programming.kicks-ass.net/ Suggested-by: Peter Zijlstra Acked-by: Dmitry Vyukov Signed-off-by: Marco Elver --- v2: * Use atomic_set(&event_count, 1), since it must always be 0 in perf_pending_event_disable(). * Implicitly restrict inheriting events if sigtrap, but the child was cloned with CLONE_CLEAR_SIGHAND, because it is not generally safe if the child cleared all signal handlers to continue sending SIGTRAP. --- include/uapi/linux/perf_event.h | 3 ++- kernel/events/core.c | 28 +++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index 8c5b9f5ad63f..3a4dbb1688f0 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -391,7 +391,8 @@ struct perf_event_attr { build_id : 1, /* use build id in mmap2 events */ inherit_thread : 1, /* children only inherit if cloned with CLONE_THREAD */ remove_on_exec : 1, /* event is removed from task on exec */ - __reserved_1 : 27; + sigtrap : 1, /* send synchronous SIGTRAP on event */ + __reserved_1 : 26; union { __u32 wakeup_events; /* wakeup every n events */ diff --git a/kernel/events/core.c b/kernel/events/core.c index bc9e6e35e414..e70c411b0b16 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6328,6 +6328,17 @@ void perf_event_wakeup(struct perf_event *event) } } +static void perf_sigtrap(struct perf_event *event) +{ + struct kernel_siginfo info; + + clear_siginfo(&info); + info.si_signo = SIGTRAP; + info.si_code = TRAP_PERF; + info.si_errno = event->attr.type; + force_sig_info(&info); +} + static void perf_pending_event_disable(struct perf_event *event) { int cpu = READ_ONCE(event->pending_disable); @@ -6337,6 +6348,13 @@ static void perf_pending_event_disable(struct perf_event *event) if (cpu == smp_processor_id()) { WRITE_ONCE(event->pending_disable, -1); + + if (event->attr.sigtrap) { + atomic_set(&event->event_limit, 1); /* rearm event */ + perf_sigtrap(event); + return; + } + perf_event_disable_local(event); return; } @@ -11367,6 +11385,9 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, event->state = PERF_EVENT_STATE_INACTIVE; + if (event->attr.sigtrap) + atomic_set(&event->event_limit, 1); + if (task) { event->attach_state = PERF_ATTACH_TASK; /* @@ -11645,6 +11666,9 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, if (attr->remove_on_exec && attr->enable_on_exec) return -EINVAL; + if (attr->sigtrap && !attr->remove_on_exec) + return -EINVAL; + out: return ret; @@ -12874,7 +12898,9 @@ inherit_task_group(struct perf_event *event, struct task_struct *parent, struct perf_event_context *child_ctx; if (!event->attr.inherit || - (event->attr.inherit_thread && !(clone_flags & CLONE_THREAD))) { + (event->attr.inherit_thread && !(clone_flags & CLONE_THREAD)) || + /* Do not inherit if sigtrap and signal handlers were cleared. */ + (event->attr.sigtrap && (clone_flags & CLONE_CLEAR_SIGHAND))) { *inherited_all = 0; return 0; } From patchwork Wed Mar 10 10:41:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Elver X-Patchwork-Id: 12127673 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9688DC4160E for ; Wed, 10 Mar 2021 10:42:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 747C46500E for ; Wed, 10 Mar 2021 10:42:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232646AbhCJKm2 (ORCPT ); Wed, 10 Mar 2021 05:42:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38666 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232619AbhCJKmF (ORCPT ); Wed, 10 Mar 2021 05:42:05 -0500 Received: from mail-qv1-xf4a.google.com (mail-qv1-xf4a.google.com [IPv6:2607:f8b0:4864:20::f4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7E182C061762 for ; Wed, 10 Mar 2021 02:42:05 -0800 (PST) Received: by mail-qv1-xf4a.google.com with SMTP id u15so12354085qvo.13 for ; Wed, 10 Mar 2021 02:42:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=4oqgRNZGjKcuPrToE+ulENN9iboOssrjKjo3aJMrJ9Q=; b=s9prmAM12n13n3qUuRwt5GQbWCYJHSsKmZprdRrOZs1gcLo/jLhX5+3loZNnDFCA2q nD60ujTcDCXFKGqmUrEjCqph2454+hgHUx2kS6kXUOwivci8j6Mif9dpjGjG503isGp1 kf+wK0k/Xsyf5nrxWzBgoZ/wGa3SXc38O7F02QcrR9nXHUpgV/7F1x2d75Dcs4dLgWtp 9mTK7K/zOQyvHM3nkQuGlNOxP59cN1NaLkgu3ud8HYy5GeghbyxJQobe7h22TU5+l0IK 7rEIMbjOaLk2jy0V3usd/JNl9vYV+Q12llM/d18bb95be6iuEyb/xXSScecLRUVmbDFM cRDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=4oqgRNZGjKcuPrToE+ulENN9iboOssrjKjo3aJMrJ9Q=; b=H3ruJ6yu3B3bOPrEDx2GMX/fCBRz/1VJJ5JD8w3uc7qJV8RpqVlTT9L9lou0tW8TB7 XsI5KCRr+WLS7VsqDBfqiHSkWfsnNQVuayzYPJ8GaRUrLqMPwlTOjkhroXluraMpG884 JY22rncE/AxHnbPztKUohzoqJOoeCn9Vy9IVdX4RICKDCBaT2jrFK5Nj12skfb564aIr M2f0l8Z3elIVx9EYWaXwTuirXJ9SGdwVQmonn9faJsmBTakGsifbX7xaaW516MM47QFH jiG+jxWQbyAyx9Dh+2o1ZyvNIH/hkJTomwtG2GyHxbmfGwLBLaygIZdVh9DMjIeO6vbI aTIQ== X-Gm-Message-State: AOAM531GG+MtFcEE5yuo3AB7Pi9+5MlloykaOO4Q4a+lyy9Mgc4/G9az kmEprh0u3kzABmzKUEosbz0I9+mKFg== X-Google-Smtp-Source: ABdhPJzZZYzpha85M4VLEh0UrtTjdzhQkJpiQu+lvwmZ/3NwfOWbQiR6FN6lp5YnDpdBObOChPowjwgZ4w== X-Received: from elver.muc.corp.google.com ([2a00:79e0:15:13:e995:ac0b:b57c:49a4]) (user=elver job=sendgmr) by 2002:a05:6214:c27:: with SMTP id a7mr2084546qvd.54.1615372924678; Wed, 10 Mar 2021 02:42:04 -0800 (PST) Date: Wed, 10 Mar 2021 11:41:37 +0100 In-Reply-To: <20210310104139.679618-1-elver@google.com> Message-Id: <20210310104139.679618-7-elver@google.com> Mime-Version: 1.0 References: <20210310104139.679618-1-elver@google.com> X-Mailer: git-send-email 2.30.1.766.gb4fecdf3b7-goog Subject: [PATCH RFC v2 6/8] perf/core: Add breakpoint information to siginfo on SIGTRAP From: Marco Elver To: elver@google.com, peterz@infradead.org, alexander.shishkin@linux.intel.com, acme@kernel.org, mingo@redhat.com, jolsa@redhat.com, mark.rutland@arm.com, namhyung@kernel.org, tglx@linutronix.de Cc: glider@google.com, viro@zeniv.linux.org.uk, arnd@arndb.de, christian@brauner.io, dvyukov@google.com, jannh@google.com, axboe@kernel.dk, mascasa@google.com, pcc@google.com, irogers@google.com, kasan-dev@googlegroups.com, linux-arch@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, x86@kernel.org, linux-kselftest@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Encode information from breakpoint attributes into siginfo_t, which helps disambiguate which breakpoint fired. Note, providing the event fd may be unreliable, since the event may have been modified (via PERF_EVENT_IOC_MODIFY_ATTRIBUTES) between the event triggering and the signal being delivered to user space. Signed-off-by: Marco Elver --- v2: * Add comment about si_perf==0. --- kernel/events/core.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/kernel/events/core.c b/kernel/events/core.c index e70c411b0b16..aa47e111435e 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6336,6 +6336,22 @@ static void perf_sigtrap(struct perf_event *event) info.si_signo = SIGTRAP; info.si_code = TRAP_PERF; info.si_errno = event->attr.type; + + switch (event->attr.type) { + case PERF_TYPE_BREAKPOINT: + info.si_addr = (void *)(unsigned long)event->attr.bp_addr; + info.si_perf = (event->attr.bp_len << 16) | (u64)event->attr.bp_type; + break; + default: + /* + * No additional info set (si_perf == 0). + * + * Adding new cases for event types to set si_perf to a + * non-constant value must ensure that si_perf != 0. + */ + break; + } + force_sig_info(&info); } From patchwork Wed Mar 10 10:41:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Elver X-Patchwork-Id: 12127679 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9484FC1550D for ; Wed, 10 Mar 2021 10:43:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 66F1764FE8 for ; Wed, 10 Mar 2021 10:43:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232653AbhCJKm2 (ORCPT ); Wed, 10 Mar 2021 05:42:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232624AbhCJKmI (ORCPT ); Wed, 10 Mar 2021 05:42:08 -0500 Received: from mail-qt1-x84a.google.com (mail-qt1-x84a.google.com [IPv6:2607:f8b0:4864:20::84a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 11A56C061760 for ; Wed, 10 Mar 2021 02:42:08 -0800 (PST) Received: by mail-qt1-x84a.google.com with SMTP id t5so12621771qti.5 for ; Wed, 10 Mar 2021 02:42:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=NKxCcYzNapnhBc0c8bTeezMWyMgR4Ia19sYvvDoOw3g=; b=XG/AL71q9TznK064iSOw477ElJVifXxOFlN5/FYumKytsH4+vzl68B4BHhGAYWTLhN sQ+bIhmQzBTBAnlpFKlDzUxuFFQ/XwK2C9psRFD3xPfqWPZwImuclGCt5Dic2cCaQsa2 V+jv1dxUDGeD1bigg7emOhf1N1Xxyx/L62vzH7N9+bGE256xFsu0U8ZS3GEAaNJUHfq1 v8BCe+z0dNj1jcVQ047+6/Czrn5VCWeEmZHb/M04vjdmp7WC4f0Sd1JKhRT/5whH2Z99 QtlPPb0JA2GWEt6COFuMOtuw5xKSyMHKcwJm/YXBYyWIcGs59wFjqdi25IHx9dyfh6Ey qrNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=NKxCcYzNapnhBc0c8bTeezMWyMgR4Ia19sYvvDoOw3g=; b=mHjVT7t3PUuW6dUC/lUJb5kidbspd/XzfTiPgyubGMnS7hcBCekdOtQzRiSP8ehlsw nbNCwWmH/ywr6JoHSRtlJRMtdniarK6jK79UeJdORDeaeNQoq8lwLSrWrSC7sesB9eJC VFeG6eYaSTMg++pe8sDeDi3RwYtep8HUjsqYmYd2TsCv3tfg5eNgzKQqyiM8avlbVcZQ lmkkQT96bdUyg4hlB0lw5Z9ptmHLKmAaRjXcdk1XRXMoQgcONaOf+UdOdJVHuA9sJrYm UBOyrqG4COcmlKgsTY7bBXwtLdNVv+IgyndS0uHtB3xTpskmAA4t2As6fDHjHdL0vXhU U6fw== X-Gm-Message-State: AOAM530bsja/uIM1hBU2PDdWL/09Q7MUCP35GljjT347Op1oN8f7iz/K oImTL7mJKLq2e2gzZvb35IFMGj9LWQ== X-Google-Smtp-Source: ABdhPJzNnznXr9Ge+q1qD86LOJ2e2Y1LBjmAv9dW/UpmqnDxrzB9gb5AZlTAUWS4qgnapOZcp9yEfzZMuQ== X-Received: from elver.muc.corp.google.com ([2a00:79e0:15:13:e995:ac0b:b57c:49a4]) (user=elver job=sendgmr) by 2002:a05:6214:248a:: with SMTP id gi10mr2189822qvb.35.1615372927193; Wed, 10 Mar 2021 02:42:07 -0800 (PST) Date: Wed, 10 Mar 2021 11:41:38 +0100 In-Reply-To: <20210310104139.679618-1-elver@google.com> Message-Id: <20210310104139.679618-8-elver@google.com> Mime-Version: 1.0 References: <20210310104139.679618-1-elver@google.com> X-Mailer: git-send-email 2.30.1.766.gb4fecdf3b7-goog Subject: [PATCH RFC v2 7/8] selftests/perf: Add kselftest for process-wide sigtrap handling From: Marco Elver To: elver@google.com, peterz@infradead.org, alexander.shishkin@linux.intel.com, acme@kernel.org, mingo@redhat.com, jolsa@redhat.com, mark.rutland@arm.com, namhyung@kernel.org, tglx@linutronix.de Cc: glider@google.com, viro@zeniv.linux.org.uk, arnd@arndb.de, christian@brauner.io, dvyukov@google.com, jannh@google.com, axboe@kernel.dk, mascasa@google.com, pcc@google.com, irogers@google.com, kasan-dev@googlegroups.com, linux-arch@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, x86@kernel.org, linux-kselftest@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Add a kselftest for testing process-wide perf events with synchronous SIGTRAP on events (using breakpoints). In particular, we want to test that changes to the event propagate to all children, and the SIGTRAPs are in fact synchronously sent to the thread where the event occurred. Signed-off-by: Marco Elver --- v2: * Patch added to series. --- .../testing/selftests/perf_events/.gitignore | 2 + tools/testing/selftests/perf_events/Makefile | 6 + tools/testing/selftests/perf_events/config | 1 + tools/testing/selftests/perf_events/settings | 1 + .../selftests/perf_events/sigtrap_threads.c | 202 ++++++++++++++++++ 5 files changed, 212 insertions(+) create mode 100644 tools/testing/selftests/perf_events/.gitignore create mode 100644 tools/testing/selftests/perf_events/Makefile create mode 100644 tools/testing/selftests/perf_events/config create mode 100644 tools/testing/selftests/perf_events/settings create mode 100644 tools/testing/selftests/perf_events/sigtrap_threads.c diff --git a/tools/testing/selftests/perf_events/.gitignore b/tools/testing/selftests/perf_events/.gitignore new file mode 100644 index 000000000000..4dc43e1bd79c --- /dev/null +++ b/tools/testing/selftests/perf_events/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +sigtrap_threads diff --git a/tools/testing/selftests/perf_events/Makefile b/tools/testing/selftests/perf_events/Makefile new file mode 100644 index 000000000000..973a2c39ca83 --- /dev/null +++ b/tools/testing/selftests/perf_events/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +CFLAGS += -Wl,-no-as-needed -Wall -I../../../../usr/include +LDFLAGS += -lpthread + +TEST_GEN_PROGS := sigtrap_threads +include ../lib.mk diff --git a/tools/testing/selftests/perf_events/config b/tools/testing/selftests/perf_events/config new file mode 100644 index 000000000000..ba58ff2203e4 --- /dev/null +++ b/tools/testing/selftests/perf_events/config @@ -0,0 +1 @@ +CONFIG_PERF_EVENTS=y diff --git a/tools/testing/selftests/perf_events/settings b/tools/testing/selftests/perf_events/settings new file mode 100644 index 000000000000..6091b45d226b --- /dev/null +++ b/tools/testing/selftests/perf_events/settings @@ -0,0 +1 @@ +timeout=120 diff --git a/tools/testing/selftests/perf_events/sigtrap_threads.c b/tools/testing/selftests/perf_events/sigtrap_threads.c new file mode 100644 index 000000000000..7ebb9bb34c2e --- /dev/null +++ b/tools/testing/selftests/perf_events/sigtrap_threads.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test for perf events with SIGTRAP across all threads. + * + * Copyright (C) 2021, Google LLC. + */ + +#define _GNU_SOURCE +#include + +/* We need the latest siginfo from the kernel repo. */ +#include +#define __have_siginfo_t 1 +#define __have_sigval_t 1 +#define __have_sigevent_t 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../kselftest_harness.h" + +#define NUM_THREADS 5 + +/* Data shared between test body, threads, and signal handler. */ +static struct { + int tids_want_signal; /* Which threads still want a signal. */ + int signal_count; /* Sanity check number of signals received. */ + volatile int iterate_on; /* Variable to set breakpoint on. */ + siginfo_t first_siginfo; /* First observed siginfo_t. */ +} ctx; + +static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr) +{ + struct perf_event_attr attr = { + .type = PERF_TYPE_BREAKPOINT, + .size = sizeof(attr), + .sample_period = 1, + .disabled = !enabled, + .bp_addr = (long)addr, + .bp_type = HW_BREAKPOINT_RW, + .bp_len = HW_BREAKPOINT_LEN_1, + .inherit = 1, /* Children inherit events ... */ + .inherit_thread = 1, /* ... but only cloned with CLONE_THREAD. */ + .remove_on_exec = 1, /* Required by sigtrap. */ + .sigtrap = 1, /* Request synchronous SIGTRAP on event. */ + }; + return attr; +} + +static void sigtrap_handler(int signum, siginfo_t *info, void *ucontext) +{ + if (info->si_code != TRAP_PERF) { + fprintf(stderr, "%s: unexpected si_code %d\n", __func__, info->si_code); + return; + } + + /* + * The data in siginfo_t we're interested in should all be the same + * across threads. + */ + if (!__atomic_fetch_add(&ctx.signal_count, 1, __ATOMIC_RELAXED)) + ctx.first_siginfo = *info; + __atomic_fetch_sub(&ctx.tids_want_signal, syscall(__NR_gettid), __ATOMIC_RELAXED); +} + +static void *test_thread(void *arg) +{ + pthread_barrier_t *barrier = (pthread_barrier_t *)arg; + pid_t tid = syscall(__NR_gettid); + int iter; + int i; + + pthread_barrier_wait(barrier); + + __atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED); + iter = ctx.iterate_on; /* read */ + for (i = 0; i < iter - 1; i++) { + __atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED); + ctx.iterate_on = iter; /* idempotent write */ + } + + return NULL; +} + +FIXTURE(sigtrap_threads) +{ + struct sigaction oldact; + pthread_t threads[NUM_THREADS]; + pthread_barrier_t barrier; + int fd; +}; + +FIXTURE_SETUP(sigtrap_threads) +{ + struct perf_event_attr attr = make_event_attr(false, &ctx.iterate_on); + struct sigaction action = {}; + int i; + + memset(&ctx, 0, sizeof(ctx)); + + /* Initialize sigtrap handler. */ + action.sa_flags = SA_SIGINFO | SA_NODEFER; + action.sa_sigaction = sigtrap_handler; + sigemptyset(&action.sa_mask); + ASSERT_EQ(sigaction(SIGTRAP, &action, &self->oldact), 0); + + /* Initialize perf event. */ + self->fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, PERF_FLAG_FD_CLOEXEC); + ASSERT_NE(self->fd, -1); + + /* Spawn threads inheriting perf event. */ + pthread_barrier_init(&self->barrier, NULL, NUM_THREADS + 1); + for (i = 0; i < NUM_THREADS; i++) + ASSERT_EQ(pthread_create(&self->threads[i], NULL, test_thread, &self->barrier), 0); +} + +FIXTURE_TEARDOWN(sigtrap_threads) +{ + pthread_barrier_destroy(&self->barrier); + close(self->fd); + sigaction(SIGTRAP, &self->oldact, NULL); +} + +static void run_test_threads(struct __test_metadata *_metadata, + FIXTURE_DATA(sigtrap_threads) *self) +{ + int i; + + pthread_barrier_wait(&self->barrier); + for (i = 0; i < NUM_THREADS; i++) + ASSERT_EQ(pthread_join(self->threads[i], NULL), 0); +} + +TEST_F(sigtrap_threads, remain_disabled) +{ + run_test_threads(_metadata, self); + EXPECT_EQ(ctx.signal_count, 0); + EXPECT_NE(ctx.tids_want_signal, 0); +} + +TEST_F(sigtrap_threads, enable_event) +{ + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0); + run_test_threads(_metadata, self); + + EXPECT_EQ(ctx.signal_count, NUM_THREADS); + EXPECT_EQ(ctx.tids_want_signal, 0); + EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on); + EXPECT_EQ(ctx.first_siginfo.si_errno, PERF_TYPE_BREAKPOINT); + EXPECT_EQ(ctx.first_siginfo.si_perf, (HW_BREAKPOINT_LEN_1 << 16) | HW_BREAKPOINT_RW); + + /* Check enabled for parent. */ + ctx.iterate_on = 0; + EXPECT_EQ(ctx.signal_count, NUM_THREADS + 1); +} + +/* Test that modification propagates to all inherited events. */ +TEST_F(sigtrap_threads, modify_and_enable_event) +{ + struct perf_event_attr new_attr = make_event_attr(true, &ctx.iterate_on); + + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, &new_attr), 0); + run_test_threads(_metadata, self); + + EXPECT_EQ(ctx.signal_count, NUM_THREADS); + EXPECT_EQ(ctx.tids_want_signal, 0); + EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on); + EXPECT_EQ(ctx.first_siginfo.si_errno, PERF_TYPE_BREAKPOINT); + EXPECT_EQ(ctx.first_siginfo.si_perf, (HW_BREAKPOINT_LEN_1 << 16) | HW_BREAKPOINT_RW); + + /* Check enabled for parent. */ + ctx.iterate_on = 0; + EXPECT_EQ(ctx.signal_count, NUM_THREADS + 1); +} + +/* Stress test event + signal handling. */ +TEST_F(sigtrap_threads, signal_stress) +{ + ctx.iterate_on = 3000; + + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0); + run_test_threads(_metadata, self); + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_DISABLE, 0), 0); + + EXPECT_EQ(ctx.signal_count, NUM_THREADS * ctx.iterate_on); + EXPECT_EQ(ctx.tids_want_signal, 0); + EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on); + EXPECT_EQ(ctx.first_siginfo.si_errno, PERF_TYPE_BREAKPOINT); + EXPECT_EQ(ctx.first_siginfo.si_perf, (HW_BREAKPOINT_LEN_1 << 16) | HW_BREAKPOINT_RW); +} + +TEST_HARNESS_MAIN From patchwork Wed Mar 10 10:41:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Elver X-Patchwork-Id: 12127681 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6AB01C4161F for ; Wed, 10 Mar 2021 10:43:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4A93964F77 for ; Wed, 10 Mar 2021 10:43:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232657AbhCJKm2 (ORCPT ); Wed, 10 Mar 2021 05:42:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38696 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232627AbhCJKmL (ORCPT ); Wed, 10 Mar 2021 05:42:11 -0500 Received: from mail-wr1-x44a.google.com (mail-wr1-x44a.google.com [IPv6:2a00:1450:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A5F81C061762 for ; Wed, 10 Mar 2021 02:42:10 -0800 (PST) Received: by mail-wr1-x44a.google.com with SMTP id g5so7748109wrd.22 for ; Wed, 10 Mar 2021 02:42:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=7/IRp5vkLAkmWPwXwPAt2lcWrbp37U2bBtUBzeSgBmg=; b=oT8UbYzHn9gNsaJlosymdC745FCCb5j1NpqCi6y6XGk2LCpINk9uNwnZGGUJkKV6Vb BvjKaIo38nsHgSw8NnUG0skzxM69CaULuVSdFd5vlWXaT6sH0tT0jdlSCtSlKeYnesIU MeptW1dQMsxpCJH+Le+g51q/hy3d7tAUn2IuhPjQus7f6at98xHDrkr2gRdno0xXLXdR WrkerH8tDwFNYLyDwIp3QopJLccGoHWCUbj+5x7yPB6+2vI63wsXZfx1VM3J7t5GxXAU koogE7GC4rcE4UZWoGEojxOM/6FLPltTUum3LORIo/0pvDz9lSg0kFfiCcw8U45f72pE yjmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=7/IRp5vkLAkmWPwXwPAt2lcWrbp37U2bBtUBzeSgBmg=; b=c3MYfIEoPHp0uQHdUqntRjdyT6rP+6MsaLGyxYhqMBHY+aOV4zbeXNK6BQhtQNpvL1 D6kuvbRhPaOsdaCPKpYZ5U1EdEtG+FaFwftQO1bufTc1EnsyA/azULd0Lw//Hy+JALya 0mN7/AwvJ5D7hJA4siyJ8ZKL3kwln2wku9KeM2c8FjwhVTAWaNM/c9yxriB92E89BQzW 4TTnVZy9hu7ALP1ETUjZgw5whtZbgdRQmkSIvSLxNsuYvScy2052r/y6i6KTP7i82q8B O25xdDL5Mjqm45cKKHaTRmKr8ekrci3JM7x9dk57VP5ujlUV86/mu8Q1PEhEo24CNiZ5 A+8Q== X-Gm-Message-State: AOAM5330iq8HcSjZ1AZI47AJn4+0AXAIRVGEtFM9KYjuANqGzmzChA92 +BV85nwkHWKSDCjmUgsNblmsP0nBNA== X-Google-Smtp-Source: ABdhPJzmmPUgjwv7c5uDiZlm36P7gAPiW3mZSGqSdc+JHgYuQCBvLe0Wg1klUV1748sLe9PMLNyFlADrUQ== X-Received: from elver.muc.corp.google.com ([2a00:79e0:15:13:e995:ac0b:b57c:49a4]) (user=elver job=sendgmr) by 2002:a1c:4c17:: with SMTP id z23mr2721408wmf.17.1615372929385; Wed, 10 Mar 2021 02:42:09 -0800 (PST) Date: Wed, 10 Mar 2021 11:41:39 +0100 In-Reply-To: <20210310104139.679618-1-elver@google.com> Message-Id: <20210310104139.679618-9-elver@google.com> Mime-Version: 1.0 References: <20210310104139.679618-1-elver@google.com> X-Mailer: git-send-email 2.30.1.766.gb4fecdf3b7-goog Subject: [PATCH RFC v2 8/8] selftests/perf: Add kselftest for remove_on_exec From: Marco Elver To: elver@google.com, peterz@infradead.org, alexander.shishkin@linux.intel.com, acme@kernel.org, mingo@redhat.com, jolsa@redhat.com, mark.rutland@arm.com, namhyung@kernel.org, tglx@linutronix.de Cc: glider@google.com, viro@zeniv.linux.org.uk, arnd@arndb.de, christian@brauner.io, dvyukov@google.com, jannh@google.com, axboe@kernel.dk, mascasa@google.com, pcc@google.com, irogers@google.com, kasan-dev@googlegroups.com, linux-arch@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, x86@kernel.org, linux-kselftest@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Add kselftest to test that remove_on_exec removes inherited events from child tasks. Signed-off-by: Marco Elver Signed-off-by: Peter Zijlstra (Intel) --- v2: * Add patch to series. --- .../testing/selftests/perf_events/.gitignore | 1 + tools/testing/selftests/perf_events/Makefile | 2 +- .../selftests/perf_events/remove_on_exec.c | 256 ++++++++++++++++++ 3 files changed, 258 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/perf_events/remove_on_exec.c diff --git a/tools/testing/selftests/perf_events/.gitignore b/tools/testing/selftests/perf_events/.gitignore index 4dc43e1bd79c..790c47001e77 100644 --- a/tools/testing/selftests/perf_events/.gitignore +++ b/tools/testing/selftests/perf_events/.gitignore @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only sigtrap_threads +remove_on_exec diff --git a/tools/testing/selftests/perf_events/Makefile b/tools/testing/selftests/perf_events/Makefile index 973a2c39ca83..fcafa5f0d34c 100644 --- a/tools/testing/selftests/perf_events/Makefile +++ b/tools/testing/selftests/perf_events/Makefile @@ -2,5 +2,5 @@ CFLAGS += -Wl,-no-as-needed -Wall -I../../../../usr/include LDFLAGS += -lpthread -TEST_GEN_PROGS := sigtrap_threads +TEST_GEN_PROGS := sigtrap_threads remove_on_exec include ../lib.mk diff --git a/tools/testing/selftests/perf_events/remove_on_exec.c b/tools/testing/selftests/perf_events/remove_on_exec.c new file mode 100644 index 000000000000..e176b3a74d55 --- /dev/null +++ b/tools/testing/selftests/perf_events/remove_on_exec.c @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test for remove_on_exec. + * + * Copyright (C) 2021, Google LLC. + */ + +#define _GNU_SOURCE +#include + +/* We need the latest siginfo from the kernel repo. */ +#include +#define __have_siginfo_t 1 +#define __have_sigval_t 1 +#define __have_sigevent_t 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../kselftest_harness.h" + +static volatile int signal_count; + +static struct perf_event_attr make_event_attr(void) +{ + struct perf_event_attr attr = { + .type = PERF_TYPE_HARDWARE, + .size = sizeof(attr), + .config = PERF_COUNT_HW_INSTRUCTIONS, + .sample_period = 1000, + .exclude_kernel = 1, + .exclude_hv = 1, + .disabled = 1, + .inherit = 1, + /* + * Children normally retain their inherited event on exec; with + * remove_on_exec, we'll remove their event, but the parent and + * any other non-exec'd children will keep their events. + */ + .remove_on_exec = 1, + .sigtrap = 1, + }; + return attr; +} + +static void sigtrap_handler(int signum, siginfo_t *info, void *ucontext) +{ + if (info->si_code != TRAP_PERF) { + fprintf(stderr, "%s: unexpected si_code %d\n", __func__, info->si_code); + return; + } + + signal_count++; +} + +FIXTURE(remove_on_exec) +{ + struct sigaction oldact; + int fd; +}; + +FIXTURE_SETUP(remove_on_exec) +{ + struct perf_event_attr attr = make_event_attr(); + struct sigaction action = {}; + + signal_count = 0; + + /* Initialize sigtrap handler. */ + action.sa_flags = SA_SIGINFO | SA_NODEFER; + action.sa_sigaction = sigtrap_handler; + sigemptyset(&action.sa_mask); + ASSERT_EQ(sigaction(SIGTRAP, &action, &self->oldact), 0); + + /* Initialize perf event. */ + self->fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, PERF_FLAG_FD_CLOEXEC); + ASSERT_NE(self->fd, -1); +} + +FIXTURE_TEARDOWN(remove_on_exec) +{ + close(self->fd); + sigaction(SIGTRAP, &self->oldact, NULL); +} + +/* Verify event propagates to fork'd child. */ +TEST_F(remove_on_exec, fork_only) +{ + int status; + pid_t pid = fork(); + + if (pid == 0) { + ASSERT_EQ(signal_count, 0); + ASSERT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0); + while (!signal_count); + _exit(42); + } + + while (!signal_count); /* Child enables event. */ + EXPECT_EQ(waitpid(pid, &status, 0), pid); + EXPECT_EQ(WEXITSTATUS(status), 42); +} + +/* + * Verify that event does _not_ propagate to fork+exec'd child; event enabled + * after fork+exec. + */ +TEST_F(remove_on_exec, fork_exec_then_enable) +{ + pid_t pid_exec, pid_only_fork; + int pipefd[2]; + int tmp; + + /* + * Non-exec child, to ensure exec does not affect inherited events of + * other children. + */ + pid_only_fork = fork(); + if (pid_only_fork == 0) { + /* Block until parent enables event. */ + while (!signal_count); + _exit(42); + } + + ASSERT_NE(pipe(pipefd), -1); + pid_exec = fork(); + if (pid_exec == 0) { + ASSERT_NE(dup2(pipefd[1], STDOUT_FILENO), -1); + close(pipefd[0]); + execl("/proc/self/exe", "exec_child", NULL); + _exit((perror("exec failed"), 1)); + } + close(pipefd[1]); + + ASSERT_EQ(waitpid(pid_exec, &tmp, WNOHANG), 0); /* Child is running. */ + /* Wait for exec'd child to start spinning. */ + EXPECT_EQ(read(pipefd[0], &tmp, sizeof(int)), sizeof(int)); + EXPECT_EQ(tmp, 42); + close(pipefd[0]); + /* Now we can enable the event, knowing the child is doing work. */ + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0); + /* If the event propagated to the exec'd child, it will exit normally... */ + usleep(100000); /* ... give time for event to trigger (in case of bug). */ + EXPECT_EQ(waitpid(pid_exec, &tmp, WNOHANG), 0); /* Should still be running. */ + EXPECT_EQ(kill(pid_exec, SIGKILL), 0); + + /* Verify removal from child did not affect this task's event. */ + tmp = signal_count; + while (signal_count == tmp); /* Should not hang! */ + /* Nor should it have affected the first child. */ + EXPECT_EQ(waitpid(pid_only_fork, &tmp, 0), pid_only_fork); + EXPECT_EQ(WEXITSTATUS(tmp), 42); +} + +/* + * Verify that event does _not_ propagate to fork+exec'd child; event enabled + * before fork+exec. + */ +TEST_F(remove_on_exec, enable_then_fork_exec) +{ + pid_t pid_exec; + int tmp; + + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0); + + pid_exec = fork(); + if (pid_exec == 0) { + execl("/proc/self/exe", "exec_child", NULL); + _exit((perror("exec failed"), 1)); + } + + /* + * The child may exit abnormally at any time if the event propagated and + * a SIGTRAP is sent before the handler was set up. + */ + usleep(100000); /* ... give time for event to trigger (in case of bug). */ + EXPECT_EQ(waitpid(pid_exec, &tmp, WNOHANG), 0); /* Should still be running. */ + EXPECT_EQ(kill(pid_exec, SIGKILL), 0); + + /* Verify removal from child did not affect this task's event. */ + tmp = signal_count; + while (signal_count == tmp); /* Should not hang! */ +} + +TEST_F(remove_on_exec, exec_stress) +{ + pid_t pids[30]; + int i, tmp; + + for (i = 0; i < sizeof(pids) / sizeof(pids[0]); i++) { + pids[i] = fork(); + if (pids[i] == 0) { + execl("/proc/self/exe", "exec_child", NULL); + _exit((perror("exec failed"), 1)); + } + + /* Some forked with event disabled, rest with enabled. */ + if (i > 10) + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0); + } + + usleep(100000); /* ... give time for event to trigger (in case of bug). */ + + for (i = 0; i < sizeof(pids) / sizeof(pids[0]); i++) { + /* All children should still be running. */ + EXPECT_EQ(waitpid(pids[i], &tmp, WNOHANG), 0); + EXPECT_EQ(kill(pids[i], SIGKILL), 0); + } + + /* Verify event is still alive. */ + tmp = signal_count; + while (signal_count == tmp); +} + +/* For exec'd child. */ +static void exec_child(void) +{ + struct sigaction action = {}; + const int val = 42; + + /* Set up sigtrap handler in case we erroneously receive a trap. */ + action.sa_flags = SA_SIGINFO | SA_NODEFER; + action.sa_sigaction = sigtrap_handler; + sigemptyset(&action.sa_mask); + if (sigaction(SIGTRAP, &action, NULL)) + _exit((perror("sigaction failed"), 1)); + + /* Signal parent that we're starting to spin. */ + if (write(STDOUT_FILENO, &val, sizeof(int)) == -1) + _exit((perror("write failed"), 1)); + + /* Should hang here until killed. */ + while (!signal_count); +} + +#define main test_main +TEST_HARNESS_MAIN +#undef main +int main(int argc, char *argv[]) +{ + if (!strcmp(argv[0], "exec_child")) { + exec_child(); + return 1; + } + + return test_main(argc, argv); +}