1a2561b12SSai Praneeth Prakhya // SPDX-License-Identifier: GPL-2.0
2a2561b12SSai Praneeth Prakhya /*
3a2561b12SSai Praneeth Prakhya  * fill_buf benchmark
4a2561b12SSai Praneeth Prakhya  *
5a2561b12SSai Praneeth Prakhya  * Copyright (C) 2018 Intel Corporation
6a2561b12SSai Praneeth Prakhya  *
7a2561b12SSai Praneeth Prakhya  * Authors:
8a2561b12SSai Praneeth Prakhya  *    Sai Praneeth Prakhya <[email protected]>,
9a2561b12SSai Praneeth Prakhya  *    Fenghua Yu <[email protected]>
10a2561b12SSai Praneeth Prakhya  */
11a2561b12SSai Praneeth Prakhya #include <stdio.h>
12a2561b12SSai Praneeth Prakhya #include <unistd.h>
13a2561b12SSai Praneeth Prakhya #include <stdlib.h>
14a2561b12SSai Praneeth Prakhya #include <sys/types.h>
15a2561b12SSai Praneeth Prakhya #include <sys/wait.h>
16a2561b12SSai Praneeth Prakhya #include <inttypes.h>
17a2561b12SSai Praneeth Prakhya #include <string.h>
18a2561b12SSai Praneeth Prakhya 
19a2561b12SSai Praneeth Prakhya #include "resctrl.h"
20a2561b12SSai Praneeth Prakhya 
21a2561b12SSai Praneeth Prakhya #define CL_SIZE			(64)
22a2561b12SSai Praneeth Prakhya #define PAGE_SIZE		(4 * 1024)
23a2561b12SSai Praneeth Prakhya #define MB			(1024 * 1024)
24a2561b12SSai Praneeth Prakhya 
25a2561b12SSai Praneeth Prakhya static void sb(void)
26a2561b12SSai Praneeth Prakhya {
27a2561b12SSai Praneeth Prakhya #if defined(__i386) || defined(__x86_64)
28a2561b12SSai Praneeth Prakhya 	asm volatile("sfence\n\t"
29a2561b12SSai Praneeth Prakhya 		     : : : "memory");
30a2561b12SSai Praneeth Prakhya #endif
31a2561b12SSai Praneeth Prakhya }
32a2561b12SSai Praneeth Prakhya 
33a2561b12SSai Praneeth Prakhya static void cl_flush(void *p)
34a2561b12SSai Praneeth Prakhya {
35a2561b12SSai Praneeth Prakhya #if defined(__i386) || defined(__x86_64)
36a2561b12SSai Praneeth Prakhya 	asm volatile("clflush (%0)\n\t"
37a2561b12SSai Praneeth Prakhya 		     : : "r"(p) : "memory");
38a2561b12SSai Praneeth Prakhya #endif
39a2561b12SSai Praneeth Prakhya }
40a2561b12SSai Praneeth Prakhya 
41*f4123975SIlpo Järvinen static void mem_flush(unsigned char *buf, size_t buf_size)
42a2561b12SSai Praneeth Prakhya {
43*f4123975SIlpo Järvinen 	unsigned char *cp = buf;
44a2561b12SSai Praneeth Prakhya 	size_t i = 0;
45a2561b12SSai Praneeth Prakhya 
46*f4123975SIlpo Järvinen 	buf_size = buf_size / CL_SIZE; /* mem size in cache lines */
47a2561b12SSai Praneeth Prakhya 
48*f4123975SIlpo Järvinen 	for (i = 0; i < buf_size; i++)
49a2561b12SSai Praneeth Prakhya 		cl_flush(&cp[i * CL_SIZE]);
50a2561b12SSai Praneeth Prakhya 
51a2561b12SSai Praneeth Prakhya 	sb();
52a2561b12SSai Praneeth Prakhya }
53a2561b12SSai Praneeth Prakhya 
54*f4123975SIlpo Järvinen static void *malloc_and_init_memory(size_t buf_size)
55a2561b12SSai Praneeth Prakhya {
565d869d7bSIlpo Järvinen 	void *p = NULL;
57a2561b12SSai Praneeth Prakhya 	uint64_t *p64;
58a2561b12SSai Praneeth Prakhya 	size_t s64;
595d869d7bSIlpo Järvinen 	int ret;
60a2561b12SSai Praneeth Prakhya 
61*f4123975SIlpo Järvinen 	ret = posix_memalign(&p, PAGE_SIZE, buf_size);
625d869d7bSIlpo Järvinen 	if (ret < 0)
6322a8be28SIlpo Järvinen 		return NULL;
64a2561b12SSai Praneeth Prakhya 
65a2561b12SSai Praneeth Prakhya 	p64 = (uint64_t *)p;
66*f4123975SIlpo Järvinen 	s64 = buf_size / sizeof(uint64_t);
67a2561b12SSai Praneeth Prakhya 
68a2561b12SSai Praneeth Prakhya 	while (s64 > 0) {
69a2561b12SSai Praneeth Prakhya 		*p64 = (uint64_t)rand();
70a2561b12SSai Praneeth Prakhya 		p64 += (CL_SIZE / sizeof(uint64_t));
71a2561b12SSai Praneeth Prakhya 		s64 -= (CL_SIZE / sizeof(uint64_t));
72a2561b12SSai Praneeth Prakhya 	}
73a2561b12SSai Praneeth Prakhya 
74a2561b12SSai Praneeth Prakhya 	return p;
75a2561b12SSai Praneeth Prakhya }
76a2561b12SSai Praneeth Prakhya 
77*f4123975SIlpo Järvinen static int fill_one_span_read(unsigned char *buf, size_t buf_size)
78a2561b12SSai Praneeth Prakhya {
79*f4123975SIlpo Järvinen 	unsigned char *end_ptr = buf + buf_size;
80a2561b12SSai Praneeth Prakhya 	unsigned char sum, *p;
81a2561b12SSai Praneeth Prakhya 
82a2561b12SSai Praneeth Prakhya 	sum = 0;
83*f4123975SIlpo Järvinen 	p = buf;
84a2561b12SSai Praneeth Prakhya 	while (p < end_ptr) {
85a2561b12SSai Praneeth Prakhya 		sum += *p;
86a2561b12SSai Praneeth Prakhya 		p += (CL_SIZE / 2);
87a2561b12SSai Praneeth Prakhya 	}
88a2561b12SSai Praneeth Prakhya 
89a2561b12SSai Praneeth Prakhya 	return sum;
90a2561b12SSai Praneeth Prakhya }
91a2561b12SSai Praneeth Prakhya 
92*f4123975SIlpo Järvinen static void fill_one_span_write(unsigned char *buf, size_t buf_size)
93a2561b12SSai Praneeth Prakhya {
94*f4123975SIlpo Järvinen 	unsigned char *end_ptr = buf + buf_size;
95a2561b12SSai Praneeth Prakhya 	unsigned char *p;
96a2561b12SSai Praneeth Prakhya 
97*f4123975SIlpo Järvinen 	p = buf;
98a2561b12SSai Praneeth Prakhya 	while (p < end_ptr) {
99a2561b12SSai Praneeth Prakhya 		*p = '1';
100a2561b12SSai Praneeth Prakhya 		p += (CL_SIZE / 2);
101a2561b12SSai Praneeth Prakhya 	}
102a2561b12SSai Praneeth Prakhya }
103a2561b12SSai Praneeth Prakhya 
104*f4123975SIlpo Järvinen static int fill_cache_read(unsigned char *buf, size_t buf_size,
105a2561b12SSai Praneeth Prakhya 			   char *resctrl_val)
106a2561b12SSai Praneeth Prakhya {
107a2561b12SSai Praneeth Prakhya 	int ret = 0;
108a2561b12SSai Praneeth Prakhya 	FILE *fp;
109a2561b12SSai Praneeth Prakhya 
110790bf585SFenghua Yu 	while (1) {
111*f4123975SIlpo Järvinen 		ret = fill_one_span_read(buf, buf_size);
11224286736SFenghua Yu 		if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
113790bf585SFenghua Yu 			break;
114790bf585SFenghua Yu 	}
115a2561b12SSai Praneeth Prakhya 
116a2561b12SSai Praneeth Prakhya 	/* Consume read result so that reading memory is not optimized out. */
117a2561b12SSai Praneeth Prakhya 	fp = fopen("/dev/null", "w");
118c7b607faSColin Ian King 	if (!fp) {
119a2561b12SSai Praneeth Prakhya 		perror("Unable to write to /dev/null");
120c7b607faSColin Ian King 		return -1;
121c7b607faSColin Ian King 	}
122a2561b12SSai Praneeth Prakhya 	fprintf(fp, "Sum: %d ", ret);
123a2561b12SSai Praneeth Prakhya 	fclose(fp);
124a2561b12SSai Praneeth Prakhya 
125a2561b12SSai Praneeth Prakhya 	return 0;
126a2561b12SSai Praneeth Prakhya }
127a2561b12SSai Praneeth Prakhya 
128*f4123975SIlpo Järvinen static int fill_cache_write(unsigned char *buf, size_t buf_size,
129a2561b12SSai Praneeth Prakhya 			    char *resctrl_val)
130a2561b12SSai Praneeth Prakhya {
131790bf585SFenghua Yu 	while (1) {
132*f4123975SIlpo Järvinen 		fill_one_span_write(buf, buf_size);
13324286736SFenghua Yu 		if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
134790bf585SFenghua Yu 			break;
135790bf585SFenghua Yu 	}
136a2561b12SSai Praneeth Prakhya 
137a2561b12SSai Praneeth Prakhya 	return 0;
138a2561b12SSai Praneeth Prakhya }
139a2561b12SSai Praneeth Prakhya 
140326baed2SIlpo Järvinen static int fill_cache(size_t buf_size, int memflush, int op, char *resctrl_val)
141a2561b12SSai Praneeth Prakhya {
142*f4123975SIlpo Järvinen 	unsigned char *buf;
143a2561b12SSai Praneeth Prakhya 	int ret;
144a2561b12SSai Praneeth Prakhya 
145*f4123975SIlpo Järvinen 	buf = malloc_and_init_memory(buf_size);
146*f4123975SIlpo Järvinen 	if (!buf)
147a2561b12SSai Praneeth Prakhya 		return -1;
148a2561b12SSai Praneeth Prakhya 
149a2561b12SSai Praneeth Prakhya 	/* Flush the memory before using to avoid "cache hot pages" effect */
150a2561b12SSai Praneeth Prakhya 	if (memflush)
151*f4123975SIlpo Järvinen 		mem_flush(buf, buf_size);
152a2561b12SSai Praneeth Prakhya 
153a2561b12SSai Praneeth Prakhya 	if (op == 0)
154*f4123975SIlpo Järvinen 		ret = fill_cache_read(buf, buf_size, resctrl_val);
155a2561b12SSai Praneeth Prakhya 	else
156*f4123975SIlpo Järvinen 		ret = fill_cache_write(buf, buf_size, resctrl_val);
157a2561b12SSai Praneeth Prakhya 
158*f4123975SIlpo Järvinen 	free(buf);
1592d320b10SIlpo Järvinen 
160a2561b12SSai Praneeth Prakhya 	if (ret) {
16114f4283aSColin Ian King 		printf("\n Error in fill cache read/write...\n");
162a2561b12SSai Praneeth Prakhya 		return -1;
163a2561b12SSai Praneeth Prakhya 	}
164a2561b12SSai Praneeth Prakhya 
165a2561b12SSai Praneeth Prakhya 
166a2561b12SSai Praneeth Prakhya 	return 0;
167a2561b12SSai Praneeth Prakhya }
168a2561b12SSai Praneeth Prakhya 
169326baed2SIlpo Järvinen int run_fill_buf(size_t span, int memflush, int op, char *resctrl_val)
170a2561b12SSai Praneeth Prakhya {
17167a86643SIlpo Järvinen 	size_t cache_size = span;
172a2561b12SSai Praneeth Prakhya 	int ret;
173a2561b12SSai Praneeth Prakhya 
174326baed2SIlpo Järvinen 	ret = fill_cache(cache_size, memflush, op, resctrl_val);
175a2561b12SSai Praneeth Prakhya 	if (ret) {
17614f4283aSColin Ian King 		printf("\n Error in fill cache\n");
177a2561b12SSai Praneeth Prakhya 		return -1;
178a2561b12SSai Praneeth Prakhya 	}
179a2561b12SSai Praneeth Prakhya 
180a2561b12SSai Praneeth Prakhya 	return 0;
181a2561b12SSai Praneeth Prakhya }
182