Initial import from FreeBSD RELENG_4:
[dragonfly.git] / share / doc / papers / memfs / 1.t
1 .\" Copyright (c) 1990 The Regents of the University of California.
2 .\" All rights reserved.
3 .\"
4 .\" Redistribution and use in source and binary forms, with or without
5 .\" modification, are permitted provided that the following conditions
6 .\" are met:
7 .\" 1. Redistributions of source code must retain the above copyright
8 .\"    notice, this list of conditions and the following disclaimer.
9 .\" 2. Redistributions in binary form must reproduce the above copyright
10 .\"    notice, this list of conditions and the following disclaimer in the
11 .\"    documentation and/or other materials provided with the distribution.
12 .\" 3. All advertising materials mentioning features or use of this software
13 .\"    must display the following acknowledgement:
14 .\"     This product includes software developed by the University of
15 .\"     California, Berkeley and its contributors.
16 .\" 4. Neither the name of the University nor the names of its contributors
17 .\"    may be used to endorse or promote products derived from this software
18 .\"    without specific prior written permission.
19 .\"
20 .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 .\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 .\" SUCH DAMAGE.
31 .\"
32 .\"     @(#)1.t 5.1 (Berkeley) 4/16/91
33 .\"
34 .nr PS 11
35 .nr VS 13
36 .NH
37 Introduction
38 .PP
39 This paper describes the motivation for and implementation of
40 a memory-based filesystem.
41 Memory-based filesystems have existed for a long time;
42 they have generally been marketed as RAM disks or sometimes
43 as software packages that use the machine's general purpose memory.
44 .[
45 white
46 .]
47 .PP
48 A RAM disk is designed to appear like any other disk peripheral
49 connected to a machine.
50 It is normally interfaced to the processor through the I/O bus
51 and is accessed through a device driver similar or sometimes identical
52 to the device driver used for a normal magnetic disk.
53 The device driver sends requests for blocks of data to the device
54 and the requested data is then DMA'ed to or from the requested block.
55 Instead of storing its data on a rotating magnetic disk,
56 the RAM disk stores its data in a large array of random access memory
57 or bubble memory.
58 Thus, the latency of accessing the RAM disk is nearly zero
59 compared to the 15-50 milliseconds of latency incurred when
60 access rotating magnetic media.
61 RAM disks also have the benefit of being able to transfer data at
62 the maximum DMA rate of the system,
63 while disks are typically limited by the rate that the data passes
64 under the disk head.
65 .PP
66 Software packages simulating RAM disks operate by allocating
67 a fixed partition of the system memory.
68 The software then provides a device driver interface similar
69 to the one described for hardware RAM disks,
70 except that it uses memory-to-memory copy instead of DMA to move
71 the data between the RAM disk and the system buffers,
72 or it maps the contents of the RAM disk into the system buffers.
73 Because the memory used by the RAM disk is not available for
74 other purposes, software RAM-disk solutions are used primarily
75 for machines with limited addressing capabilities such as PC's
76 that do not have an effective way of using the extra memory anyway.
77 .PP
78 Most software RAM disks lose their contents when the system is powered
79 down or rebooted.
80 The contents can be saved by using battery backed-up memory,
81 by storing critical filesystem data structures in the filesystem,
82 and by running a consistency check program after each reboot.
83 These conditions increase the hardware cost
84 and potentially slow down the speed of the disk.
85 Thus, RAM-disk filesystems are not typically
86 designed to survive power failures;
87 because of their volatility, their usefulness is limited to transient
88 or easily recreated information such as might be found in
89 .PN /tmp .
90 Their primary benefit is that they have higher throughput
91 than disk based filesystems.
92 .[
93 smith
94 .]
95 This improved throughput is particularly useful for utilities that
96 make heavy use of temporary files, such as compilers.
97 On fast processors, nearly half of the elapsed time for a compilation
98 is spent waiting for synchronous operations required for file
99 creation and deletion.
100 The use of the memory-based filesystem nearly eliminates this waiting time.
101 .PP
102 Using dedicated memory to exclusively support a RAM disk
103 is a poor use of resources.
104 The overall throughput of the system can be improved
105 by using the memory where it is getting the highest access rate.
106 These needs may shift between supporting process virtual address spaces
107 and caching frequently used disk blocks.
108 If the memory is dedicated to the filesystem,
109 it is better used in a buffer cache.
110 The buffer cache permits faster access to the data
111 because it requires only a single memory-to-memory copy
112 from the kernel to the user process.
113 The use of memory is used in a RAM-disk configuration may require two
114 memory-to-memory copies, one from the RAM disk
115 to the buffer cache,
116 then another copy from the buffer cache to the user process.
117 .PP
118 The new work being presented in this paper is building a prototype
119 RAM-disk filesystem in pageable memory instead of dedicated memory.
120 The goal is to provide the speed benefits of a RAM disk
121 without paying the performance penalty inherent in dedicating
122 part of the physical memory on the machine to the RAM disk.
123 By building the filesystem in pageable memory,
124 it competes with other processes for the available memory.
125 When memory runs short, the paging system pushes its
126 least-recently-used pages to backing store.
127 Being pageable also allows the filesystem to be much larger than
128 would be practical if it were limited by the amount of physical
129 memory that could be dedicated to that purpose.
130 We typically operate our
131 .PN /tmp
132 with 30 to 60 megabytes of space
133 which is larger than the amount of memory on the machine.
134 This configuration allows small files to be accessed quickly,
135 while still allowing
136 .PN /tmp
137 to be used for big files,
138 although at a speed more typical of normal, disk-based filesystems.
139 .PP
140 An alternative to building a memory-based filesystem would be to have
141 a filesystem that never did operations synchronously and never
142 flushed its dirty buffers to disk.
143 However, we believe that such a filesystem would either
144 use a disproportionately large percentage of the buffer
145 cache space, to the detriment of other filesystems,
146 or would require the paging system to flush its dirty pages.
147 Waiting for other filesystems to push dirty pages
148 subjects them to delays while waiting for the pages to be written.
149 We await the results of others trying this approach.
150 .[
151 Ohta
152 .]
153 .NH
154 Implementation
155 .PP
156 The current implementation took less time to write than did this paper.
157 It consists of 560 lines of kernel code (1.7K text + data)
158 and some minor modifications to the program that builds
159 disk based filesystems, \fInewfs\fP.
160 A condensed version of the kernel code for the
161 memory-based filesystem are reproduced in Appendix 1.
162 .PP
163 A filesystem is created by invoking the modified \fInewfs\fP, with
164 an option telling it to create a memory-based filesystem.
165 It allocates a section of virtual address space of the requested
166 size and builds a filesystem in the memory
167 instead of on a disk partition.
168 When built, it does a \fImount\fP system call specifying a filesystem type of
169 .SM MFS
170 (Memory File System).
171 The auxiliary data parameter to the mount call specifies a pointer
172 to the base of the memory in which it has built the filesystem.
173 (The auxiliary data parameter used by the local filesystem, \fIufs\fP,
174 specifies the block device containing the filesystem.)
175 .PP
176 The mount system call allocates and initializes a mount table
177 entry and then calls the filesystem-specific mount routine.
178 The filesystem-specific routine is responsible for doing
179 the mount and initializing the filesystem-specific
180 portion of the mount table entry.
181 The memory-based filesystem-specific mount routine,
182 .RN mfs_mount ,
183 is shown in Appendix 1.
184 It allocates a block-device vnode to represent the memory disk device.
185 In the private area of this vnode it stores the base address of
186 the filesystem and the process identifier of the \fInewfs\fP process
187 for later reference when doing I/O.
188 It also initializes an I/O list that it
189 uses to record outstanding I/O requests.
190 It can then call the \fIufs\fP filesystem mount routine,
191 passing the special block-device vnode that it has created
192 instead of the usual disk block-device vnode.
193 The mount proceeds just as any other local mount, except that
194 requests to read from the block device are vectored through
195 .RN mfs_strategy
196 (described below) instead of the usual
197 .RN spec_strategy
198 block device I/O function.
199 When the mount is completed,
200 .RN mfs_mount
201 does not return as most other filesystem mount functions do;
202 instead it sleeps in the kernel awaiting I/O requests.
203 Each time an I/O request is posted for the filesystem,
204 a wakeup is issued for the corresponding \fInewfs\fP process.
205 When awakened, the process checks for requests on its buffer list.
206 A read request is serviced by copying data from the section of the
207 \fInewfs\fP address space corresponding to the requested disk block
208 to the kernel buffer.
209 Similarly a write request is serviced by copying data to the section of the
210 \fInewfs\fP address space corresponding to the requested disk block
211 from the kernel buffer.
212 When all the requests have been serviced, the \fInewfs\fP
213 process returns to sleep to await more requests.
214 .PP
215 Once mounted,
216 all operations on files in the memory-based filesystem are handled
217 by the \fIufs\fP filesystem code until they get to the point where the
218 filesystem needs to do I/O on the device.
219 Here, the filesystem encounters the second piece of the
220 memory-based filesystem.
221 Instead of calling the special-device strategy routine,
222 it calls the memory-based strategy routine,
223 .RN mfs_strategy .
224 Usually,
225 the request is serviced by linking the buffer onto the
226 I/O list for the memory-based filesystem
227 vnode and sending a wakeup to the \fInewfs\fP process.
228 This wakeup results in a context-switch to the \fInewfs\fP
229 process, which does a copyin or copyout as described above.
230 The strategy routine must be careful to check whether
231 the I/O request is coming from the \fInewfs\fP process itself, however.
232 Such requests happen during mount and unmount operations,
233 when the kernel is reading and writing the superblock.
234 Here,
235 .RN mfs_strategy
236 must do the I/O itself to avoid deadlock.
237 .PP
238 The final piece of kernel code to support the
239 memory-based filesystem is the close routine.
240 After the filesystem has been successfully unmounted,
241 the device close routine is called.
242 For a memory-based filesystem, the device close routine is
243 .RN mfs_close .
244 This routine flushes any pending I/O requests,
245 then sets the I/O list head to a special value
246 that is recognized by the I/O servicing loop in
247 .RN mfs_mount
248 as an indication that the filesystem is unmounted.
249 The
250 .RN mfs_mount
251 routine exits, in turn causing the \fInewfs\fP process
252 to exit, resulting in the filesystem vanishing in a cloud of dirty pages.
253 .PP
254 The paging of the filesystem does not require any additional
255 code beyond that already in the kernel to support virtual memory.
256 The \fInewfs\fP process competes with other processes on an equal basis
257 for the machine's available memory.
258 Data pages of the filesystem that have not yet been used
259 are zero-fill-on-demand pages that do not occupy memory,
260 although they currently allocate space in backing store.
261 As long as memory is plentiful, the entire contents of the filesystem
262 remain memory resident.
263 When memory runs short, the oldest pages of \fInewfs\fP will be
264 pushed to backing store as part of the normal paging activity.
265 The pages that are pushed usually hold the contents of
266 files that have been created in the memory-based filesystem
267 but have not been recently accessed (or have been deleted).
268 .[
269 leffler
270 .]
271 .NH
272 Performance
273 .PP
274 The performance of the current memory-based filesystem is determined by
275 the memory-to-memory copy speed of the processor.
276 Empirically we find that the throughput is about 45% of this
277 memory-to-memory copy speed.
278 The basic set of steps for each block written is:
279 .IP 1)
280 memory-to-memory copy from the user process doing the write to a kernel buffer
281 .IP 2)
282 context-switch to the \fInewfs\fP process
283 .IP 3)
284 memory-to-memory copy from the kernel buffer to the \fInewfs\fP address space
285 .IP 4)
286 context switch back to the writing process
287 .LP
288 Thus each write requires at least two memory-to-memory copies
289 accounting for about 90% of the
290 .SM CPU
291 time.
292 The remaining 10% is consumed in the context switches and
293 the filesystem allocation and block location code.
294 The actual context switch count is really only about half
295 of the worst case outlined above because
296 read-ahead and write-behind allow multiple blocks
297 to be handled with each context switch.
298 .PP
299 On the six-\c
300 .SM "MIPS CCI"
301 Power 6/32 machine,
302 the raw reading and writing speed is only about twice that of
303 a regular disk-based filesystem.
304 However, for processes that create and delete many files,
305 the speedup is considerably greater.
306 The reason for the speedup is that the filesystem
307 must do two synchronous operations to create a file,
308 first writing the allocated inode to disk, then creating the
309 directory entry.
310 Deleting a file similarly requires at least two synchronous
311 operations.
312 Here, the low latency of the memory-based filesystem is
313 noticeable compared to the disk-based filesystem,
314 as a synchronous operation can be done with
315 just two context switches instead of incurring the disk latency.
316 .NH
317 Future Work
318 .PP
319 The most obvious shortcoming of the current implementation
320 is that filesystem blocks are copied twice, once between the \fInewfs\fP
321 process' address space and the kernel buffer cache,
322 and once between the kernel buffer and the requesting process.
323 These copies are done in different process contexts, necessitating
324 two context switches per group of I/O requests.
325 These problems arise because of the current inability of the kernel
326 to do page-in operations
327 for an address space other than that of the currently-running process,
328 and the current inconvenience of mapping process-owned pages into the kernel
329 buffer cache.
330 Both of these problems are expected to be solved in the next version
331 of the virtual memory system,
332 and thus we chose not to address them in the current implementation.
333 With the new version of the virtual memory system, we expect to use
334 any part of physical memory as part of the buffer cache,
335 even though it will not be entirely addressable at once within the kernel.
336 In that system, the implementation of a memory-based filesystem
337 that avoids the double copy and context switches will be much easier.
338 .PP
339 Ideally part of the kernel's address space would reside in pageable memory.
340 Once such a facility is available it would be most efficient to
341 build a memory-based filesystem within the kernel.
342 One potential problem with such a scheme is that many kernels
343 are limited to a small address space (usually a few megabytes).
344 This restriction limits the size of memory-based
345 filesystem that such a machine can support.
346 On such a machine, the kernel can describe a memory-based filesystem
347 that is larger than its address space and use a ``window''
348 to map the larger filesystem address space into its limited address space.
349 The window would maintain a cache of recently accessed pages.
350 The problem with this scheme is that if the working set of
351 active pages is greater than the size of the window, then
352 much time is spent remapping pages and invalidating
353 translation buffers.
354 Alternatively, a separate address space could be constructed for each
355 memory-based filesystem as in the current implementation,
356 and the memory-resident pages of that address space could be mapped
357 exactly as other cached pages are accessed.
358 .PP
359 The current system uses the existing local filesystem structures
360 and code to implement the memory-based filesystem.
361 The major advantages of this approach are the sharing of code
362 and the simplicity of the approach.
363 There are several disadvantages, however.
364 One is that the size of the filesystem is fixed at mount time.
365 This means that a fixed number of inodes (files) and data blocks
366 can be supported.
367 Currently, this approach requires enough swap space for the entire
368 filesystem, and prevents expansion and contraction of the filesystem on demand.
369 The current design also prevents the filesystem from taking advantage
370 of the memory-resident character of the filesystem.
371 It would be interesting to explore other filesystem implementations
372 that would be less expensive to execute and that would make better
373 use of the space.
374 For example, the current filesystem structure is optimized for magnetic
375 disks.
376 It includes replicated control structures, ``cylinder groups''
377 with separate allocation maps and control structures,
378 and data structures that optimize rotational layout of files.
379 None of this is useful in a memory-based filesystem (at least when the
380 backing store for the filesystem is dynamically allocated and not
381 contiguous on a single disk type).
382 On the other hand,
383 directories could be implemented using dynamically-allocated
384 memory organized as linked lists or trees rather than as files stored
385 in ``disk'' blocks.
386 Allocation and location of pages for file data might use virtual memory
387 primitives and data structures rather than direct and indirect blocks.
388 A reimplementation along these lines will be considered when the virtual
389 memory system in the current system has been replaced.
390 .[
391 $LIST$
392 .]