Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf bench mem: Pull out init/fini logic

No functional change.

Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Raghavendra K T <raghavendra.kt@amd.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ankur Arora and committed by
Arnaldo Carvalho de Melo
bdc22a83 dbf5dad1

+81 -34
+71 -32
tools/perf/bench/mem-functions.c
··· 62 62 unsigned int nr_loops; 63 63 }; 64 64 65 + struct bench_mem_info { 66 + const struct function *functions; 67 + int (*do_op)(const struct function *r, struct bench_params *p, 68 + void *src, void *dst, union bench_clock *rt); 69 + const char *const *usage; 70 + bool alloc_src; 71 + }; 72 + 73 + typedef bool (*mem_init_t)(struct bench_mem_info *, struct bench_params *, 74 + void **, void **); 75 + typedef void (*mem_fini_t)(struct bench_mem_info *, struct bench_params *, 76 + void **, void **); 65 77 typedef void *(*memcpy_t)(void *, const void *, size_t); 66 78 typedef void *(*memset_t)(void *, int, size_t); 67 79 68 80 struct function { 69 81 const char *name; 70 82 const char *desc; 71 - union { 72 - memcpy_t memcpy; 73 - memset_t memset; 83 + struct { 84 + mem_init_t init; 85 + mem_fini_t fini; 86 + union { 87 + memcpy_t memcpy; 88 + memset_t memset; 89 + }; 74 90 } fn; 75 91 }; 76 92 ··· 154 138 printf(" %14lf GB/sec\n", x / K / K / K); \ 155 139 } while (0) 156 140 157 - struct bench_mem_info { 158 - const struct function *functions; 159 - union bench_clock (*do_op)(const struct function *r, struct bench_params *p, 160 - void *src, void *dst); 161 - const char *const *usage; 162 - bool alloc_src; 163 - }; 164 - 165 141 static void __bench_mem_function(struct bench_mem_info *info, struct bench_params *p, 166 142 int r_idx) 167 143 { 168 144 const struct function *r = &info->functions[r_idx]; 169 145 double result_bps = 0.0; 170 146 union bench_clock rt = { 0 }; 171 - void *src = NULL, *dst = zalloc(p->size); 147 + void *src = NULL, *dst = NULL; 172 148 173 149 printf("# function '%s' (%s)\n", r->name, r->desc); 174 150 175 - if (dst == NULL) 176 - goto out_alloc_failed; 177 - 178 - if (info->alloc_src) { 179 - src = zalloc(p->size); 180 - if (src == NULL) 181 - goto out_alloc_failed; 182 - } 151 + if (r->fn.init && r->fn.init(info, p, &src, &dst)) 152 + goto out_init_failed; 183 153 184 154 if (bench_format == BENCH_FORMAT_DEFAULT) 185 155 printf("# Copying %s bytes ...\n\n", size_str); 186 156 187 - rt = info->do_op(r, p, src, dst); 157 + if (info->do_op(r, p, src, dst, &rt)) 158 + goto out_test_failed; 188 159 189 160 switch (bench_format) { 190 161 case BENCH_FORMAT_DEFAULT: ··· 197 194 break; 198 195 } 199 196 197 + out_test_failed: 200 198 out_free: 201 - free(src); 202 - free(dst); 199 + if (r->fn.fini) r->fn.fini(info, p, &src, &dst); 203 200 return; 204 - out_alloc_failed: 201 + out_init_failed: 205 202 printf("# Memory allocation failed - maybe size (%s) is too large?\n", size_str); 206 203 goto out_free; 207 204 } ··· 268 265 fn(dst, src, size); 269 266 } 270 267 271 - static union bench_clock do_memcpy(const struct function *r, struct bench_params *p, 272 - void *src, void *dst) 268 + static int do_memcpy(const struct function *r, struct bench_params *p, 269 + void *src, void *dst, union bench_clock *rt) 273 270 { 274 271 union bench_clock start, end; 275 272 memcpy_t fn = r->fn.memcpy; ··· 281 278 fn(dst, src, p->size); 282 279 clock_get(&end); 283 280 284 - return clock_diff(&start, &end); 281 + *rt = clock_diff(&start, &end); 282 + 283 + return 0; 284 + } 285 + 286 + static bool mem_alloc(struct bench_mem_info *info, struct bench_params *p, 287 + void **src, void **dst) 288 + { 289 + bool failed; 290 + 291 + *dst = zalloc(p->size); 292 + failed = *dst == NULL; 293 + 294 + if (info->alloc_src) { 295 + *src = zalloc(p->size); 296 + failed = failed || *src == NULL; 297 + } 298 + 299 + return failed; 300 + } 301 + 302 + static void mem_free(struct bench_mem_info *info __maybe_unused, 303 + struct bench_params *p __maybe_unused, 304 + void **src, void **dst) 305 + { 306 + free(*dst); 307 + free(*src); 308 + 309 + *dst = *src = NULL; 285 310 } 286 311 287 312 struct function memcpy_functions[] = { 288 313 { .name = "default", 289 314 .desc = "Default memcpy() provided by glibc", 315 + .fn.init = mem_alloc, 316 + .fn.fini = mem_free, 290 317 .fn.memcpy = memcpy }, 291 318 292 319 #ifdef HAVE_ARCH_X86_64_SUPPORT 293 - # define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, 320 + # define MEMCPY_FN(_fn, _init, _fini, _name, _desc) \ 321 + {.name = _name, .desc = _desc, .fn.memcpy = _fn, .fn.init = _init, .fn.fini = _fini }, 294 322 # include "mem-memcpy-x86-64-asm-def.h" 295 323 # undef MEMCPY_FN 296 324 #endif ··· 346 312 return bench_mem_common(argc, argv, &info); 347 313 } 348 314 349 - static union bench_clock do_memset(const struct function *r, struct bench_params *p, 350 - void *src __maybe_unused, void *dst) 315 + static int do_memset(const struct function *r, struct bench_params *p, 316 + void *src __maybe_unused, void *dst, union bench_clock *rt) 351 317 { 352 318 union bench_clock start, end; 353 319 memset_t fn = r->fn.memset; ··· 363 329 fn(dst, i, p->size); 364 330 clock_get(&end); 365 331 366 - return clock_diff(&start, &end); 332 + *rt = clock_diff(&start, &end); 333 + 334 + return 0; 367 335 } 368 336 369 337 static const char * const bench_mem_memset_usage[] = { ··· 376 340 static const struct function memset_functions[] = { 377 341 { .name = "default", 378 342 .desc = "Default memset() provided by glibc", 343 + .fn.init = mem_alloc, 344 + .fn.fini = mem_free, 379 345 .fn.memset = memset }, 380 346 381 347 #ifdef HAVE_ARCH_X86_64_SUPPORT 382 - # define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn }, 348 + # define MEMSET_FN(_fn, _init, _fini, _name, _desc) \ 349 + {.name = _name, .desc = _desc, .fn.memset = _fn, .fn.init = _init, .fn.fini = _fini }, 383 350 # include "mem-memset-x86-64-asm-def.h" 384 351 # undef MEMSET_FN 385 352 #endif
+1 -1
tools/perf/bench/mem-memcpy-arch.h
··· 2 2 3 3 #ifdef HAVE_ARCH_X86_64_SUPPORT 4 4 5 - #define MEMCPY_FN(fn, name, desc) \ 5 + #define MEMCPY_FN(fn, init, fini, name, desc) \ 6 6 void *fn(void *, const void *, size_t); 7 7 8 8 #include "mem-memcpy-x86-64-asm-def.h"
+4
tools/perf/bench/mem-memcpy-x86-64-asm-def.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 2 3 3 MEMCPY_FN(memcpy_orig, 4 + mem_alloc, 5 + mem_free, 4 6 "x86-64-unrolled", 5 7 "unrolled memcpy() in arch/x86/lib/memcpy_64.S") 6 8 7 9 MEMCPY_FN(__memcpy, 10 + mem_alloc, 11 + mem_free, 8 12 "x86-64-movsq", 9 13 "movsq-based memcpy() in arch/x86/lib/memcpy_64.S")
+1 -1
tools/perf/bench/mem-memset-arch.h
··· 2 2 3 3 #ifdef HAVE_ARCH_X86_64_SUPPORT 4 4 5 - #define MEMSET_FN(fn, name, desc) \ 5 + #define MEMSET_FN(fn, init, fini, name, desc) \ 6 6 void *fn(void *, int, size_t); 7 7 8 8 #include "mem-memset-x86-64-asm-def.h"
+4
tools/perf/bench/mem-memset-x86-64-asm-def.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 2 3 3 MEMSET_FN(memset_orig, 4 + mem_alloc, 5 + mem_free, 4 6 "x86-64-unrolled", 5 7 "unrolled memset() in arch/x86/lib/memset_64.S") 6 8 7 9 MEMSET_FN(__memset, 10 + mem_alloc, 11 + mem_free, 8 12 "x86-64-stosq", 9 13 "movsq-based memset() in arch/x86/lib/memset_64.S")