1*4882a593SmuzhiyunFrom 65180976c9963432d166b47a0b692260a69c0d47 Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Qingming Su <qingming.su@windriver.com>
3*4882a593SmuzhiyunDate: Tue, 19 Aug 2014 05:16:17 -0400
4*4882a593SmuzhiyunSubject: [PATCH] lmbench: Can't proceed on some targets
5*4882a593Smuzhiyun
6*4882a593Smuzhiyunlmbench can't proceed on some targets.  The memory check fails because the
7*4882a593Smuzhiyunmemory latency of each page is longer then 10us, which is a time limit set
8*4882a593Smuzhiyunin the original memsize.c.
9*4882a593Smuzhiyun
10*4882a593SmuzhiyunThe memory latency is very different on different targets due to the
11*4882a593Smuzhiyunhardware and current system load.  The targets with slower memory
12*4882a593Smuzhiyunchips or heavy system load need much longer time to read or write
13*4882a593Smuzhiyunthe memory.
14*4882a593Smuzhiyun
15*4882a593SmuzhiyunThis fix changes the fixed time limit of 10us to a specific value calculated
16*4882a593Smuzhiyunfrom the runtime target.
17*4882a593Smuzhiyun
18*4882a593SmuzhiyunAlso set an upper limit of memory size used for lmbench testing.  The memory
19*4882a593Smuzhiyuncheck sometimes fails if the target has a large amount of memory, for
20*4882a593Smuzhiyunexample more than 4G.
21*4882a593Smuzhiyun
22*4882a593SmuzhiyunSigned-off-by: Qingming Su <qingming.su@windriver.com>
23*4882a593SmuzhiyunSigned-off-by: Fupan Li <fupan.li@windriver.com>
24*4882a593Smuzhiyun
25*4882a593SmuzhiyunAdd and reword above comments
26*4882a593Smuzhiyun
27*4882a593SmuzhiyunUpstream-status: inappropriate [ configuration ]
28*4882a593Smuzhiyun
29*4882a593SmuzhiyunSigned-off-by: Mark Hatle <mark.hatle@windriver.com>
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun---
32*4882a593Smuzhiyun scripts/config-run | 12 +++++++---
33*4882a593Smuzhiyun src/Makefile       |  4 ++--
34*4882a593Smuzhiyun src/memsize.c      | 66 +++++++++++++++++++++++++++++++++++-------------------
35*4882a593Smuzhiyun 3 files changed, 54 insertions(+), 28 deletions(-)
36*4882a593Smuzhiyun
37*4882a593Smuzhiyundiff --git a/scripts/config-run b/scripts/config-run
38*4882a593Smuzhiyunindex 918cbdf..096ed12 100755
39*4882a593Smuzhiyun--- a/scripts/config-run
40*4882a593Smuzhiyun+++ b/scripts/config-run
41*4882a593Smuzhiyun@@ -197,6 +197,12 @@ The bigger the range, the more accurate the results, but larger sizes
42*4882a593Smuzhiyun take somewhat longer to run the benchmark.
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun EOF
45*4882a593Smuzhiyun+
46*4882a593Smuzhiyun+# By default, use 512M memory as the upper limit for lmbench test
47*4882a593Smuzhiyun+if [ $MB -gt 512 ];then
48*4882a593Smuzhiyun+MB=512
49*4882a593Smuzhiyun+fi
50*4882a593Smuzhiyun+
51*4882a593Smuzhiyun echo $ECHON "MB [default $MB]: $ECHOC"
52*4882a593Smuzhiyun read TMP
53*4882a593Smuzhiyun if [ X$TMP != X ]
54*4882a593Smuzhiyun@@ -687,10 +693,10 @@ case $MAIL in
55*4882a593Smuzhiyun 		;;
56*4882a593Smuzhiyun esac
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun-INFO=`../scripts/info`
59*4882a593Smuzhiyun+INFO=`../scripts/hostinfo`
60*4882a593Smuzhiyun if [ $MAIL = yes ]
61*4882a593Smuzhiyun then	if [ ! -f $INFO ]
62*4882a593Smuzhiyun-	then	cp ../scripts/info-template $INFO
63*4882a593Smuzhiyun+	then	cp ../scripts/hostinfo-template $INFO
64*4882a593Smuzhiyun 		chmod +w $INFO
65*4882a593Smuzhiyun 		REUSE=no
66*4882a593Smuzhiyun 	else
67*4882a593Smuzhiyun@@ -733,7 +739,7 @@ EOF
68*4882a593Smuzhiyun 		then	EDITOR=$TMP
69*4882a593Smuzhiyun 		fi
70*4882a593Smuzhiyun 		if [ X$EDITOR != "none" ]
71*4882a593Smuzhiyun-		then	$EDITOR `../scripts/info`
72*4882a593Smuzhiyun+		then	$EDITOR `../scripts/hostinfo`
73*4882a593Smuzhiyun 		fi
74*4882a593Smuzhiyun 	fi
75*4882a593Smuzhiyun fi
76*4882a593Smuzhiyundiff --git a/src/Makefile b/src/Makefile
77*4882a593Smuzhiyunindex c7e4e3c..d9efd54 100644
78*4882a593Smuzhiyun--- a/src/Makefile
79*4882a593Smuzhiyun+++ b/src/Makefile
80*4882a593Smuzhiyun@@ -50,7 +50,7 @@ TARGET=`../scripts/target`
81*4882a593Smuzhiyun BINDIR=../bin/$(OS)
82*4882a593Smuzhiyun CONFIG=../bin/$(OS)/`../scripts/config`
83*4882a593Smuzhiyun UTILS=../scripts/target ../scripts/os ../scripts/gnu-os ../scripts/compiler \
84*4882a593Smuzhiyun-	../scripts/info ../scripts/info-template ../scripts/version \
85*4882a593Smuzhiyun+	../scripts/hostinfo ../scripts/hostinfo-template ../scripts/version \
86*4882a593Smuzhiyun 	../scripts/config ../scripts/config-run ../scripts/results \
87*4882a593Smuzhiyun 	../scripts/lmbench ../scripts/make ../scripts/build
88*4882a593Smuzhiyun INSTALL=cp
89*4882a593Smuzhiyun@@ -240,7 +240,7 @@ $O/getopt.o : getopt.c $(INCS)
90*4882a593Smuzhiyun 	$(COMPILE) -c getopt.c -o $O/getopt.o
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun $(UTILS) :
93*4882a593Smuzhiyun-	-cd ../scripts; make get
94*4882a593Smuzhiyun+	-cd ../scripts; cp info hostinfo; cp info-template hostinfo-template
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun # Do not remove the next line, $(MAKE) depend needs it
97*4882a593Smuzhiyun # MAKEDEPEND follows
98*4882a593Smuzhiyundiff --git a/src/memsize.c b/src/memsize.c
99*4882a593Smuzhiyunindex eb25a09..82d7faf 100644
100*4882a593Smuzhiyun--- a/src/memsize.c
101*4882a593Smuzhiyun+++ b/src/memsize.c
102*4882a593Smuzhiyun@@ -14,9 +14,12 @@ char	*id = "$Id$\n";
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun #define	CHK(x)	if ((x) == -1) { perror("x"); exit(1); }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun-#ifndef	TOO_LONG
107*4882a593Smuzhiyun-#define	TOO_LONG	10	/* usecs */
108*4882a593Smuzhiyun-#endif
109*4882a593Smuzhiyun+//#ifndef	TOO_LONG
110*4882a593Smuzhiyun+//#define	TOO_LONG	10	/* usecs */
111*4882a593Smuzhiyun+//#endif
112*4882a593Smuzhiyun+
113*4882a593Smuzhiyun+#define	MEMORY_SIZE_1MB (1024 * 1024)
114*4882a593Smuzhiyun+#define	MEMORY_SIZE_8MB (8 * 1024 * 1024)
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun int	alarm_triggered = 0;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun@@ -35,10 +38,10 @@ main(int ac, char **av)
119*4882a593Smuzhiyun 	size_t	delta;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun 	if (ac == 2) {
122*4882a593Smuzhiyun-		max = size = bytes(av[1]) * 1024 * 1024;
123*4882a593Smuzhiyun+		max = size = bytes(av[1]) * MEMORY_SIZE_1MB;
124*4882a593Smuzhiyun 	}
125*4882a593Smuzhiyun-	if (max < 1024 * 1024) {
126*4882a593Smuzhiyun-		max = size = 1024 * 1024 * 1024;
127*4882a593Smuzhiyun+	if (max < MEMORY_SIZE_1MB) {
128*4882a593Smuzhiyun+		max = size = 1024 * MEMORY_SIZE_1MB;
129*4882a593Smuzhiyun 	}
130*4882a593Smuzhiyun 	/*
131*4882a593Smuzhiyun 	 * Binary search down and then binary search up
132*4882a593Smuzhiyun@@ -48,7 +51,7 @@ main(int ac, char **av)
133*4882a593Smuzhiyun 	}
134*4882a593Smuzhiyun 	/* delta = size / (2 * 1024 * 1024) */
135*4882a593Smuzhiyun 	for (delta = (size >> 21); delta > 0; delta >>= 1) {
136*4882a593Smuzhiyun-		uint64 sz = (uint64)size + (uint64)delta * 1024 * 1024;
137*4882a593Smuzhiyun+		uint64 sz = (uint64)size + (uint64)delta * MEMORY_SIZE_1MB;
138*4882a593Smuzhiyun 		size_t check = sz;
139*4882a593Smuzhiyun 		if (max < sz) continue;
140*4882a593Smuzhiyun 		if (check < sz || !test_malloc(sz)) break;
141*4882a593Smuzhiyun@@ -66,41 +69,58 @@ timeit(char *where, size_t size)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun 	int	sum = 0;
144*4882a593Smuzhiyun 	size_t	n;
145*4882a593Smuzhiyun-	size_t	s_prev;
146*4882a593Smuzhiyun+	size_t	s_prev = MEMORY_SIZE_8MB;
147*4882a593Smuzhiyun 	size_t	range;
148*4882a593Smuzhiyun-	size_t	incr = 1024 * 1024;
149*4882a593Smuzhiyun+	size_t	incr = MEMORY_SIZE_1MB;
150*4882a593Smuzhiyun 	size_t	pagesize = getpagesize();
151*4882a593Smuzhiyun-	unsigned long long	s;
152*4882a593Smuzhiyun-
153*4882a593Smuzhiyun-	if (size < 1024*1024 - 16*1024) {
154*4882a593Smuzhiyun-		fprintf(stderr, "Bad size\n");
155*4882a593Smuzhiyun-		return;
156*4882a593Smuzhiyun-	}
157*4882a593Smuzhiyun+	size_t	time_each_page = 0;
158*4882a593Smuzhiyun+	size_t	too_long = 0;
159*4882a593Smuzhiyun+	unsigned long long      s;
160*4882a593Smuzhiyun+
161*4882a593Smuzhiyun+	if (pagesize < MEMORY_SIZE_1MB)
162*4882a593Smuzhiyun+		range = MEMORY_SIZE_1MB;
163*4882a593Smuzhiyun+	else
164*4882a593Smuzhiyun+		range = MEMORY_SIZE_8MB;
165*4882a593Smuzhiyun+
166*4882a593Smuzhiyun+	incr = MEMORY_SIZE_1MB;
167*4882a593Smuzhiyun+
168*4882a593Smuzhiyun+	if (size < range) {
169*4882a593Smuzhiyun+              fprintf(stderr, "Bad size\n");
170*4882a593Smuzhiyun+              return;
171*4882a593Smuzhiyun+	    }
172*4882a593Smuzhiyun+
173*4882a593Smuzhiyun+	//Touch range of memory, get the average time (usec) of operating each memory page on this system
174*4882a593Smuzhiyun+        start(0);
175*4882a593Smuzhiyun+        touchRange(where, range, pagesize);
176*4882a593Smuzhiyun+        sum = stop(0, 0);
177*4882a593Smuzhiyun+
178*4882a593Smuzhiyun+        if ((time_each_page = sum * pagesize / range) < 1)
179*4882a593Smuzhiyun+		time_each_page = 1;
180*4882a593Smuzhiyun+	//Set the uper limit of time spending on one page
181*4882a593Smuzhiyun+        too_long = 10 * time_each_page;
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun-	range = 1024 * 1024;
184*4882a593Smuzhiyun-	incr = 1024 * 1024;
185*4882a593Smuzhiyun-	touchRange(where, range, pagesize);
186*4882a593Smuzhiyun 	for (range += incr; range <= size; range += incr) {
187*4882a593Smuzhiyun 		n = range / pagesize;
188*4882a593Smuzhiyun-		set_alarm(n * TOO_LONG);
189*4882a593Smuzhiyun+		set_alarm(n * too_long);
190*4882a593Smuzhiyun 		touchRange(where + range - incr, incr, pagesize);
191*4882a593Smuzhiyun 		clear_alarm();
192*4882a593Smuzhiyun-		set_alarm(n * TOO_LONG);
193*4882a593Smuzhiyun+		set_alarm(n * too_long);
194*4882a593Smuzhiyun 		start(0);
195*4882a593Smuzhiyun 		touchRange(where, range, pagesize);
196*4882a593Smuzhiyun 		sum = stop(0, 0);
197*4882a593Smuzhiyun 		clear_alarm();
198*4882a593Smuzhiyun-		if ((sum / n) > TOO_LONG || alarm_triggered) {
199*4882a593Smuzhiyun+		if ((sum / n) > too_long || alarm_triggered) {
200*4882a593Smuzhiyun 			size = range - incr;
201*4882a593Smuzhiyun+			fprintf(stderr, "Error! Memory testing timeout! Touch one page of memory needs more than %d (usecs)\n ", too_long);
202*4882a593Smuzhiyun 			break;
203*4882a593Smuzhiyun 		}
204*4882a593Smuzhiyun-		for (s = 8 * 1024 * 1024; s <= range; s_prev = s, s *= 2)
205*4882a593Smuzhiyun+		for (s = s_prev; s <= range; s_prev = s, s *= 2)
206*4882a593Smuzhiyun 			if (s < s_prev) break;
207*4882a593Smuzhiyun 		incr = s / 8;
208*4882a593Smuzhiyun 		if (range < size && size < range + incr) {
209*4882a593Smuzhiyun 			incr = size - range;
210*4882a593Smuzhiyun 		}
211*4882a593Smuzhiyun-		fprintf(stderr, "%dMB OK\r", (int)(range/(1024*1024)));
212*4882a593Smuzhiyun+		fprintf(stderr, "%dMB OK\r", (int)(range/MEMORY_SIZE_1MB));
213*4882a593Smuzhiyun 	}
214*4882a593Smuzhiyun 	fprintf(stderr, "\n");
215*4882a593Smuzhiyun 	printf("%d\n", (int)(size>>20));
216