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 unsigned char *startptr;
26a2561b12SSai Praneeth Prakhya 
27a2561b12SSai Praneeth Prakhya static void sb(void)
28a2561b12SSai Praneeth Prakhya {
29a2561b12SSai Praneeth Prakhya #if defined(__i386) || defined(__x86_64)
30a2561b12SSai Praneeth Prakhya 	asm volatile("sfence\n\t"
31a2561b12SSai Praneeth Prakhya 		     : : : "memory");
32a2561b12SSai Praneeth Prakhya #endif
33a2561b12SSai Praneeth Prakhya }
34a2561b12SSai Praneeth Prakhya 
35a2561b12SSai Praneeth Prakhya static void ctrl_handler(int signo)
36a2561b12SSai Praneeth Prakhya {
37a2561b12SSai Praneeth Prakhya 	free(startptr);
38a2561b12SSai Praneeth Prakhya 	printf("\nEnding\n");
39a2561b12SSai Praneeth Prakhya 	sb();
40a2561b12SSai Praneeth Prakhya 	exit(EXIT_SUCCESS);
41a2561b12SSai Praneeth Prakhya }
42a2561b12SSai Praneeth Prakhya 
43a2561b12SSai Praneeth Prakhya static void cl_flush(void *p)
44a2561b12SSai Praneeth Prakhya {
45a2561b12SSai Praneeth Prakhya #if defined(__i386) || defined(__x86_64)
46a2561b12SSai Praneeth Prakhya 	asm volatile("clflush (%0)\n\t"
47a2561b12SSai Praneeth Prakhya 		     : : "r"(p) : "memory");
48a2561b12SSai Praneeth Prakhya #endif
49a2561b12SSai Praneeth Prakhya }
50a2561b12SSai Praneeth Prakhya 
51a2561b12SSai Praneeth Prakhya static void mem_flush(void *p, size_t s)
52a2561b12SSai Praneeth Prakhya {
53a2561b12SSai Praneeth Prakhya 	char *cp = (char *)p;
54a2561b12SSai Praneeth Prakhya 	size_t i = 0;
55a2561b12SSai Praneeth Prakhya 
56a2561b12SSai Praneeth Prakhya 	s = s / CL_SIZE; /* mem size in cache llines */
57a2561b12SSai Praneeth Prakhya 
58a2561b12SSai Praneeth Prakhya 	for (i = 0; i < s; i++)
59a2561b12SSai Praneeth Prakhya 		cl_flush(&cp[i * CL_SIZE]);
60a2561b12SSai Praneeth Prakhya 
61a2561b12SSai Praneeth Prakhya 	sb();
62a2561b12SSai Praneeth Prakhya }
63a2561b12SSai Praneeth Prakhya 
64a2561b12SSai Praneeth Prakhya static void *malloc_and_init_memory(size_t s)
65a2561b12SSai Praneeth Prakhya {
66*5d869d7bSIlpo Järvinen 	void *p = NULL;
67a2561b12SSai Praneeth Prakhya 	uint64_t *p64;
68a2561b12SSai Praneeth Prakhya 	size_t s64;
69*5d869d7bSIlpo Järvinen 	int ret;
70a2561b12SSai Praneeth Prakhya 
71*5d869d7bSIlpo Järvinen 	ret = posix_memalign(&p, PAGE_SIZE, s);
72*5d869d7bSIlpo Järvinen 	if (ret < 0)
7322a8be28SIlpo Järvinen 		return NULL;
74a2561b12SSai Praneeth Prakhya 
75a2561b12SSai Praneeth Prakhya 	p64 = (uint64_t *)p;
76a2561b12SSai Praneeth Prakhya 	s64 = s / sizeof(uint64_t);
77a2561b12SSai Praneeth Prakhya 
78a2561b12SSai Praneeth Prakhya 	while (s64 > 0) {
79a2561b12SSai Praneeth Prakhya 		*p64 = (uint64_t)rand();
80a2561b12SSai Praneeth Prakhya 		p64 += (CL_SIZE / sizeof(uint64_t));
81a2561b12SSai Praneeth Prakhya 		s64 -= (CL_SIZE / sizeof(uint64_t));
82a2561b12SSai Praneeth Prakhya 	}
83a2561b12SSai Praneeth Prakhya 
84a2561b12SSai Praneeth Prakhya 	return p;
85a2561b12SSai Praneeth Prakhya }
86a2561b12SSai Praneeth Prakhya 
87a2561b12SSai Praneeth Prakhya static int fill_one_span_read(unsigned char *start_ptr, unsigned char *end_ptr)
88a2561b12SSai Praneeth Prakhya {
89a2561b12SSai Praneeth Prakhya 	unsigned char sum, *p;
90a2561b12SSai Praneeth Prakhya 
91a2561b12SSai Praneeth Prakhya 	sum = 0;
92a2561b12SSai Praneeth Prakhya 	p = start_ptr;
93a2561b12SSai Praneeth Prakhya 	while (p < end_ptr) {
94a2561b12SSai Praneeth Prakhya 		sum += *p;
95a2561b12SSai Praneeth Prakhya 		p += (CL_SIZE / 2);
96a2561b12SSai Praneeth Prakhya 	}
97a2561b12SSai Praneeth Prakhya 
98a2561b12SSai Praneeth Prakhya 	return sum;
99a2561b12SSai Praneeth Prakhya }
100a2561b12SSai Praneeth Prakhya 
101a2561b12SSai Praneeth Prakhya static
102a2561b12SSai Praneeth Prakhya void fill_one_span_write(unsigned char *start_ptr, unsigned char *end_ptr)
103a2561b12SSai Praneeth Prakhya {
104a2561b12SSai Praneeth Prakhya 	unsigned char *p;
105a2561b12SSai Praneeth Prakhya 
106a2561b12SSai Praneeth Prakhya 	p = start_ptr;
107a2561b12SSai Praneeth Prakhya 	while (p < end_ptr) {
108a2561b12SSai Praneeth Prakhya 		*p = '1';
109a2561b12SSai Praneeth Prakhya 		p += (CL_SIZE / 2);
110a2561b12SSai Praneeth Prakhya 	}
111a2561b12SSai Praneeth Prakhya }
112a2561b12SSai Praneeth Prakhya 
113a2561b12SSai Praneeth Prakhya static int fill_cache_read(unsigned char *start_ptr, unsigned char *end_ptr,
114a2561b12SSai Praneeth Prakhya 			   char *resctrl_val)
115a2561b12SSai Praneeth Prakhya {
116a2561b12SSai Praneeth Prakhya 	int ret = 0;
117a2561b12SSai Praneeth Prakhya 	FILE *fp;
118a2561b12SSai Praneeth Prakhya 
119790bf585SFenghua Yu 	while (1) {
120a2561b12SSai Praneeth Prakhya 		ret = fill_one_span_read(start_ptr, end_ptr);
12124286736SFenghua Yu 		if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
122790bf585SFenghua Yu 			break;
123790bf585SFenghua Yu 	}
124a2561b12SSai Praneeth Prakhya 
125a2561b12SSai Praneeth Prakhya 	/* Consume read result so that reading memory is not optimized out. */
126a2561b12SSai Praneeth Prakhya 	fp = fopen("/dev/null", "w");
127c7b607faSColin Ian King 	if (!fp) {
128a2561b12SSai Praneeth Prakhya 		perror("Unable to write to /dev/null");
129c7b607faSColin Ian King 		return -1;
130c7b607faSColin Ian King 	}
131a2561b12SSai Praneeth Prakhya 	fprintf(fp, "Sum: %d ", ret);
132a2561b12SSai Praneeth Prakhya 	fclose(fp);
133a2561b12SSai Praneeth Prakhya 
134a2561b12SSai Praneeth Prakhya 	return 0;
135a2561b12SSai Praneeth Prakhya }
136a2561b12SSai Praneeth Prakhya 
137a2561b12SSai Praneeth Prakhya static int fill_cache_write(unsigned char *start_ptr, unsigned char *end_ptr,
138a2561b12SSai Praneeth Prakhya 			    char *resctrl_val)
139a2561b12SSai Praneeth Prakhya {
140790bf585SFenghua Yu 	while (1) {
141a2561b12SSai Praneeth Prakhya 		fill_one_span_write(start_ptr, end_ptr);
14224286736SFenghua Yu 		if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
143790bf585SFenghua Yu 			break;
144790bf585SFenghua Yu 	}
145a2561b12SSai Praneeth Prakhya 
146a2561b12SSai Praneeth Prakhya 	return 0;
147a2561b12SSai Praneeth Prakhya }
148a2561b12SSai Praneeth Prakhya 
149a2561b12SSai Praneeth Prakhya static int
150a2561b12SSai Praneeth Prakhya fill_cache(unsigned long long buf_size, int malloc_and_init, int memflush,
151a2561b12SSai Praneeth Prakhya 	   int op, char *resctrl_val)
152a2561b12SSai Praneeth Prakhya {
153a2561b12SSai Praneeth Prakhya 	unsigned char *start_ptr, *end_ptr;
154a2561b12SSai Praneeth Prakhya 	unsigned long long i;
155a2561b12SSai Praneeth Prakhya 	int ret;
156a2561b12SSai Praneeth Prakhya 
157a2561b12SSai Praneeth Prakhya 	if (malloc_and_init)
158a2561b12SSai Praneeth Prakhya 		start_ptr = malloc_and_init_memory(buf_size);
159a2561b12SSai Praneeth Prakhya 	else
160a2561b12SSai Praneeth Prakhya 		start_ptr = malloc(buf_size);
161a2561b12SSai Praneeth Prakhya 
162a2561b12SSai Praneeth Prakhya 	if (!start_ptr)
163a2561b12SSai Praneeth Prakhya 		return -1;
164a2561b12SSai Praneeth Prakhya 
165a2561b12SSai Praneeth Prakhya 	startptr = start_ptr;
166a2561b12SSai Praneeth Prakhya 	end_ptr = start_ptr + buf_size;
167a2561b12SSai Praneeth Prakhya 
168a2561b12SSai Praneeth Prakhya 	/*
169a2561b12SSai Praneeth Prakhya 	 * It's better to touch the memory once to avoid any compiler
170a2561b12SSai Praneeth Prakhya 	 * optimizations
171a2561b12SSai Praneeth Prakhya 	 */
172a2561b12SSai Praneeth Prakhya 	if (!malloc_and_init) {
173a2561b12SSai Praneeth Prakhya 		for (i = 0; i < buf_size; i++)
174a2561b12SSai Praneeth Prakhya 			*start_ptr++ = (unsigned char)rand();
175a2561b12SSai Praneeth Prakhya 	}
176a2561b12SSai Praneeth Prakhya 
177a2561b12SSai Praneeth Prakhya 	start_ptr = startptr;
178a2561b12SSai Praneeth Prakhya 
179a2561b12SSai Praneeth Prakhya 	/* Flush the memory before using to avoid "cache hot pages" effect */
180a2561b12SSai Praneeth Prakhya 	if (memflush)
181a2561b12SSai Praneeth Prakhya 		mem_flush(start_ptr, buf_size);
182a2561b12SSai Praneeth Prakhya 
183a2561b12SSai Praneeth Prakhya 	if (op == 0)
184a2561b12SSai Praneeth Prakhya 		ret = fill_cache_read(start_ptr, end_ptr, resctrl_val);
185a2561b12SSai Praneeth Prakhya 	else
186a2561b12SSai Praneeth Prakhya 		ret = fill_cache_write(start_ptr, end_ptr, resctrl_val);
187a2561b12SSai Praneeth Prakhya 
188a2561b12SSai Praneeth Prakhya 	if (ret) {
18914f4283aSColin Ian King 		printf("\n Error in fill cache read/write...\n");
190a2561b12SSai Praneeth Prakhya 		return -1;
191a2561b12SSai Praneeth Prakhya 	}
192a2561b12SSai Praneeth Prakhya 
193a2561b12SSai Praneeth Prakhya 	free(startptr);
194a2561b12SSai Praneeth Prakhya 
195a2561b12SSai Praneeth Prakhya 	return 0;
196a2561b12SSai Praneeth Prakhya }
197a2561b12SSai Praneeth Prakhya 
198a2561b12SSai Praneeth Prakhya int run_fill_buf(unsigned long span, int malloc_and_init_memory,
199a2561b12SSai Praneeth Prakhya 		 int memflush, int op, char *resctrl_val)
200a2561b12SSai Praneeth Prakhya {
201a2561b12SSai Praneeth Prakhya 	unsigned long long cache_size = span;
202a2561b12SSai Praneeth Prakhya 	int ret;
203a2561b12SSai Praneeth Prakhya 
204a2561b12SSai Praneeth Prakhya 	/* set up ctrl-c handler */
205a2561b12SSai Praneeth Prakhya 	if (signal(SIGINT, ctrl_handler) == SIG_ERR)
206a2561b12SSai Praneeth Prakhya 		printf("Failed to catch SIGINT!\n");
207a2561b12SSai Praneeth Prakhya 	if (signal(SIGHUP, ctrl_handler) == SIG_ERR)
208a2561b12SSai Praneeth Prakhya 		printf("Failed to catch SIGHUP!\n");
209a2561b12SSai Praneeth Prakhya 
210a2561b12SSai Praneeth Prakhya 	ret = fill_cache(cache_size, malloc_and_init_memory, memflush, op,
211a2561b12SSai Praneeth Prakhya 			 resctrl_val);
212a2561b12SSai Praneeth Prakhya 	if (ret) {
21314f4283aSColin Ian King 		printf("\n Error in fill cache\n");
214a2561b12SSai Praneeth Prakhya 		return -1;
215a2561b12SSai Praneeth Prakhya 	}
216a2561b12SSai Praneeth Prakhya 
217a2561b12SSai Praneeth Prakhya 	return 0;
218a2561b12SSai Praneeth Prakhya }
219