162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * fill_buf benchmark 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2018 Intel Corporation 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Authors: 862306a36Sopenharmony_ci * Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>, 962306a36Sopenharmony_ci * Fenghua Yu <fenghua.yu@intel.com> 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci#include <stdio.h> 1262306a36Sopenharmony_ci#include <unistd.h> 1362306a36Sopenharmony_ci#include <stdlib.h> 1462306a36Sopenharmony_ci#include <sys/types.h> 1562306a36Sopenharmony_ci#include <sys/wait.h> 1662306a36Sopenharmony_ci#include <inttypes.h> 1762306a36Sopenharmony_ci#include <string.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include "resctrl.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define CL_SIZE (64) 2262306a36Sopenharmony_ci#define PAGE_SIZE (4 * 1024) 2362306a36Sopenharmony_ci#define MB (1024 * 1024) 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistatic void sb(void) 2662306a36Sopenharmony_ci{ 2762306a36Sopenharmony_ci#if defined(__i386) || defined(__x86_64) 2862306a36Sopenharmony_ci asm volatile("sfence\n\t" 2962306a36Sopenharmony_ci : : : "memory"); 3062306a36Sopenharmony_ci#endif 3162306a36Sopenharmony_ci} 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cistatic void cl_flush(void *p) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci#if defined(__i386) || defined(__x86_64) 3662306a36Sopenharmony_ci asm volatile("clflush (%0)\n\t" 3762306a36Sopenharmony_ci : : "r"(p) : "memory"); 3862306a36Sopenharmony_ci#endif 3962306a36Sopenharmony_ci} 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistatic void mem_flush(unsigned char *buf, size_t buf_size) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci unsigned char *cp = buf; 4462306a36Sopenharmony_ci size_t i = 0; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci buf_size = buf_size / CL_SIZE; /* mem size in cache lines */ 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci for (i = 0; i < buf_size; i++) 4962306a36Sopenharmony_ci cl_flush(&cp[i * CL_SIZE]); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci sb(); 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistatic void *malloc_and_init_memory(size_t buf_size) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci void *p = NULL; 5762306a36Sopenharmony_ci uint64_t *p64; 5862306a36Sopenharmony_ci size_t s64; 5962306a36Sopenharmony_ci int ret; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci ret = posix_memalign(&p, PAGE_SIZE, buf_size); 6262306a36Sopenharmony_ci if (ret < 0) 6362306a36Sopenharmony_ci return NULL; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci p64 = (uint64_t *)p; 6662306a36Sopenharmony_ci s64 = buf_size / sizeof(uint64_t); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci while (s64 > 0) { 6962306a36Sopenharmony_ci *p64 = (uint64_t)rand(); 7062306a36Sopenharmony_ci p64 += (CL_SIZE / sizeof(uint64_t)); 7162306a36Sopenharmony_ci s64 -= (CL_SIZE / sizeof(uint64_t)); 7262306a36Sopenharmony_ci } 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci return p; 7562306a36Sopenharmony_ci} 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic int fill_one_span_read(unsigned char *buf, size_t buf_size) 7862306a36Sopenharmony_ci{ 7962306a36Sopenharmony_ci unsigned char *end_ptr = buf + buf_size; 8062306a36Sopenharmony_ci unsigned char sum, *p; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci sum = 0; 8362306a36Sopenharmony_ci p = buf; 8462306a36Sopenharmony_ci while (p < end_ptr) { 8562306a36Sopenharmony_ci sum += *p; 8662306a36Sopenharmony_ci p += (CL_SIZE / 2); 8762306a36Sopenharmony_ci } 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci return sum; 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cistatic void fill_one_span_write(unsigned char *buf, size_t buf_size) 9362306a36Sopenharmony_ci{ 9462306a36Sopenharmony_ci unsigned char *end_ptr = buf + buf_size; 9562306a36Sopenharmony_ci unsigned char *p; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci p = buf; 9862306a36Sopenharmony_ci while (p < end_ptr) { 9962306a36Sopenharmony_ci *p = '1'; 10062306a36Sopenharmony_ci p += (CL_SIZE / 2); 10162306a36Sopenharmony_ci } 10262306a36Sopenharmony_ci} 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistatic int fill_cache_read(unsigned char *buf, size_t buf_size, bool once) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci int ret = 0; 10762306a36Sopenharmony_ci FILE *fp; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci while (1) { 11062306a36Sopenharmony_ci ret = fill_one_span_read(buf, buf_size); 11162306a36Sopenharmony_ci if (once) 11262306a36Sopenharmony_ci break; 11362306a36Sopenharmony_ci } 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci /* Consume read result so that reading memory is not optimized out. */ 11662306a36Sopenharmony_ci fp = fopen("/dev/null", "w"); 11762306a36Sopenharmony_ci if (!fp) { 11862306a36Sopenharmony_ci perror("Unable to write to /dev/null"); 11962306a36Sopenharmony_ci return -1; 12062306a36Sopenharmony_ci } 12162306a36Sopenharmony_ci fprintf(fp, "Sum: %d ", ret); 12262306a36Sopenharmony_ci fclose(fp); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci return 0; 12562306a36Sopenharmony_ci} 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cistatic int fill_cache_write(unsigned char *buf, size_t buf_size, bool once) 12862306a36Sopenharmony_ci{ 12962306a36Sopenharmony_ci while (1) { 13062306a36Sopenharmony_ci fill_one_span_write(buf, buf_size); 13162306a36Sopenharmony_ci if (once) 13262306a36Sopenharmony_ci break; 13362306a36Sopenharmony_ci } 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci return 0; 13662306a36Sopenharmony_ci} 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_cistatic int fill_cache(size_t buf_size, int memflush, int op, bool once) 13962306a36Sopenharmony_ci{ 14062306a36Sopenharmony_ci unsigned char *buf; 14162306a36Sopenharmony_ci int ret; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci buf = malloc_and_init_memory(buf_size); 14462306a36Sopenharmony_ci if (!buf) 14562306a36Sopenharmony_ci return -1; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci /* Flush the memory before using to avoid "cache hot pages" effect */ 14862306a36Sopenharmony_ci if (memflush) 14962306a36Sopenharmony_ci mem_flush(buf, buf_size); 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci if (op == 0) 15262306a36Sopenharmony_ci ret = fill_cache_read(buf, buf_size, once); 15362306a36Sopenharmony_ci else 15462306a36Sopenharmony_ci ret = fill_cache_write(buf, buf_size, once); 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci free(buf); 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci if (ret) { 15962306a36Sopenharmony_ci printf("\n Error in fill cache read/write...\n"); 16062306a36Sopenharmony_ci return -1; 16162306a36Sopenharmony_ci } 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci return 0; 16562306a36Sopenharmony_ci} 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ciint run_fill_buf(size_t span, int memflush, int op, bool once) 16862306a36Sopenharmony_ci{ 16962306a36Sopenharmony_ci size_t cache_size = span; 17062306a36Sopenharmony_ci int ret; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci ret = fill_cache(cache_size, memflush, op, once); 17362306a36Sopenharmony_ci if (ret) { 17462306a36Sopenharmony_ci printf("\n Error in fill cache\n"); 17562306a36Sopenharmony_ci return -1; 17662306a36Sopenharmony_ci } 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci return 0; 17962306a36Sopenharmony_ci} 180