* + tools-mm-make-gup_bench-a-benchmark-only-tool.patch added to mm-new branch
@ 2026-09-06 0:32 Andrew Morton
0 siblings, 0 replies; only message in thread
From: Andrew Morton @ 2026-09-06 0:32 UTC (permalink / raw)
To: mm-commits, sarthak.sharma, akpm
The patch titled
Subject: tools/mm: make gup_bench a benchmark only tool
has been added to the -mm mm-new branch. Its filename is
tools-mm-make-gup_bench-a-benchmark-only-tool.patch
This patch will shortly appear at
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/tools-mm-make-gup_bench-a-benchmark-only-tool.patch
This patch will later appear in the mm-new branch at
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Note, mm-new is a provisional staging ground for work-in-progress
patches, and acceptance into mm-new is a notification for others take
notice and to finish up reviews. Please do not hesitate to respond to
review feedback and post updated versions to replace or incrementally
fixup patches in mm-new.
The mm-new branch of mm.git is not included in linux-next
If a few days of testing in mm-new is successful, the patch will me moved
into mm.git's mm-unstable branch, which is included in linux-next
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next via various
branches at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there most days
------------------------------------------------------
From: Sarthak Sharma <sarthak.sharma@arm.com>
Subject: tools/mm: make gup_bench a benchmark only tool
Date: Fri, 4 Sep 2026 18:06:30 +0530
Remove the functional modes (GUP_BASIC_TEST, PIN_BASIC_TEST and
DUMP_USER_PAGES_TEST) from gup_bench. Drop the kselftest dependency and
use normal diagnostics and exit statuses.
When no arguments are supplied, run a single GUP_FAST_BENCHMARK with the
existing default values. Let users select other configurations through
command-line options. Report ioctl failures and handle errors without
relying on assert().
Link: https://lore.kernel.org/20260904123631.198697-6-sarthak.sharma@arm.com
Signed-off-by: Sarthak Sharma <sarthak.sharma@arm.com>
Suggested-by: David Hildenbrand (Arm) <david@kernel.org>
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Nico Pache <npache@redhat.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Zi Yan <ziy@nvidia.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
tools/mm/gup_bench.c | 184 +++++++++++++++++------------------------
1 file changed, 79 insertions(+), 105 deletions(-)
--- a/tools/mm/gup_bench.c~tools-mm-make-gup_bench-a-benchmark-only-tool
+++ a/tools/mm/gup_bench.c
@@ -10,10 +10,10 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <pthread.h>
-#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
#include <mm/gup_test.h>
#include <mm/hugepage_settings.h>
-#include "../testing/selftests/kselftest.h"
#define MB (1UL << 20)
@@ -37,12 +37,6 @@ static char *cmd_to_str(unsigned long cm
return "PIN_FAST_BENCHMARK";
case PIN_LONGTERM_BENCHMARK:
return "PIN_LONGTERM_BENCHMARK";
- case GUP_BASIC_TEST:
- return "GUP_BASIC_TEST";
- case PIN_BASIC_TEST:
- return "PIN_BASIC_TEST";
- case DUMP_USER_PAGES_TEST:
- return "DUMP_USER_PAGES_TEST";
}
return "Unknown command";
}
@@ -52,39 +46,29 @@ void *gup_thread(void *data)
struct gup_test gup = *(struct gup_test *)data;
int i, status;
- /* Only report timing information on the *_BENCHMARK commands: */
- if ((cmd == PIN_FAST_BENCHMARK) || (cmd == GUP_FAST_BENCHMARK) ||
- (cmd == PIN_LONGTERM_BENCHMARK)) {
- for (i = 0; i < repeats; i++) {
- gup.size = size;
- status = ioctl(gup_fd, cmd, &gup);
- if (status)
- break;
+ for (i = 0; i < repeats; i++) {
+ gup.size = size;
+ status = ioctl(gup_fd, cmd, &gup);
+ if (status) {
+ int err = errno;
pthread_mutex_lock(&print_mutex);
- ksft_print_msg("%s: Time: get:%lld put:%lld us",
- cmd_to_str(cmd), gup.get_delta_usec,
- gup.put_delta_usec);
- if (gup.size != size)
- ksft_print_msg(", truncated (size: %lld)", gup.size);
- ksft_print_msg("\n");
+ fprintf(stderr, "%s ioctl failed: %s\n", cmd_to_str(cmd),
+ strerror(err));
pthread_mutex_unlock(&print_mutex);
+ return data;
}
- } else {
- gup.size = size;
- status = ioctl(gup_fd, cmd, &gup);
- if (status)
- goto return_;
pthread_mutex_lock(&print_mutex);
- ksft_print_msg("%s: done\n", cmd_to_str(cmd));
+ printf("%s: Time: get:%lld put:%lld us",
+ cmd_to_str(cmd), gup.get_delta_usec,
+ gup.put_delta_usec);
if (gup.size != size)
- ksft_print_msg("Truncated (size: %lld)\n", gup.size);
+ printf(", truncated (size: %lld)", gup.size);
+ printf("\n");
pthread_mutex_unlock(&print_mutex);
}
-return_:
- ksft_test_result(!status, "ioctl status %d\n", status);
return NULL;
}
@@ -92,38 +76,21 @@ int main(int argc, char **argv)
{
struct gup_test gup = { 0 };
int filed, i, opt, nr_pages = 1, thp = -1, write = 1, nthreads = 1, ret;
- int flags = MAP_PRIVATE;
+ int flags = MAP_PRIVATE, started_threads = 0, exit_status = 1;
char *file = "/dev/zero";
- bool hugetlb = false;
+ bool hugetlb = false, thread_error = false;
+ void *thread_result;
pthread_t *tid;
char *p;
- while ((opt = getopt(argc, argv, "m:r:n:F:f:abcj:tTLUuwWSHpz")) != -1) {
+ while ((opt = getopt(argc, argv, "m:r:n:F:f:aj:tTLuwWSH")) != -1) {
switch (opt) {
case 'a':
cmd = PIN_FAST_BENCHMARK;
break;
- case 'b':
- cmd = PIN_BASIC_TEST;
- break;
case 'L':
cmd = PIN_LONGTERM_BENCHMARK;
break;
- case 'c':
- cmd = DUMP_USER_PAGES_TEST;
- /*
- * Dump page 0 (index 1). May be overridden later, by
- * user's non-option arguments.
- *
- * .which_pages is zero-based, so that zero can mean "do
- * nothing".
- */
- gup.which_pages[0] = 1;
- break;
- case 'p':
- /* works only with DUMP_USER_PAGES_TEST */
- gup.test_flags |= GUP_TEST_FLAG_DUMP_PAGES_USE_PIN;
- break;
case 'F':
/* strtol, so you can pass flags in hex form */
gup.gup_flags = strtol(optarg, 0, 0);
@@ -148,9 +115,6 @@ int main(int argc, char **argv)
case 'T':
thp = 0;
break;
- case 'U':
- cmd = GUP_BASIC_TEST;
- break;
case 'u':
cmd = GUP_FAST_BENCHMARK;
break;
@@ -172,52 +136,41 @@ int main(int argc, char **argv)
hugetlb = true;
break;
default:
- ksft_exit_fail_msg("Wrong argument\n");
+ fprintf(stderr, "Wrong argument\n");
+ exit(1);
}
}
- if (optind < argc) {
- int extra_arg_count = 0;
- /*
- * For example:
- *
- * ./gup_test -c 0 1 0x1001
- *
- * ...to dump pages 0, 1, and 4097
- */
-
- while ((optind < argc) &&
- (extra_arg_count < GUP_TEST_MAX_PAGES_TO_DUMP)) {
- /*
- * Do the 1-based indexing here, so that the user can
- * use normal 0-based indexing on the command line.
- */
- long page_index = strtol(argv[optind], 0, 0) + 1;
-
- gup.which_pages[extra_arg_count] = page_index;
- extra_arg_count++;
- optind++;
- }
+ if (optind != argc) {
+ fprintf(stderr, "Unexpected argument '%s'\n", argv[optind]);
+ exit(1);
}
- ksft_print_header();
+ if (getuid()) {
+ fprintf(stderr, "Please run this test as root\n");
+ exit(1);
+ }
if (hugetlb) {
unsigned long hp_size = default_huge_page_size();
- if (!hp_size)
- ksft_exit_skip("HugeTLB is unavailable\n");
+ if (!hp_size) {
+ fprintf(stderr, "Could not determine huge page size\n");
+ return 1;
+ }
size = (size + hp_size - 1) & ~(hp_size - 1);
- if (!hugetlb_setup_default(size / hp_size))
- ksft_exit_skip("Not enough huge pages\n");
+ if (!hugetlb_setup_default(size / hp_size)) {
+ fprintf(stderr, "Not enough huge pages\n");
+ return 1;
+ }
}
- ksft_set_plan(nthreads);
-
filed = open(file, O_RDWR|O_CREAT, 0664);
- if (filed < 0)
- ksft_exit_fail_msg("Unable to open %s: %s\n", file, strerror(errno));
+ if (filed < 0) {
+ fprintf(stderr, "Unable to open %s: %s\n", file, strerror(errno));
+ return 1;
+ }
gup.nr_pages_per_call = nr_pages;
if (write)
@@ -226,26 +179,24 @@ int main(int argc, char **argv)
gup_fd = open(GUP_TEST_FILE, O_RDWR);
if (gup_fd == -1) {
switch (errno) {
- case EACCES:
- if (getuid())
- ksft_print_msg("Please run this test as root\n");
- break;
case ENOENT:
if (opendir("/sys/kernel/debug") == NULL)
- ksft_print_msg("mount debugfs at /sys/kernel/debug\n");
- ksft_print_msg("check if CONFIG_GUP_TEST is enabled in kernel config\n");
+ fprintf(stderr, "mount debugfs at /sys/kernel/debug\n");
+ fprintf(stderr, "check if CONFIG_GUP_TEST is enabled in kernel config\n");
break;
default:
- ksft_print_msg("failed to open %s: %s\n", GUP_TEST_FILE, strerror(errno));
+ fprintf(stderr, "failed to open %s: %s\n", GUP_TEST_FILE,
+ strerror(errno));
break;
}
- ksft_test_result_skip("Please run this test as root\n");
- ksft_exit_pass();
+ goto err_close_filed;
}
p = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, filed, 0);
- if (p == MAP_FAILED)
- ksft_exit_fail_msg("mmap: %s\n", strerror(errno));
+ if (p == MAP_FAILED) {
+ fprintf(stderr, "mmap: %s\n", strerror(errno));
+ goto err_close_gup_fd;
+ }
gup.addr = (unsigned long)p;
if (thp == 1)
@@ -258,17 +209,40 @@ int main(int argc, char **argv)
p[0] = 0;
tid = malloc(sizeof(pthread_t) * nthreads);
- assert(tid);
+ if (!tid) {
+ fprintf(stderr, "Failed to allocate %d threads: %s\n",
+ nthreads, strerror(errno));
+ goto err_unmap;
+ }
+
for (i = 0; i < nthreads; i++) {
ret = pthread_create(&tid[i], NULL, gup_thread, &gup);
- assert(ret == 0);
+ if (ret) {
+ fprintf(stderr, "pthread_create failed: %s\n", strerror(ret));
+ thread_error = true;
+ break;
+ }
+ started_threads++;
}
- for (i = 0; i < nthreads; i++) {
- ret = pthread_join(tid[i], NULL);
- assert(ret == 0);
+ for (i = 0; i < started_threads; i++) {
+ ret = pthread_join(tid[i], &thread_result);
+ if (ret) {
+ fprintf(stderr, "pthread_join failed: %s\n", strerror(ret));
+ thread_error = true;
+ } else if (thread_result)
+ thread_error = true;
}
free(tid);
-
- ksft_exit_pass();
+ if (thread_error)
+ goto err_unmap;
+ exit_status = 0;
+
+err_unmap:
+ munmap((void *)gup.addr, size);
+err_close_gup_fd:
+ close(gup_fd);
+err_close_filed:
+ close(filed);
+ return exit_status;
}
_
Patches currently in -mm which might be from sarthak.sharma@arm.com are
mm-gup_test-report-actual-pinned-bytes.patch
selftests-mm-make-file-helpers-return-errors.patch
tools-lib-mm-add-shared-file-helpers.patch
tools-lib-mm-move-hugepage_settings-out-of-selftests.patch
tools-mm-move-gup_test-from-selftests-mm-to-tools-mm.patch
tools-mm-make-gup_bench-a-benchmark-only-tool.patch
selftests-mm-add-a-gup-selftest.patch
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-06 0:32 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-06 0:32 + tools-mm-make-gup_bench-a-benchmark-only-tool.patch added to mm-new branch Andrew Morton
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.