mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Gopal Malaviya <gopalmalaviya53@gmail.com>
To: alireza.haddadi@it.uu.se
Cc: jack@suse.cz, willy@infradead.org, akpm@linux-foundation.org,
	vishal.moola@gmail.com, fujunjie1@qq.com,
	roman.gushchin@linux.dev, linux-mm@kvack.org,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	regressions@lists.linux.dev, tracekotae@gmail.com
Subject: Re: [PATCH] mm/filemap: let sequential faults restart mmap readahead
Date: Fri, 13 Nov 2026 06:24:46 +0000	[thread overview]
Message-ID: <20261113062446.193820-1-gopalmalaviya53@gmail.com> (raw)
In-Reply-To: <26E03EC6-F37C-4350-B2A9-1F354217F469@it.uu.se>

On Wed, Nov 11, 2026 at 07:43:54AM +0000, Alireza Haddadi wrote:
> That would be great, thank you. Could you share the short-run test,
> So I can run the same here while working on it?

Sure, it is below. It writes the file (or reuses it with "keep"),
drops it from the page cache with POSIX_FADV_DONTNEED, touches 1% of
its pages through a MAP_PRIVATE mapping and prints the MiB read
(pgpgin in /proc/vmstat) and the major faults for each pattern:

  ./mmap-rand FILE               2600 MiB file, removed at the end
  ./mmap-rand FILE 20480 keep    20 GiB file, kept for the next run

The tables came from the second form in a 3 GiB guest, with
"echo 128 > /sys/block/vda/queue/read_ahead_kb" (or 8192) before each
run. "random 4-page recs" is the short-run case. Like the earlier
tests, the program was written with the help of an AI assistant.

Thanks,
Gopal

---8<--- mmap-rand.c
/*
 * mmap-rand.c: how much does the kernel read from disk for sparse
 * mmap access (random, and fixed stride) on a cold file?
 * Reports disk input (pgpgin from /proc/vmstat) and major faults.
 *
 *   ./mmap-rand FILE        (FILE must not exist; removed at the end)
 *   ./mmap-rand FILE SIZE_MIB keep   (reuse FILE if it exists, keep it)
 */
#define _GNU_SOURCE
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <unistd.h>

#define MIB	(1UL << 20)
static unsigned long SIZE = 2600 * MIB;

static long pgpgin_kib(void)
{
	char name[64];
	long val;
	FILE *f = fopen("/proc/vmstat", "r");

	if (!f)
		err(1, "/proc/vmstat");
	while (fscanf(f, "%63s %ld", name, &val) == 2)
		if (!strcmp(name, "pgpgin")) {
			fclose(f);
			return val;
		}
	errx(1, "no pgpgin");
}

static long majflt(void)
{
	struct rusage ru;

	getrusage(RUSAGE_SELF, &ru);
	return ru.ru_majflt;
}

static void run(const char *path, const char *name, unsigned long stride,
		unsigned long rec)
{
	unsigned long page = sysconf(_SC_PAGESIZE), npages = SIZE / page;
	unsigned long n = npages / 100, i, idx;	/* touch 1% of the pages */
	long in0, mf0;
	volatile char sink;
	char *m;
	int fd;

	fd = open(path, O_RDONLY);
	if (fd < 0)
		err(1, "open");
	if (posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED))
		errx(1, "posix_fadvise");
	m = mmap(NULL, SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
	if (m == MAP_FAILED)
		err(1, "mmap");

	srandom(1);
	in0 = pgpgin_kib();
	mf0 = majflt();
	for (i = 0; i < n; i += rec) {
		unsigned long j;

		idx = stride ? (i * stride) % npages : random() % (npages - rec);
		for (j = 0; j < rec; j++)	/* a record of rec adjacent pages */
			sink = m[(idx + j) * page];
	}
	printf("%-20s %6lu touches %8ld MiB read %6ld major faults\n", name, n,
	       (pgpgin_kib() - in0) / 1024, majflt() - mf0);

	(void)sink;
	munmap(m, SIZE);
	close(fd);
}

int main(int argc, char **argv)
{
	static char buf[MIB];
	unsigned long i;
	int fd;

	if (argc != 2 && argc != 4)
		errx(2, "usage: %s FILE [SIZE_MIB keep]", argv[0]);
	if (argc == 4)
		SIZE = strtoul(argv[2], NULL, 0) * MIB;
	fd = open(argv[1], O_WRONLY | O_CREAT | O_EXCL, 0600);
	if (fd >= 0) {
		memset(buf, 0x5a, sizeof(buf));
		for (i = 0; i < SIZE / MIB; i++)
			if (write(fd, buf, MIB) != (ssize_t)MIB)
				err(1, "write");
		if (fsync(fd))
			err(1, "fsync");
		close(fd);
	} else if (argc != 4) {
		err(1, "create");
	}

	setvbuf(stdout, NULL, _IOLBF, 0);
	run(argv[1], "random", 0, 1);
	run(argv[1], "stride 2053 pages", 2053, 1);
	run(argv[1], "random 2-page recs", 0, 2);
	run(argv[1], "random 4-page recs", 0, 4);
	if (argc != 4)
		unlink(argv[1]);
	return 0;
}

      reply	other threads:[~2026-11-13  6:25 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-09 14:23 Alireza Haddadi via B4 Relay
2026-11-09 17:11 ` Jan Kara
2026-11-09 20:23   ` Alireza Haddadi
2026-11-10 10:37     ` Jan Kara
2026-11-11  4:23 ` Gopal Malaviya
2026-11-11  7:43   ` Alireza Haddadi
2026-11-13  6:24     ` Gopal Malaviya [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=20261113062446.193820-1-gopalmalaviya53@gmail.com \
    --to=gopalmalaviya53@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=alireza.haddadi@it.uu.se \
    --cc=fujunjie1@qq.com \
    --cc=jack@suse.cz \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=regressions@lists.linux.dev \
    --cc=roman.gushchin@linux.dev \
    --cc=tracekotae@gmail.com \
    --cc=vishal.moola@gmail.com \
    --cc=willy@infradead.org \
    /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®