blob: 811640d0b687d7b17cfa1a54cabe1d60d98c9df7 [file] [log] [blame]
nstraz5dc95292002-01-09 15:32:22 +00001From linux-kernel-owner@vger.kernel.org Tue Jan 8 20:59:05 2002
2Message-Id: <200201090245.g092jnt02235@mysql.sashanet.com>
3Content-Type: text/plain;
4 charset="us-ascii"
5From: Sasha Pachev <sasha@mysql.com>
6Organization: MySQL
7To: linux-kernel@vger.kernel.org
8Subject: Test case for cache leak in 2.17.2-rc2
9Date: Tue, 8 Jan 2002 19:45:49 -0700
10X-Mailer: KMail [version 1.3.1]
11MIME-Version: 1.0
12Content-Transfer-Encoding: 8bit
13Sender: linux-kernel-owner@vger.kernel.org
14Precedence: bulk
15X-Mailing-List: linux-kernel@vger.kernel.org
16Status: RO
17Content-Length: 3887
18
19The following test program demonstrates incorrect cache shrinking logic in
202.17.2-rc2 with 0 swap. I suspect the same problem will happen if swap is not
21zero but is filled up. I have not noticed anything relevant in the changelogs
22between my version and 2.4.18-pre2, so I assume the bug is still there. It
23would be nice if somebody could verify it.
24
25First the code:
26
27-------------------start---------------------
28#include <stdio.h>
29#include <stdlib.h>
30#include <signal.h>
31#include <unistd.h>
32
33#define BLOCK_SIZE 1024
34
35int done_hog_cache=0;
36int done_hog_free=0;
37int go_pipe[2];
38pid_t child_pid=0;
39
40void stop_hog_cache()
41{
42 done_hog_cache=1;
43}
44
45void stop_hog_free()
46{
47 done_hog_free=1;
48}
49
50void stop_all()
51{
52 done_hog_free=done_hog_cache=1;
53 if (child_pid>0)
54 kill(child_pid,SIGHUP);
55}
56
57void hog_free(int blocks)
58{
59 char* buf;
60 char go_buf[2];
61
62 signal(SIGHUP,stop_hog_free);
63 signal(SIGTERM,stop_hog_free);
64 printf("Hogging free mem, to stop, do kill -HUP %d in another terminal\n",
65 getpid());
66 read(go_pipe[0],go_buf,2);
67 if (!(buf=(char*)malloc(blocks*BLOCK_SIZE)))
68 {
69 fprintf(stderr,"malloc() failed\n");
70 exit(1);
71 }
72 memset(buf,0xff,blocks*BLOCK_SIZE);
73 while (!done_hog_free)
74 {
75 sleep(1);
76 }
77}
78
79void hog_cache(int blocks)
80{
81 FILE* fp;
82 char buf[BLOCK_SIZE];
83 const char* hog_file="/tmp/hog-file";
84 int i;
85
86 memset(buf,0xff,sizeof(buf));
87 if (!(fp=fopen(hog_file,"w+")))
88 {
89 fprintf(stderr,"Could not open crash file\n");
90 exit(1);
91 }
92 signal(SIGHUP,stop_hog_cache);
93 signal(SIGTERM,stop_hog_free);
94 printf("Hogging disk cache, to stop, do kill -HUP %d in another terminal\n",
95 getpid());
96 for (i=0;i<blocks;i++)
97 {
98 fwrite(buf,1,sizeof(buf),fp);
99 }
100 fflush(fp);
101 write(go_pipe[1],"go",2);
102 while (!done_hog_cache)
103 {
104 fseek(fp,0L,SEEK_SET);
105 for (i=0;i<blocks;i++)
106 {
107 fread(buf,1,sizeof(buf),fp);
108 }
109 }
110
111 fclose(fp);
112 unlink(hog_file);
113 printf("Finished cleanup of disk cache hog\n");
114}
115
116int main(int argc,char** argv)
117{
118 int cache_blocks,free_blocks;
119 if (argc<3)
120 {
121 fprintf(stderr,"Usage: ./crash-kernel cache_blocks free_blocks\n");
122 exit(1);
123 }
124 cache_blocks=atoi(argv[1]);
125 free_blocks=atoi(argv[2]);
126 if (pipe(go_pipe) == -1)
127 {
128 fprintf(stderr,"could not create pipe\n");
129 exit(1);
130 }
131 signal(SIGINT,stop_all);
132 switch ((child_pid=fork()))
133 {
134 case 0: hog_cache(cache_blocks); break;
135 case -1:
136 fprintf(stderr, "cannot fork\n");
137 exit(1);
138 default: hog_free(free_blocks); break;
139 }
140}
141-----------------end------
142
143To see the problem, ./crash-kernel cache_blocks free_blocks
144
145set cache_blocks to eat up all of your physical RAM + swap, and free_blocks
146to some sigficant amount, but less than what is actually available before you
147run the test.
148
149As you can see from the source, crash-kernel first tries to bloat the cache
150by creating a large file, and then tries to keep it bloated by reading the
151file data in a loop. As soon as the file is created, the other fork tries to
152allocate and initialize a chunk of memory, and then goes to sleep.
153
154The correct behaviour would be, of course, to shrink the bloated cache and
155give memory from it. But what happens on 2.4.17-rc2 is that the memory thread
156gets killed instead.
157
158Please CC me on replies as I do not subsribe to the list...
159
160--
161MySQL Development Team
162For technical support contracts, visit https://order.mysql.com/
163 __ ___ ___ ____ __
164 / |/ /_ __/ __/ __ \/ / Sasha Pachev <sasha@mysql.com>
165 / /|_/ / // /\ \/ /_/ / /__ MySQL AB, http://www.mysql.com/
166/_/ /_/\_, /___/\___\_\___/ Provo, Utah, USA
167 <___/
168-
169To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
170the body of a message to majordomo@vger.kernel.org
171More majordomo info at http://vger.kernel.org/majordomo-info.html
172Please read the FAQ at http://www.tux.org/lkml/
173
174