mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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

      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®