From nobody Sun Feb 8 15:59:26 2026 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B89E2195; Fri, 12 Apr 2024 00:17:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712881072; cv=none; b=g8Jpq5cefJTleJc2XmoRcNKJrOWEzrfjfYLIgQ9xIxvZptVxi9aMjmUiRIETjNXLh1hOP7r3prQdxvR7YfxeP0TjAm4HgPLlTb2hYHaBEhA+tSR3R7zd5/8GCTMKjG+QSKHOUnhAs2yeOQPjKLgKyRGnq73VqjUY7vOBc2YcR8k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712881072; c=relaxed/simple; bh=BNNGY5+CHDXfjGHZyVuZHwM0zX798QLsj57JCFZBkCM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=IQReKa6HK1StAH/phDzT44cvYnP9GFLVYEMHFUqMwV/16R8U17aKrPN92rjcWyPPpeCQGzSCC16R0KjQ1Qk3Fh8yob/sAilomF2oiqFePXq4xqIlAWxd7EoJojanDkChP0Mx8haLDdFz3uk/P7FNPJpKkGoWguqrGyjRWXSJ/gw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=pHbs6rc2; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="pHbs6rc2" Received: from localhost.localdomain (unknown [4.155.48.125]) by linux.microsoft.com (Postfix) with ESMTPSA id 5443720EC323; Thu, 11 Apr 2024 17:17:50 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 5443720EC323 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1712881070; bh=FcYc71XiBGnC8Gok9z2Cask+yzIzGSZjKrNW1Wp57BQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pHbs6rc2Hz4XH0t/RUJ0X9ZWZ6aQbFRsQqZM5mwhNekKT53ImaIjfq95Y5xTO5kAK rdf/MPPBiFUU0FLQXoP2tbi+vFFmc4bTtM3ui0v5lFV6IIFezUdGQrERlGTlzCajVc fP+hQStG4MLRgUfOAtKCdwUC/YAqSKLjDlBC+di4= From: Beau Belgrave To: peterz@infradead.org, mingo@redhat.com, acme@kernel.org, namhyung@kernel.org, rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com Cc: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mark.rutland@arm.com, alexander.shishkin@linux.intel.com, jolsa@kernel.org, irogers@google.com, adrian.hunter@intel.com, primiano@google.com, aahringo@redhat.com, dcook@linux.microsoft.com Subject: [RFC PATCH 1/4] perf/core: Introduce perf_prepare_dump_data() Date: Fri, 12 Apr 2024 00:17:29 +0000 Message-Id: <20240412001732.475-2-beaub@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412001732.475-1-beaub@linux.microsoft.com> References: <20240412001732.475-1-beaub@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Factor out perf_prepare_dump_data() so that the same logic is used for dumping stack data as other types, such as TLS. Slightly refactor perf_sample_ustack_size() to perf_sample_dump_size(). Move reg checks up into perf_ustack_task_size() since the task size must now be calculated before preparing dump data. Signed-off-by: Beau Belgrave --- kernel/events/core.c | 79 ++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 724e6d7e128f..07de5cc2aa25 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6912,7 +6912,13 @@ static void perf_sample_regs_intr(struct perf_regs *= regs_intr, */ static u64 perf_ustack_task_size(struct pt_regs *regs) { - unsigned long addr =3D perf_user_stack_pointer(regs); + unsigned long addr; + + /* No regs, no stack pointer, no dump. */ + if (!regs) + return 0; + + addr =3D perf_user_stack_pointer(regs); =20 if (!addr || addr >=3D TASK_SIZE) return 0; @@ -6921,42 +6927,35 @@ static u64 perf_ustack_task_size(struct pt_regs *re= gs) } =20 static u16 -perf_sample_ustack_size(u16 stack_size, u16 header_size, - struct pt_regs *regs) +perf_sample_dump_size(u16 dump_size, u16 header_size, u64 task_size) { - u64 task_size; - - /* No regs, no stack pointer, no dump. */ - if (!regs) - return 0; - /* - * Check if we fit in with the requested stack size into the: + * Check if we fit in with the requested dump size into the: * - TASK_SIZE * If we don't, we limit the size to the TASK_SIZE. * * - remaining sample size - * If we don't, we customize the stack size to + * If we don't, we customize the dump size to * fit in to the remaining sample size. */ =20 - task_size =3D min((u64) USHRT_MAX, perf_ustack_task_size(regs)); - stack_size =3D min(stack_size, (u16) task_size); + task_size =3D min((u64) USHRT_MAX, task_size); + dump_size =3D min(dump_size, (u16) task_size); =20 /* Current header size plus static size and dynamic size. */ header_size +=3D 2 * sizeof(u64); =20 - /* Do we fit in with the current stack dump size? */ - if ((u16) (header_size + stack_size) < header_size) { + /* Do we fit in with the current dump size? */ + if ((u16) (header_size + dump_size) < header_size) { /* * If we overflow the maximum size for the sample, - * we customize the stack dump size to fit in. + * we customize the dump size to fit in. */ - stack_size =3D USHRT_MAX - header_size - sizeof(u64); - stack_size =3D round_up(stack_size, sizeof(u64)); + dump_size =3D USHRT_MAX - header_size - sizeof(u64); + dump_size =3D round_up(dump_size, sizeof(u64)); } =20 - return stack_size; + return dump_size; } =20 static void @@ -7648,6 +7647,32 @@ static __always_inline u64 __cond_set(u64 flags, u64= s, u64 d) return d * !!(flags & s); } =20 +static inline u16 +perf_prepare_dump_data(struct perf_sample_data *data, + struct perf_event *event, + struct pt_regs *regs, + u16 dump_size, + u64 task_size) +{ + u16 header_size =3D perf_sample_data_size(data, event); + u16 size =3D sizeof(u64); + + dump_size =3D perf_sample_dump_size(dump_size, header_size, + task_size); + + /* + * If there is something to dump, add space for the dump + * itself and for the field that tells the dynamic size, + * which is how many have been actually dumped. + */ + if (dump_size) + size +=3D sizeof(u64) + dump_size; + + data->dyn_size +=3D size; + + return dump_size; +} + void perf_prepare_sample(struct perf_sample_data *data, struct perf_event *event, struct pt_regs *regs) @@ -7725,22 +7750,12 @@ void perf_prepare_sample(struct perf_sample_data *d= ata, * up the rest of the sample size. */ u16 stack_size =3D event->attr.sample_stack_user; - u16 header_size =3D perf_sample_data_size(data, event); - u16 size =3D sizeof(u64); - - stack_size =3D perf_sample_ustack_size(stack_size, header_size, - data->regs_user.regs); + u64 task_size =3D perf_ustack_task_size(regs); =20 - /* - * If there is something to dump, add space for the dump - * itself and for the field that tells the dynamic size, - * which is how many have been actually dumped. - */ - if (stack_size) - size +=3D sizeof(u64) + stack_size; + stack_size =3D perf_prepare_dump_data(data, event, regs, + stack_size, task_size); =20 data->stack_user_size =3D stack_size; - data->dyn_size +=3D size; data->sample_flags |=3D PERF_SAMPLE_STACK_USER; } =20 --=20 2.34.1 From nobody Sun Feb 8 15:59:26 2026 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DE3FF360; Fri, 12 Apr 2024 00:17:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712881073; cv=none; b=PCBdLsUqbvn266RED+NtjxY0n7Invcas8sB7/Fsu0iufKLKTvNxTbsX0PW4hSJP9fyL7i9/3tBxjabAAoMsjhmyy/17TUZ+6PYv+uCa/i9NePi2IbRfKCXqddf9PpJaQMkfi45rzNn51K+dbxDyv0QCJsSSuHsUsQ32wQN/C+dU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712881073; c=relaxed/simple; bh=xj6QGik4xvsN4lQj/YHP4pSr4CLFuW5i5RgEQz//Dw4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=oNDSycgUuKE+HPokBPUGpbH/R887E1Yw5tWC4NVbONwjZFCM673Eh0C1g8L7+Hyxj+/XlRV4soge8IR1kCeOrlUMislPz/JRBAofUFFfGgwgKvv9/tmZ7RGTO3IcBkffXK5Sqr9PbaiHeADw3aDvZlb50RSvTz+AIbHk48O9ZNo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=ddlglKL+; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="ddlglKL+" Received: from localhost.localdomain (unknown [4.155.48.125]) by linux.microsoft.com (Postfix) with ESMTPSA id 715BA20EC327; Thu, 11 Apr 2024 17:17:50 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 715BA20EC327 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1712881070; bh=eaw3h+lPrjxdh5uerWDCtaQEhq8uGqBARjhEDVRDDbg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ddlglKL+mK3nW5AG9GRMnLlhSlx6QEDk+w8xDhRnmmbAADOfnyFJQOkAooA3UJyvZ kSB6XMtc7zEAhVPoP+1Yha/hP09gMN5n7jqika65Cgi79T/vIKnfvt6AZw/Nghn2HW WALVmt3n5eEHbTX5ZLKQ67/wnJPWIlW1n8Uz4T1Q= From: Beau Belgrave To: peterz@infradead.org, mingo@redhat.com, acme@kernel.org, namhyung@kernel.org, rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com Cc: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mark.rutland@arm.com, alexander.shishkin@linux.intel.com, jolsa@kernel.org, irogers@google.com, adrian.hunter@intel.com, primiano@google.com, aahringo@redhat.com, dcook@linux.microsoft.com Subject: [RFC PATCH 2/4] perf: Introduce PERF_SAMPLE_TLS_USER sample type Date: Fri, 12 Apr 2024 00:17:30 +0000 Message-Id: <20240412001732.475-3-beaub@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412001732.475-1-beaub@linux.microsoft.com> References: <20240412001732.475-1-beaub@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When samples are generated, there is no way via the perf_event ABI to fetch per-thread data. This data is very useful in tracing scenarios that involve correlation IDs, such as OpenTelemetry. They are also useful for tracking per-thread performance details directly within a cooperating user process. The newly establish OpenTelemetry profiling group requires a way to get tracing correlations on both Linux and Windows. On Windows this correlation is on a per-thread basis directly via ETW. On Linux we need a fast mechanism to store these details and TLS seems like the best option, see links for more details. Add a new sample type (PERF_SAMPLE_TLS_USER) that fetches TLS data up to X bytes per-sample. Use the existing PERF_SAMPLE_STACK_USER ABI for outputting data out to consumers. Store requested data size by the user in the previously reserved u16 (__reserved_2) within perf_event_attr. Add tls_addr and tls_user_size to perf_sample_data and calculate them during sample preparation. This allows the output side to know if truncation is going to occur and not having to re-fetch the TLS value from the user process a second time. Add CONFIG_HAVE_PERF_USER_TLS_DUMP so that architectures can specify if they have a TLS specific register (or other logic) that can be used for dumping. This does not yet enable any architecture to do TLS dump, it simply makes it possible by allowing a arch defined method named arch_perf_user_tls_pointer(). Add perf_tls struct that arch_perf_user_tls_pointer() utilizes to set TLS details of the address and size (for 32bit on 64bit compat cases). Link: https://opentelemetry.io/blog/2024/profiling/ Link: https://www.elastic.co/blog/continuous-profiling-distributed-tracing-= correlation Signed-off-by: Beau Belgrave --- arch/Kconfig | 7 +++ include/linux/perf_event.h | 7 +++ include/uapi/linux/perf_event.h | 5 +- kernel/events/core.c | 105 +++++++++++++++++++++++++++++++- kernel/events/internal.h | 16 +++++ 5 files changed, 137 insertions(+), 3 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 9f066785bb71..6afaf5f46e2f 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -430,6 +430,13 @@ config HAVE_PERF_USER_STACK_DUMP access to the user stack pointer which is not unified across architectures. =20 +config HAVE_PERF_USER_TLS_DUMP + bool + help + Support user tls dumps for perf event samples. This needs + access to the user tls pointer which is not unified across + architectures. + config HAVE_ARCH_JUMP_LABEL bool =20 diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index d2a15c0c6f8a..7fac81929eed 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -1202,8 +1202,15 @@ struct perf_sample_data { u64 data_page_size; u64 code_page_size; u64 aux_size; + u64 tls_addr; + u64 tls_user_size; } ____cacheline_aligned; =20 +struct perf_tls { + unsigned long base; /* Base address for TLS */ + unsigned long size; /* Size of base address */ +}; + /* default value for data source */ #define PERF_MEM_NA (PERF_MEM_S(OP, NA) |\ PERF_MEM_S(LVL, NA) |\ diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_even= t.h index 3a64499b0f5d..b62669cfe581 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -162,8 +162,9 @@ enum perf_event_sample_format { PERF_SAMPLE_DATA_PAGE_SIZE =3D 1U << 22, PERF_SAMPLE_CODE_PAGE_SIZE =3D 1U << 23, PERF_SAMPLE_WEIGHT_STRUCT =3D 1U << 24, + PERF_SAMPLE_TLS_USER =3D 1U << 25, =20 - PERF_SAMPLE_MAX =3D 1U << 25, /* non-ABI */ + PERF_SAMPLE_MAX =3D 1U << 26, /* non-ABI */ }; =20 #define PERF_SAMPLE_WEIGHT_TYPE (PERF_SAMPLE_WEIGHT | PERF_SAMPLE_WEIGHT_S= TRUCT) @@ -509,7 +510,7 @@ struct perf_event_attr { */ __u32 aux_watermark; __u16 sample_max_stack; - __u16 __reserved_2; + __u16 sample_tls_user; /* Size of TLS data to dump on samples */ __u32 aux_sample_size; __u32 __reserved_3; =20 diff --git a/kernel/events/core.c b/kernel/events/core.c index 07de5cc2aa25..f848bf4be9bd 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6926,6 +6926,45 @@ static u64 perf_ustack_task_size(struct pt_regs *reg= s) return TASK_SIZE - addr; } =20 +/* + * Get remaining task size from user tls pointer. + * + * Outputs the address to use for the dump to avoid doing + * this twice (prepare and output). + */ +static u64 +perf_utls_task_size(struct pt_regs *regs, u64 dump_size, u64 *tls_addr) +{ + struct perf_tls tls; + unsigned long addr; + + *tls_addr =3D 0; + + /* No regs, no tls pointer, no dump. */ + if (!regs) + return 0; + + perf_user_tls_pointer(&tls); + + if (WARN_ONCE(tls.size > sizeof(addr), "perf: Bad TLS size.\n")) + return 0; + + addr =3D 0; + arch_perf_out_copy_user(&addr, (void *)tls.base, tls.size); + + if (addr < dump_size) + return 0; + + addr -=3D dump_size; + + if (!addr || addr >=3D TASK_SIZE) + return 0; + + *tls_addr =3D addr; + + return TASK_SIZE - addr; +} + static u16 perf_sample_dump_size(u16 dump_size, u16 header_size, u64 task_size) { @@ -6997,6 +7036,43 @@ perf_output_sample_ustack(struct perf_output_handle = *handle, u64 dump_size, } } =20 +static void +perf_output_sample_utls(struct perf_output_handle *handle, u64 addr, + u64 dump_size, struct pt_regs *regs) +{ + /* Case of a kernel thread, nothing to dump */ + if (!regs) { + u64 size =3D 0; + perf_output_put(handle, size); + } else { + unsigned int rem; + u64 dyn_size; + + /* + * We dump: + * static size + * - the size requested by user or the best one we can fit + * in to the sample max size + * data + * - user tls dump data + * dynamic size + * - the actual dumped size + */ + + /* Static size. */ + perf_output_put(handle, dump_size); + + /* Data. */ + rem =3D __output_copy_user(handle, (void *)addr, dump_size); + dyn_size =3D dump_size - rem; + + perf_output_skip(handle, rem); + + /* Dynamic size. */ + perf_output_put(handle, dyn_size); + } +} + static unsigned long perf_prepare_sample_aux(struct perf_event *event, struct perf_sample_data *data, size_t size) @@ -7474,6 +7550,13 @@ void perf_output_sample(struct perf_output_handle *h= andle, if (sample_type & PERF_SAMPLE_CODE_PAGE_SIZE) perf_output_put(handle, data->code_page_size); =20 + if (sample_type & PERF_SAMPLE_TLS_USER) { + perf_output_sample_utls(handle, + data->tls_addr, + data->tls_user_size, + data->regs_user.regs); + } + if (sample_type & PERF_SAMPLE_AUX) { perf_output_put(handle, data->aux_size); =20 @@ -7759,6 +7842,19 @@ void perf_prepare_sample(struct perf_sample_data *da= ta, data->sample_flags |=3D PERF_SAMPLE_STACK_USER; } =20 + if (filtered_sample_type & PERF_SAMPLE_TLS_USER) { + u16 tls_size =3D event->attr.sample_tls_user; + u64 task_size =3D perf_utls_task_size(data->regs_user.regs, + tls_size, + &data->tls_addr); + + tls_size =3D perf_prepare_dump_data(data, event, regs, + tls_size, task_size); + + data->tls_user_size =3D tls_size; + data->sample_flags |=3D PERF_SAMPLE_TLS_USER; + } + if (filtered_sample_type & PERF_SAMPLE_WEIGHT_TYPE) { data->weight.full =3D 0; data->sample_flags |=3D PERF_SAMPLE_WEIGHT_TYPE; @@ -12159,7 +12255,7 @@ static int perf_copy_attr(struct perf_event_attr __= user *uattr, =20 attr->size =3D size; =20 - if (attr->__reserved_1 || attr->__reserved_2 || attr->__reserved_3) + if (attr->__reserved_1 || attr->__reserved_3) return -EINVAL; =20 if (attr->sample_type & ~(PERF_SAMPLE_MAX-1)) @@ -12225,6 +12321,13 @@ static int perf_copy_attr(struct perf_event_attr _= _user *uattr, return -EINVAL; } =20 + if (attr->sample_type & PERF_SAMPLE_TLS_USER) { + if (!arch_perf_have_user_tls_dump()) + return -ENOSYS; + else if (!IS_ALIGNED(attr->sample_tls_user, sizeof(u64))) + return -EINVAL; + } + if (!attr->sample_max_stack) attr->sample_max_stack =3D sysctl_perf_event_max_stack; =20 diff --git a/kernel/events/internal.h b/kernel/events/internal.h index 5150d5f84c03..b42747b1eb04 100644 --- a/kernel/events/internal.h +++ b/kernel/events/internal.h @@ -243,4 +243,20 @@ static inline bool arch_perf_have_user_stack_dump(void) #define perf_user_stack_pointer(regs) 0 #endif /* CONFIG_HAVE_PERF_USER_STACK_DUMP */ =20 +#ifdef CONFIG_HAVE_PERF_USER_TLS_DUMP +static inline bool arch_perf_have_user_tls_dump(void) +{ + return true; +} + +#define perf_user_tls_pointer(tls) arch_perf_user_tls_pointer(tls) +#else +static inline bool arch_perf_have_user_tls_dump(void) +{ + return false; +} + +#define perf_user_tls_pointer(tls) memset(tls, 0, sizeof(*tls)) +#endif /* CONFIG_HAVE_PERF_USER_TLS_DUMP */ + #endif /* _KERNEL_EVENTS_INTERNAL_H */ --=20 2.34.1 From nobody Sun Feb 8 15:59:26 2026 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id ECC5036C; Fri, 12 Apr 2024 00:17:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712881072; cv=none; b=MAGFfNK6AqOshpk/B0SHANbvZtmq3JceTwfYzLy4eKScjxSIix08IQZG8pzShTYQ/oj4hVTjpH3xEAiI0msuK7/WpR6uIeyBSwA7YTx8STTET2lUAC5sQ1notSXuCStNakT1ogz8vSs6iqR1lhkz2y3jnTzkrJrdT6bv9X5KG/A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712881072; c=relaxed/simple; bh=50OZ7JlsHKGdWRWX51fnAYktmg1ytZjQKr9Ej9/1m/k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rKNgtWFSq9CPjk3Y0juLQLHIgTGlHDYAYxDh4SMGSWmuNEd+jDi1maXsEZasDIt0A/uMaoAgC3mkkRt1lyFTpaMK06W+sLfHfAjCd0TMBPTn0TeJp34R7Y37Aa41XjcIF4DIT7PVjJWaQDKUA3BoHzfEmQgOBEOqD0j7hIeTRp4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=gxbzRCXd; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="gxbzRCXd" Received: from localhost.localdomain (unknown [4.155.48.125]) by linux.microsoft.com (Postfix) with ESMTPSA id 8EAF620EC32A; Thu, 11 Apr 2024 17:17:50 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 8EAF620EC32A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1712881070; bh=Zf+HTFpj8I9//v34h6ZpxRqKnTpj+6KrGfJr8S0wU4M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gxbzRCXdxkh7guY72Vjlr4GXwwDz/oDF8Eatxa7mIohHFZCqOF9dasRz5CahhOdqi a+8VRDzXhA0FsgyMBsGIknlRahgQwf0bnfrLiLb8atgrXcjG3UXDNxjEPaNZAjBDLK /zJyh+x1chEATmdXUDtzUh9r2iSb+YAUi/o+IBYI= From: Beau Belgrave To: peterz@infradead.org, mingo@redhat.com, acme@kernel.org, namhyung@kernel.org, rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com Cc: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mark.rutland@arm.com, alexander.shishkin@linux.intel.com, jolsa@kernel.org, irogers@google.com, adrian.hunter@intel.com, primiano@google.com, aahringo@redhat.com, dcook@linux.microsoft.com Subject: [RFC PATCH 3/4] perf/core: Factor perf_output_sample_udump() Date: Fri, 12 Apr 2024 00:17:31 +0000 Message-Id: <20240412001732.475-4-beaub@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412001732.475-1-beaub@linux.microsoft.com> References: <20240412001732.475-1-beaub@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" We now have two user dump sources (stack and tls). Both are doing the same logic to ensure the user dump ABI output is properly handled. The only difference is one gets the address within the method, and the other is passed the address. Add perf_output_sample_udump() and utilize it for both stack and tls sample dumps. The sp register is now fetched outside of this method and passed to it. This allows both stack and tls to utilize the same code. Signed-off-by: Beau Belgrave --- kernel/events/core.c | 68 +++++++++++++------------------------------- 1 file changed, 19 insertions(+), 49 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index f848bf4be9bd..6b3cf5afdd32 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6998,47 +6998,10 @@ perf_sample_dump_size(u16 dump_size, u16 header_siz= e, u64 task_size) } =20 static void -perf_output_sample_ustack(struct perf_output_handle *handle, u64 dump_size, - struct pt_regs *regs) -{ - /* Case of a kernel thread, nothing to dump */ - if (!regs) { - u64 size =3D 0; - perf_output_put(handle, size); - } else { - unsigned long sp; - unsigned int rem; - u64 dyn_size; - - /* - * We dump: - * static size - * - the size requested by user or the best one we can fit - * in to the sample max size - * data - * - user stack dump data - * dynamic size - * - the actual dumped size - */ - - /* Static size. */ - perf_output_put(handle, dump_size); - - /* Data. */ - sp =3D perf_user_stack_pointer(regs); - rem =3D __output_copy_user(handle, (void *) sp, dump_size); - dyn_size =3D dump_size - rem; - - perf_output_skip(handle, rem); - - /* Dynamic size. */ - perf_output_put(handle, dyn_size); - } -} - -static void -perf_output_sample_utls(struct perf_output_handle *handle, u64 addr, - u64 dump_size, struct pt_regs *regs) +perf_output_sample_udump(struct perf_output_handle *handle, + unsigned long addr, + u64 dump_size, + struct pt_regs *regs) { /* Case of a kernel thread, nothing to dump */ if (!regs) { @@ -7054,7 +7017,7 @@ perf_output_sample_utls(struct perf_output_handle *ha= ndle, u64 addr, * - the size requested by user or the best one we can fit * in to the sample max size * data - * - user tls dump data + * - user dump data * dynamic size * - the actual dumped size */ @@ -7507,9 +7470,16 @@ void perf_output_sample(struct perf_output_handle *h= andle, } =20 if (sample_type & PERF_SAMPLE_STACK_USER) { - perf_output_sample_ustack(handle, - data->stack_user_size, - data->regs_user.regs); + struct pt_regs *regs =3D data->regs_user.regs; + unsigned long sp =3D 0; + + if (regs) + sp =3D perf_user_stack_pointer(regs); + + perf_output_sample_udump(handle, + sp, + data->stack_user_size, + regs); } =20 if (sample_type & PERF_SAMPLE_WEIGHT_TYPE) @@ -7551,10 +7521,10 @@ void perf_output_sample(struct perf_output_handle *= handle, perf_output_put(handle, data->code_page_size); =20 if (sample_type & PERF_SAMPLE_TLS_USER) { - perf_output_sample_utls(handle, - data->tls_addr, - data->tls_user_size, - data->regs_user.regs); + perf_output_sample_udump(handle, + data->tls_addr, + data->tls_user_size, + data->regs_user.regs); } =20 if (sample_type & PERF_SAMPLE_AUX) { --=20 2.34.1 From nobody Sun Feb 8 15:59:26 2026 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1CB0C635; Fri, 12 Apr 2024 00:17:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712881072; cv=none; b=TeymST36GxKPudpYV1b5dG6ItMPIf18jJl9eRkgjEKD3dbpMGKyoMVKjAeE8upFxCdFtpDSR05ka9OdMeO/0VbhesWWirJg/FiZ1yL36dVY+4mut3TuDvxYEWR6cKfKgWzOUj/EJsARklWXqm4+aa/NzxWz3FxW/lViyYbJbdo8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712881072; c=relaxed/simple; bh=fv6XGHb6Pnhi1qBITnZVPVYufjPcayV7v5fU19yiQ/U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KmPAScDn7ED4/ZioRW8Lm6ZkEQjivLAACHmlR7QYHbLExBh+Pd41BQyUIhR5qpvr6Cw/qu9snaNUnl6GsEw58cDFrStgB0nkxGzrPNk8i4hKph55MIYuoFinckcvqPbhf3SqFEOf6OhmcAFJkzJsTEyW/uEtcQM8FgJUDhu7PK0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=J1y1zYHa; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="J1y1zYHa" Received: from localhost.localdomain (unknown [4.155.48.125]) by linux.microsoft.com (Postfix) with ESMTPSA id AB65920EC32E; Thu, 11 Apr 2024 17:17:50 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com AB65920EC32E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1712881070; bh=SwITDiVDGjFy3sgpbd7fUst/YZztJdWrz5P1Xp8PliE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J1y1zYHalt+p0FSBl1FqKBKyTGUXK3M4VFLVLO5wheOrmxQftG+6sWc8eK42fLyIU F0r7lfL56lv1+qeqYtdfsaVTJTGWEmgYeyurv1SNzJ7qcsopEMeuAKpzjQ1LbVIZOX 5DKZ96qyI8RJTj8sXl/LfQfDR8TZo6UOBZ+qbD6g= From: Beau Belgrave To: peterz@infradead.org, mingo@redhat.com, acme@kernel.org, namhyung@kernel.org, rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com Cc: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mark.rutland@arm.com, alexander.shishkin@linux.intel.com, jolsa@kernel.org, irogers@google.com, adrian.hunter@intel.com, primiano@google.com, aahringo@redhat.com, dcook@linux.microsoft.com Subject: [RFC PATCH 4/4] perf/x86/core: Add tls dump support Date: Fri, 12 Apr 2024 00:17:32 +0000 Message-Id: <20240412001732.475-5-beaub@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412001732.475-1-beaub@linux.microsoft.com> References: <20240412001732.475-1-beaub@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that perf supports TLS dumps, x86-64 can provide the details for how to get TLS data for user threads. Enable HAVE_PERF_USER_TLS_DUMP Kconfig only for x86-64. I do not have access to x86 to validate 32-bit. Utilize mmap_is_ia32() to determine 32/64 bit threads. Use fsbase for 64-bit and gsbase for 32-bit with appropriate size. Signed-off-by: Beau Belgrave --- arch/x86/Kconfig | 1 + arch/x86/events/core.c | 14 ++++++++++++++ arch/x86/include/asm/perf_event.h | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 4fff6ed46e90..8d46ec8ded0c 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -263,6 +263,7 @@ config X86 select HAVE_PCI select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP + select HAVE_PERF_USER_TLS_DUMP if X86_64 select MMU_GATHER_RCU_TABLE_FREE if PARAVIRT select MMU_GATHER_MERGE_VMAS select HAVE_POSIX_CPU_TIMERS_TASK_WORK diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 09050641ce5d..3f851db4c591 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -41,6 +41,7 @@ #include #include #include +#include =20 #include "perf_event.h" =20 @@ -3002,3 +3003,16 @@ u64 perf_get_hw_event_config(int hw_event) return 0; } EXPORT_SYMBOL_GPL(perf_get_hw_event_config); + +#ifdef CONFIG_X86_64 +void arch_perf_user_tls_pointer(struct perf_tls *tls) +{ + if (!mmap_is_ia32()) { + tls->base =3D current->thread.fsbase; + tls->size =3D sizeof(u64); + } else { + tls->base =3D current->thread.gsbase; + tls->size =3D sizeof(u32); + } +} +#endif diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_= event.h index 3736b8a46c04..d0f65e572c20 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -628,4 +628,9 @@ static __always_inline void perf_lopwr_cb(bool lopwr_in) =20 #define arch_perf_out_copy_user copy_from_user_nmi =20 +#ifdef CONFIG_HAVE_PERF_USER_TLS_DUMP +struct perf_tls; +extern void arch_perf_user_tls_pointer(struct perf_tls *tls); +#endif + #endif /* _ASM_X86_PERF_EVENT_H */ --=20 2.34.1