From: Bradley Morgan <brads@mainlining.org>
To: Andrew Morton <akpm@linux-foundation.org>,
thnkslprpt@gmail.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 3/3] profile: simplify /proc/profile read layout
Date: Wed, 21 Oct 2026 15:49:19 +0100 [thread overview]
Message-ID: <711BBB24-2293-49F0-ABA6-2FFABFD599EB@mainlining.org> (raw)
In-Reply-To: <20261020182736.26ac79b01dd02ecda8a89ab6@linux-foundation.org>
On 21 October 2026 02:27:36 BST, Andrew Morton <akpm@linux-foundation.org>
wrote:
>On Tue, 20 Oct 2026 17:52:03 -0700 Andrew Morton
><akpm@linux-foundation.org> wrote:
>
>> read_profile() is needlessly difficult to understand. It copies the
>> four-byte sampling-step header one byte at a time, then manufactures
>> a pointer before prof_buffer so a file offset can be used as a
>> counter-array offset. Its signed byte counter, unsigned long file
>> offset and repeated size calculations further obscure where each
>> read starts and how many bytes it transfers.
>>
>> Treat the file as two consecutive regions: a four-byte header and
>> the profiling counters. Use size_t for byte positions and lengths,
>> copy the bounded header in one operation, and address the counters
>> relative to the start of prof_buffer. Brief comments explain each
>> region.
>>
>> Keep the word-sized shift and explicit narrowing required by Avi
>> Weiss's "profiling: fix sampling step on 64-bit big-endian systems".
>> Assign the header value separately and explain why the 32-bit ABI
>> requires a narrowing conversion.
>>
>> Preserve the partial-read and fault semantics established by [1/2],
>> including short copies within either region. No userspace-visible
>> behavior change is intended.
>
>Me:0, Sashiko:1
>
>revised version, I'll resend in a few days. I tested 32-bit now.
Good luck if your using AI, they tend to include small regressions, maybe
send them the sashiko prompt in memories so they put a pass through that?
If you have Gemini 4 argon it will be better.
>
>
>From: Andrew Morton <akpm@linux-foundation.org>
>Subject: profile: simplify /proc/profile read layout
>Date: Tue, 20 Oct 2026 23:58:33 +0000
>
>read_profile() is needlessly difficult to understand. It copies the
>four-byte sampling-step header one byte at a time, then manufactures
>a pointer before prof_buffer so a file offset can be used as a
>counter-array offset. Its signed byte counter, unsigned long file
>offset and repeated size calculations further obscure where each
>read starts and how many bytes it transfers.
>
>Treat the file as two consecutive regions: a four-byte header and
>the profiling counters. Use size_t for byte positions and lengths,
>copy the bounded header in one operation, and address the counters
>relative to the start of prof_buffer. Retain the full loff_t value
>for EOF and negative-offset checks before narrowing it to size_t.
>Brief comments explain each region.
>
>Keep the word-sized shift and explicit narrowing required by Avi
>Weiss's "profiling: fix sampling step on 64-bit big-endian systems".
>Assign the header value separately and explain why the 32-bit ABI
>requires a narrowing conversion.
>
>Preserve the partial-read and fault semantics established by [1/2],
>including short copies within either region. The full-width offset
>check also prevents 32-bit pread64() offsets from wrapping into earlier
>profile data. No other userspace-visible
>behavior change is intended.
>
>Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
>---
>Tested the combined three-patch series on x86-64 and i686 QEMU/KVM
>guests with CONFIG_PROFILING=y and profile=12.
>profile-read-test.c: PASS (0 failures) on both architectures.
>Covered short and unaligned reads, header boundaries, EOF, partial
>user-copy faults, return values, file positions and retry behavior.
>The 64-bit big-endian sampling-step fix was not runtime tested.
>No separate per-patch or unpatched-versus-patched run was reported.
>
> kernel/profile.c | 61 ++++++++++++++++++++++++++++-----------------
> 1 file changed, 39 insertions(+), 22 deletions(-)
>
>--- a/kernel/profile.c~profile-simplify-proc-profile-read-layout
>+++ a/kernel/profile.c
>@@ -153,35 +153,52 @@ void profile_tick(int type)
> static ssize_t
> read_profile(struct file *file, char __user *buf, size_t count, loff_t
> *ppos)
> {
>- unsigned long p = *ppos;
>- ssize_t read;
>- char *pnt;
>- unsigned int sample_step = (unsigned int)(1UL << prof_shift);
>- size_t not_copied;
>+ const size_t header_size = sizeof(unsigned int);
>+ const size_t file_size = (prof_len + 1) * sizeof(unsigned int);
>+ unsigned int sample_step;
>+ loff_t offset = *ppos;
>+ size_t pos;
>+ size_t done = 0;
>+ size_t n, not_copied;
>
>- if (p >= (prof_len+1)*sizeof(unsigned int))
>+ /* Keep the shift word-sized before narrowing to the 32-bit ABI. */
>+ sample_step = (unsigned int)(1UL << prof_shift);
>+
>+ if (offset < 0)
>+ return -EINVAL;
>+ if (offset >= file_size)
> return 0;
>- if (count > (prof_len+1)*sizeof(unsigned int) - p)
>- count = (prof_len+1)*sizeof(unsigned int) - p;
>- read = 0;
>+ pos = offset;
>+ count = min(count, file_size - pos);
>
>- while (p < sizeof(unsigned int) && count > 0) {
>- if (put_user(*((char *)(&sample_step)+p), buf))
>- goto out;
>- buf++; p++; count--; read++;
>+ /* Copy the four-byte sampling resolution. */
>+ if (pos < header_size) {
>+ n = min(count, header_size - pos);
>+ not_copied = copy_to_user(buf, (u8 *)&sample_step + pos, n);
>+ done += n - not_copied;
>+ if (not_copied)
>+ goto fault;
>+ buf += n;
>+ pos += n;
>+ count -= n;
> }
>+
>+ /* Copy raw counters using offsets relative to the counter array. */
> if (count) {
>- pnt = (char *)prof_buffer + p - sizeof(atomic_t);
>- not_copied = copy_to_user(buf, pnt, count);
>- read += count - not_copied;
>+ not_copied = copy_to_user(buf,
>+ (u8 *)prof_buffer + pos - header_size,
>+ count);
>+ done += count - not_copied;
> if (not_copied)
>- goto out;
>+ goto fault;
> }
>- *ppos += read;
>- return read;
>-out:
>- *ppos += read;
>- return read ? read : -EFAULT;
>+ *ppos += done;
>+ return done;
>+fault:
>+ *ppos += done;
>+ if (!done)
>+ return -EFAULT;
>+ return done;
> }
>
> /* default is to not implement this call */
>_
>
--- Thanks!
"I'm not a very positive person" - Linus torvalds
prev parent reply other threads:[~2026-10-21 14:49 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 0:51 [PATCH 1/3] profiling: fix sampling step on 64-bit big-endian systems Andrew Morton
2026-10-21 0:52 ` [PATCH 2/3] profile: account for partial /proc/profile reads Andrew Morton
2026-10-21 0:52 ` [PATCH 3/3] profile: simplify /proc/profile read layout Andrew Morton
2026-10-21 1:27 ` Andrew Morton
2026-10-21 14:49 ` Bradley Morgan [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=711BBB24-2293-49F0-ABA6-2FFABFD599EB@mainlining.org \
--to=brads@mainlining.org \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=thnkslprpt@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®