]> Git Repo - J-linux.git/blob - tools/testing/selftests/resctrl/fill_buf.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[J-linux.git] / tools / testing / selftests / resctrl / fill_buf.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * fill_buf benchmark
4  *
5  * Copyright (C) 2018 Intel Corporation
6  *
7  * Authors:
8  *    Sai Praneeth Prakhya <[email protected]>,
9  *    Fenghua Yu <[email protected]>
10  */
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <stdlib.h>
14 #include <sys/types.h>
15 #include <sys/wait.h>
16 #include <inttypes.h>
17 #include <string.h>
18
19 #include "resctrl.h"
20
21 #define CL_SIZE                 (64)
22 #define PAGE_SIZE               (4 * 1024)
23 #define MB                      (1024 * 1024)
24
25 static unsigned char *startptr;
26
27 static void sb(void)
28 {
29 #if defined(__i386) || defined(__x86_64)
30         asm volatile("sfence\n\t"
31                      : : : "memory");
32 #endif
33 }
34
35 static void cl_flush(void *p)
36 {
37 #if defined(__i386) || defined(__x86_64)
38         asm volatile("clflush (%0)\n\t"
39                      : : "r"(p) : "memory");
40 #endif
41 }
42
43 static void mem_flush(void *p, size_t s)
44 {
45         char *cp = (char *)p;
46         size_t i = 0;
47
48         s = s / CL_SIZE; /* mem size in cache llines */
49
50         for (i = 0; i < s; i++)
51                 cl_flush(&cp[i * CL_SIZE]);
52
53         sb();
54 }
55
56 static void *malloc_and_init_memory(size_t s)
57 {
58         void *p = NULL;
59         uint64_t *p64;
60         size_t s64;
61         int ret;
62
63         ret = posix_memalign(&p, PAGE_SIZE, s);
64         if (ret < 0)
65                 return NULL;
66
67         p64 = (uint64_t *)p;
68         s64 = s / sizeof(uint64_t);
69
70         while (s64 > 0) {
71                 *p64 = (uint64_t)rand();
72                 p64 += (CL_SIZE / sizeof(uint64_t));
73                 s64 -= (CL_SIZE / sizeof(uint64_t));
74         }
75
76         return p;
77 }
78
79 static int fill_one_span_read(unsigned char *start_ptr, unsigned char *end_ptr)
80 {
81         unsigned char sum, *p;
82
83         sum = 0;
84         p = start_ptr;
85         while (p < end_ptr) {
86                 sum += *p;
87                 p += (CL_SIZE / 2);
88         }
89
90         return sum;
91 }
92
93 static
94 void fill_one_span_write(unsigned char *start_ptr, unsigned char *end_ptr)
95 {
96         unsigned char *p;
97
98         p = start_ptr;
99         while (p < end_ptr) {
100                 *p = '1';
101                 p += (CL_SIZE / 2);
102         }
103 }
104
105 static int fill_cache_read(unsigned char *start_ptr, unsigned char *end_ptr,
106                            char *resctrl_val)
107 {
108         int ret = 0;
109         FILE *fp;
110
111         while (1) {
112                 ret = fill_one_span_read(start_ptr, end_ptr);
113                 if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
114                         break;
115         }
116
117         /* Consume read result so that reading memory is not optimized out. */
118         fp = fopen("/dev/null", "w");
119         if (!fp) {
120                 perror("Unable to write to /dev/null");
121                 return -1;
122         }
123         fprintf(fp, "Sum: %d ", ret);
124         fclose(fp);
125
126         return 0;
127 }
128
129 static int fill_cache_write(unsigned char *start_ptr, unsigned char *end_ptr,
130                             char *resctrl_val)
131 {
132         while (1) {
133                 fill_one_span_write(start_ptr, end_ptr);
134                 if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
135                         break;
136         }
137
138         return 0;
139 }
140
141 static int
142 fill_cache(unsigned long long buf_size, int malloc_and_init, int memflush,
143            int op, char *resctrl_val)
144 {
145         unsigned char *start_ptr, *end_ptr;
146         unsigned long long i;
147         int ret;
148
149         if (malloc_and_init)
150                 start_ptr = malloc_and_init_memory(buf_size);
151         else
152                 start_ptr = malloc(buf_size);
153
154         if (!start_ptr)
155                 return -1;
156
157         startptr = start_ptr;
158         end_ptr = start_ptr + buf_size;
159
160         /*
161          * It's better to touch the memory once to avoid any compiler
162          * optimizations
163          */
164         if (!malloc_and_init) {
165                 for (i = 0; i < buf_size; i++)
166                         *start_ptr++ = (unsigned char)rand();
167         }
168
169         start_ptr = startptr;
170
171         /* Flush the memory before using to avoid "cache hot pages" effect */
172         if (memflush)
173                 mem_flush(start_ptr, buf_size);
174
175         if (op == 0)
176                 ret = fill_cache_read(start_ptr, end_ptr, resctrl_val);
177         else
178                 ret = fill_cache_write(start_ptr, end_ptr, resctrl_val);
179
180         if (ret) {
181                 printf("\n Error in fill cache read/write...\n");
182                 return -1;
183         }
184
185         free(startptr);
186
187         return 0;
188 }
189
190 int run_fill_buf(unsigned long span, int malloc_and_init_memory,
191                  int memflush, int op, char *resctrl_val)
192 {
193         unsigned long long cache_size = span;
194         int ret;
195
196         ret = fill_cache(cache_size, malloc_and_init_memory, memflush, op,
197                          resctrl_val);
198         if (ret) {
199                 printf("\n Error in fill cache\n");
200                 return -1;
201         }
202
203         return 0;
204 }
This page took 0.06483 seconds and 4 git commands to generate.