aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/atari/stram.c
diff options
context:
space:
mode:
authorHugh Dickins <hugh@veritas.com>2005-10-29 21:16:10 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-30 00:40:38 -0400
commitf9c98d0287de42221c624482fd4f8d485c98ab22 (patch)
treecc5653dcd2339b9006c224952b49f0c20b3c76a1 /arch/m68k/atari/stram.c
parent147efea8ebb034b48aee806caae1da9a2ee41b38 (diff)
[PATCH] mm: m68k kill stram swap
Please, please now delete the Atari CONFIG_STRAM_SWAP code. It may be excellent and ingenious code, but its reference to swap_vfsmnt betrays that it hasn't been built since 2.5.1 (four years old come December), it's delving deep into matters which are the preserve of core mm code, its only purpose is to give the more conscientious mm guys an anxiety attack from time to time; yet we keep on breaking it more and more. If you want to use RAM for swap, then if the MTD driver does not already provide just what you need, I'm sure David could be persuaded to add the extra. But you'd also like to be able to allocate extents of that swap for other use: we can give you a core interface for that if you need. But unbuilt for four years suggests to me that there's no need at all. I cannot swear the patch below won't break your build, but believe so. Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/m68k/atari/stram.c')
-rw-r--r--arch/m68k/atari/stram.c918
1 files changed, 15 insertions, 903 deletions
diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
index 5a3c106b40c8..22e0481a5f7b 100644
--- a/arch/m68k/atari/stram.c
+++ b/arch/m68k/atari/stram.c
@@ -15,11 +15,9 @@
15#include <linux/kdev_t.h> 15#include <linux/kdev_t.h>
16#include <linux/major.h> 16#include <linux/major.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/swap.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
20#include <linux/vmalloc.h> 19#include <linux/vmalloc.h>
21#include <linux/pagemap.h> 20#include <linux/pagemap.h>
22#include <linux/shm.h>
23#include <linux/bootmem.h> 21#include <linux/bootmem.h>
24#include <linux/mount.h> 22#include <linux/mount.h>
25#include <linux/blkdev.h> 23#include <linux/blkdev.h>
@@ -33,8 +31,6 @@
33#include <asm/io.h> 31#include <asm/io.h>
34#include <asm/semaphore.h> 32#include <asm/semaphore.h>
35 33
36#include <linux/swapops.h>
37
38#undef DEBUG 34#undef DEBUG
39 35
40#ifdef DEBUG 36#ifdef DEBUG
@@ -49,8 +45,7 @@
49#include <linux/proc_fs.h> 45#include <linux/proc_fs.h>
50#endif 46#endif
51 47
52/* Pre-swapping comments: 48/*
53 *
54 * ++roman: 49 * ++roman:
55 * 50 *
56 * New version of ST-Ram buffer allocation. Instead of using the 51 * New version of ST-Ram buffer allocation. Instead of using the
@@ -75,76 +70,6 @@
75 * 70 *
76 */ 71 */
77 72
78/*
79 * New Nov 1997: Use ST-RAM as swap space!
80 *
81 * In the past, there were often problems with modules that require ST-RAM
82 * buffers. Such drivers have to use __get_dma_pages(), which unfortunately
83 * often isn't very successful in allocating more than 1 page :-( [1] The net
84 * result was that most of the time you couldn't insmod such modules (ataflop,
85 * ACSI, SCSI on Falcon, Atari internal framebuffer, not to speak of acsi_slm,
86 * which needs a 1 MB buffer... :-).
87 *
88 * To overcome this limitation, ST-RAM can now be turned into a very
89 * high-speed swap space. If a request for an ST-RAM buffer comes, the kernel
90 * now tries to unswap some pages on that swap device to make some free (and
91 * contiguous) space. This works much better in comparison to
92 * __get_dma_pages(), since used swap pages can be selectively freed by either
93 * moving them to somewhere else in swap space, or by reading them back into
94 * system memory. Ok, there operation of unswapping isn't really cheap (for
95 * each page, one has to go through the page tables of all processes), but it
96 * doesn't happen that often (only when allocation ST-RAM, i.e. when loading a
97 * module that needs ST-RAM). But it at least makes it possible to load such
98 * modules!
99 *
100 * It could also be that overall system performance increases a bit due to
101 * ST-RAM swapping, since slow ST-RAM isn't used anymore for holding data or
102 * executing code in. It's then just a (very fast, compared to disk) back
103 * storage for not-so-often needed data. (But this effect must be compared
104 * with the loss of total memory...) Don't know if the effect is already
105 * visible on a TT, where the speed difference between ST- and TT-RAM isn't
106 * that dramatic, but it should on machines where TT-RAM is really much faster
107 * (e.g. Afterburner).
108 *
109 * [1]: __get_free_pages() does a fine job if you only want one page, but if
110 * you want more (contiguous) pages, it can give you such a block only if
111 * there's already a free one. The algorithm can't try to free buffers or swap
112 * out something in order to make more free space, since all that page-freeing
113 * mechanisms work "target-less", i.e. they just free something, but not in a
114 * specific place. I.e., __get_free_pages() can't do anything to free
115 * *adjacent* pages :-( This situation becomes even worse for DMA memory,
116 * since the freeing algorithms are also blind to DMA capability of pages.
117 */
118
119/* 1998-10-20: ++andreas
120 unswap_by_move disabled because it does not handle swapped shm pages.
121*/
122
123/* 2000-05-01: ++andreas
124 Integrated with bootmem. Remove all traces of unswap_by_move.
125*/
126
127#ifdef CONFIG_STRAM_SWAP
128#define ALIGN_IF_SWAP(x) PAGE_ALIGN(x)
129#else
130#define ALIGN_IF_SWAP(x) (x)
131#endif
132
133/* get index of swap page at address 'addr' */
134#define SWAP_NR(addr) (((addr) - swap_start) >> PAGE_SHIFT)
135
136/* get address of swap page #'nr' */
137#define SWAP_ADDR(nr) (swap_start + ((nr) << PAGE_SHIFT))
138
139/* get number of pages for 'n' bytes (already page-aligned) */
140#define N_PAGES(n) ((n) >> PAGE_SHIFT)
141
142/* The following two numbers define the maximum fraction of ST-RAM in total
143 * memory, below that the kernel would automatically use ST-RAM as swap
144 * space. This decision can be overridden with stram_swap= */
145#define MAX_STRAM_FRACTION_NOM 1
146#define MAX_STRAM_FRACTION_DENOM 3
147
148/* Start and end (virtual) of ST-RAM */ 73/* Start and end (virtual) of ST-RAM */
149static void *stram_start, *stram_end; 74static void *stram_start, *stram_end;
150 75
@@ -164,10 +89,9 @@ typedef struct stram_block {
164} BLOCK; 89} BLOCK;
165 90
166/* values for flags field */ 91/* values for flags field */
167#define BLOCK_FREE 0x01 /* free structure in the BLOCKs pool */ 92#define BLOCK_FREE 0x01 /* free structure in the BLOCKs pool */
168#define BLOCK_KMALLOCED 0x02 /* structure allocated by kmalloc() */ 93#define BLOCK_KMALLOCED 0x02 /* structure allocated by kmalloc() */
169#define BLOCK_GFP 0x08 /* block allocated with __get_dma_pages() */ 94#define BLOCK_GFP 0x08 /* block allocated with __get_dma_pages() */
170#define BLOCK_INSWAP 0x10 /* block allocated in swap space */
171 95
172/* list of allocated blocks */ 96/* list of allocated blocks */
173static BLOCK *alloc_list; 97static BLOCK *alloc_list;
@@ -179,60 +103,8 @@ static BLOCK *alloc_list;
179#define N_STATIC_BLOCKS 20 103#define N_STATIC_BLOCKS 20
180static BLOCK static_blocks[N_STATIC_BLOCKS]; 104static BLOCK static_blocks[N_STATIC_BLOCKS];
181 105
182#ifdef CONFIG_STRAM_SWAP
183/* max. number of bytes to use for swapping
184 * 0 = no ST-RAM swapping
185 * -1 = do swapping (to whole ST-RAM) if it's less than MAX_STRAM_FRACTION of
186 * total memory
187 */
188static int max_swap_size = -1;
189
190/* start and end of swapping area */
191static void *swap_start, *swap_end;
192
193/* The ST-RAM's swap info structure */
194static struct swap_info_struct *stram_swap_info;
195
196/* The ST-RAM's swap type */
197static int stram_swap_type;
198
199/* Semaphore for get_stram_region. */
200static DECLARE_MUTEX(stram_swap_sem);
201
202/* major and minor device number of the ST-RAM device; for the major, we use
203 * the same as Amiga z2ram, which is really similar and impossible on Atari,
204 * and for the minor a relatively odd number to avoid the user creating and
205 * using that device. */
206#define STRAM_MAJOR Z2RAM_MAJOR
207#define STRAM_MINOR 13
208
209/* Some impossible pointer value */
210#define MAGIC_FILE_P (struct file *)0xffffdead
211
212#ifdef DO_PROC
213static unsigned stat_swap_read;
214static unsigned stat_swap_write;
215static unsigned stat_swap_force;
216#endif /* DO_PROC */
217
218#endif /* CONFIG_STRAM_SWAP */
219
220/***************************** Prototypes *****************************/ 106/***************************** Prototypes *****************************/
221 107
222#ifdef CONFIG_STRAM_SWAP
223static int swap_init(void *start_mem, void *swap_data);
224static void *get_stram_region( unsigned long n_pages );
225static void free_stram_region( unsigned long offset, unsigned long n_pages
226 );
227static int in_some_region(void *addr);
228static unsigned long find_free_region( unsigned long n_pages, unsigned long
229 *total_free, unsigned long
230 *region_free );
231static void do_stram_request(request_queue_t *);
232static int stram_open( struct inode *inode, struct file *filp );
233static int stram_release( struct inode *inode, struct file *filp );
234static void reserve_region(void *start, void *end);
235#endif
236static BLOCK *add_region( void *addr, unsigned long size ); 108static BLOCK *add_region( void *addr, unsigned long size );
237static BLOCK *find_region( void *addr ); 109static BLOCK *find_region( void *addr );
238static int remove_region( BLOCK *block ); 110static int remove_region( BLOCK *block );
@@ -279,84 +151,11 @@ void __init atari_stram_init(void)
279 */ 151 */
280void __init atari_stram_reserve_pages(void *start_mem) 152void __init atari_stram_reserve_pages(void *start_mem)
281{ 153{
282#ifdef CONFIG_STRAM_SWAP
283 /* if max_swap_size is negative (i.e. no stram_swap= option given),
284 * determine at run time whether to use ST-RAM swapping */
285 if (max_swap_size < 0)
286 /* Use swapping if ST-RAM doesn't make up more than MAX_STRAM_FRACTION
287 * of total memory. In that case, the max. size is set to 16 MB,
288 * because ST-RAM can never be bigger than that.
289 * Also, never use swapping on a Hades, there's no separate ST-RAM in
290 * that machine. */
291 max_swap_size =
292 (!MACH_IS_HADES &&
293 (N_PAGES(stram_end-stram_start)*MAX_STRAM_FRACTION_DENOM <=
294 ((unsigned long)high_memory>>PAGE_SHIFT)*MAX_STRAM_FRACTION_NOM)) ? 16*1024*1024 : 0;
295 DPRINTK( "atari_stram_reserve_pages: max_swap_size = %d\n", max_swap_size );
296#endif
297
298 /* always reserve first page of ST-RAM, the first 2 kB are 154 /* always reserve first page of ST-RAM, the first 2 kB are
299 * supervisor-only! */ 155 * supervisor-only! */
300 if (!kernel_in_stram) 156 if (!kernel_in_stram)
301 reserve_bootmem (0, PAGE_SIZE); 157 reserve_bootmem (0, PAGE_SIZE);
302 158
303#ifdef CONFIG_STRAM_SWAP
304 {
305 void *swap_data;
306
307 start_mem = (void *) PAGE_ALIGN ((unsigned long) start_mem);
308 /* determine first page to use as swap: if the kernel is
309 in TT-RAM, this is the first page of (usable) ST-RAM;
310 otherwise just use the end of kernel data (= start_mem) */
311 swap_start = !kernel_in_stram ? stram_start + PAGE_SIZE : start_mem;
312 /* decrement by one page, rest of kernel assumes that first swap page
313 * is always reserved and maybe doesn't handle swp_entry == 0
314 * correctly */
315 swap_start -= PAGE_SIZE;
316 swap_end = stram_end;
317 if (swap_end-swap_start > max_swap_size)
318 swap_end = swap_start + max_swap_size;
319 DPRINTK( "atari_stram_reserve_pages: swapping enabled; "
320 "swap=%p-%p\n", swap_start, swap_end);
321
322 /* reserve some amount of memory for maintainance of
323 * swapping itself: one page for each 2048 (PAGE_SIZE/2)
324 * swap pages. (2 bytes for each page) */
325 swap_data = start_mem;
326 start_mem += ((SWAP_NR(swap_end) + PAGE_SIZE/2 - 1)
327 >> (PAGE_SHIFT-1)) << PAGE_SHIFT;
328 /* correct swap_start if necessary */
329 if (swap_start + PAGE_SIZE == swap_data)
330 swap_start = start_mem - PAGE_SIZE;
331
332 if (!swap_init( start_mem, swap_data )) {
333 printk( KERN_ERR "ST-RAM swap space initialization failed\n" );
334 max_swap_size = 0;
335 return;
336 }
337 /* reserve region for swapping meta-data */
338 reserve_region(swap_data, start_mem);
339 /* reserve swapping area itself */
340 reserve_region(swap_start + PAGE_SIZE, swap_end);
341
342 /*
343 * If the whole ST-RAM is used for swapping, there are no allocatable
344 * dma pages left. But unfortunately, some shared parts of the kernel
345 * (particularly the SCSI mid-level) call __get_dma_pages()
346 * unconditionally :-( These calls then fail, and scsi.c even doesn't
347 * check for NULL return values and just crashes. The quick fix for
348 * this (instead of doing much clean up work in the SCSI code) is to
349 * pretend all pages are DMA-able by setting mach_max_dma_address to
350 * ULONG_MAX. This doesn't change any functionality so far, since
351 * get_dma_pages() shouldn't be used on Atari anyway anymore (better
352 * use atari_stram_alloc()), and the Atari SCSI drivers don't need DMA
353 * memory. But unfortunately there's now no kind of warning (even not
354 * a NULL return value) if you use get_dma_pages() nevertheless :-(
355 * You just will get non-DMA-able memory...
356 */
357 mach_max_dma_address = 0xffffffff;
358 }
359#endif
360} 159}
361 160
362void atari_stram_mem_init_hook (void) 161void atari_stram_mem_init_hook (void)
@@ -367,7 +166,6 @@ void atari_stram_mem_init_hook (void)
367 166
368/* 167/*
369 * This is main public interface: somehow allocate a ST-RAM block 168 * This is main public interface: somehow allocate a ST-RAM block
370 * There are three strategies:
371 * 169 *
372 * - If we're before mem_init(), we have to make a static allocation. The 170 * - If we're before mem_init(), we have to make a static allocation. The
373 * region is taken in the kernel data area (if the kernel is in ST-RAM) or 171 * region is taken in the kernel data area (if the kernel is in ST-RAM) or
@@ -375,14 +173,9 @@ void atari_stram_mem_init_hook (void)
375 * rsvd_stram_* region. The ST-RAM is somewhere in the middle of kernel 173 * rsvd_stram_* region. The ST-RAM is somewhere in the middle of kernel
376 * address space in the latter case. 174 * address space in the latter case.
377 * 175 *
378 * - If mem_init() already has been called and ST-RAM swapping is enabled, 176 * - If mem_init() already has been called, try with __get_dma_pages().
379 * try to get the memory from the (pseudo) swap-space, either free already 177 * This has the disadvantage that it's very hard to get more than 1 page,
380 * or by moving some other pages out of the swap. 178 * and it is likely to fail :-(
381 *
382 * - If mem_init() already has been called, and ST-RAM swapping is not
383 * enabled, the only possibility is to try with __get_dma_pages(). This has
384 * the disadvantage that it's very hard to get more than 1 page, and it is
385 * likely to fail :-(
386 * 179 *
387 */ 180 */
388void *atari_stram_alloc(long size, const char *owner) 181void *atari_stram_alloc(long size, const char *owner)
@@ -393,27 +186,13 @@ void *atari_stram_alloc(long size, const char *owner)
393 186
394 DPRINTK("atari_stram_alloc(size=%08lx,owner=%s)\n", size, owner); 187 DPRINTK("atari_stram_alloc(size=%08lx,owner=%s)\n", size, owner);
395 188
396 size = ALIGN_IF_SWAP(size);
397 DPRINTK( "atari_stram_alloc: rounded size = %08lx\n", size );
398#ifdef CONFIG_STRAM_SWAP
399 if (max_swap_size) {
400 /* If swapping is active: make some free space in the swap
401 "device". */
402 DPRINTK( "atari_stram_alloc: after mem_init, swapping ok, "
403 "calling get_region\n" );
404 addr = get_stram_region( N_PAGES(size) );
405 flags = BLOCK_INSWAP;
406 }
407 else
408#endif
409 if (!mem_init_done) 189 if (!mem_init_done)
410 return alloc_bootmem_low(size); 190 return alloc_bootmem_low(size);
411 else { 191 else {
412 /* After mem_init() and no swapping: can only resort to 192 /* After mem_init(): can only resort to __get_dma_pages() */
413 * __get_dma_pages() */
414 addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size)); 193 addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size));
415 flags = BLOCK_GFP; 194 flags = BLOCK_GFP;
416 DPRINTK( "atari_stram_alloc: after mem_init, swapping off, " 195 DPRINTK( "atari_stram_alloc: after mem_init, "
417 "get_pages=%p\n", addr ); 196 "get_pages=%p\n", addr );
418 } 197 }
419 198
@@ -422,12 +201,7 @@ void *atari_stram_alloc(long size, const char *owner)
422 /* out of memory for BLOCK structure :-( */ 201 /* out of memory for BLOCK structure :-( */
423 DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- " 202 DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- "
424 "freeing again\n" ); 203 "freeing again\n" );
425#ifdef CONFIG_STRAM_SWAP 204 free_pages((unsigned long)addr, get_order(size));
426 if (flags == BLOCK_INSWAP)
427 free_stram_region( SWAP_NR(addr), N_PAGES(size) );
428 else
429#endif
430 free_pages((unsigned long)addr, get_order(size));
431 return( NULL ); 205 return( NULL );
432 } 206 }
433 block->owner = owner; 207 block->owner = owner;
@@ -451,25 +225,12 @@ void atari_stram_free( void *addr )
451 DPRINTK( "atari_stram_free: found block (%p): size=%08lx, owner=%s, " 225 DPRINTK( "atari_stram_free: found block (%p): size=%08lx, owner=%s, "
452 "flags=%02x\n", block, block->size, block->owner, block->flags ); 226 "flags=%02x\n", block, block->size, block->owner, block->flags );
453 227
454#ifdef CONFIG_STRAM_SWAP 228 if (!(block->flags & BLOCK_GFP))
455 if (!max_swap_size) {
456#endif
457 if (block->flags & BLOCK_GFP) {
458 DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
459 get_order(block->size));
460 free_pages((unsigned long)addr, get_order(block->size));
461 }
462 else
463 goto fail;
464#ifdef CONFIG_STRAM_SWAP
465 }
466 else if (block->flags & BLOCK_INSWAP) {
467 DPRINTK( "atari_stram_free: is swap-alloced\n" );
468 free_stram_region( SWAP_NR(block->start), N_PAGES(block->size) );
469 }
470 else
471 goto fail; 229 goto fail;
472#endif 230
231 DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
232 get_order(block->size));
233 free_pages((unsigned long)addr, get_order(block->size));
473 remove_region( block ); 234 remove_region( block );
474 return; 235 return;
475 236
@@ -478,612 +239,6 @@ void atari_stram_free( void *addr )
478 "(called from %p)\n", addr, __builtin_return_address(0) ); 239 "(called from %p)\n", addr, __builtin_return_address(0) );
479} 240}
480 241
481
482#ifdef CONFIG_STRAM_SWAP
483
484
485/* ------------------------------------------------------------------------ */
486/* Main Swapping Functions */
487/* ------------------------------------------------------------------------ */
488
489
490/*
491 * Initialize ST-RAM swap device
492 * (lots copied and modified from sys_swapon() in mm/swapfile.c)
493 */
494static int __init swap_init(void *start_mem, void *swap_data)
495{
496 static struct dentry fake_dentry;
497 static struct vfsmount fake_vfsmnt;
498 struct swap_info_struct *p;
499 struct inode swap_inode;
500 unsigned int type;
501 void *addr;
502 int i, j, k, prev;
503
504 DPRINTK("swap_init(start_mem=%p, swap_data=%p)\n",
505 start_mem, swap_data);
506
507 /* need at least one page for swapping to (and this also isn't very
508 * much... :-) */
509 if (swap_end - swap_start < 2*PAGE_SIZE) {
510 printk( KERN_WARNING "stram_swap_init: swap space too small\n" );
511 return( 0 );
512 }
513
514 /* find free slot in swap_info */
515 for( p = swap_info, type = 0; type < nr_swapfiles; type++, p++ )
516 if (!(p->flags & SWP_USED))
517 break;
518 if (type >= MAX_SWAPFILES) {
519 printk( KERN_WARNING "stram_swap_init: max. number of "
520 "swap devices exhausted\n" );
521 return( 0 );
522 }
523 if (type >= nr_swapfiles)
524 nr_swapfiles = type+1;
525
526 stram_swap_info = p;
527 stram_swap_type = type;
528
529 /* fake some dir cache entries to give us some name in /dev/swaps */
530 fake_dentry.d_parent = &fake_dentry;
531 fake_dentry.d_name.name = "stram (internal)";
532 fake_dentry.d_name.len = 16;
533 fake_vfsmnt.mnt_parent = &fake_vfsmnt;
534
535 p->flags = SWP_USED;
536 p->swap_file = &fake_dentry;
537 p->swap_vfsmnt = &fake_vfsmnt;
538 p->swap_map = swap_data;
539 p->cluster_nr = 0;
540 p->next = -1;
541 p->prio = 0x7ff0; /* a rather high priority, but not the higest
542 * to give the user a chance to override */
543
544 /* call stram_open() directly, avoids at least the overhead in
545 * constructing a dummy file structure... */
546 swap_inode.i_rdev = MKDEV( STRAM_MAJOR, STRAM_MINOR );
547 stram_open( &swap_inode, MAGIC_FILE_P );
548 p->max = SWAP_NR(swap_end);
549
550 /* initialize swap_map: set regions that are already allocated or belong
551 * to kernel data space to SWAP_MAP_BAD, otherwise to free */
552 j = 0; /* # of free pages */
553 k = 0; /* # of already allocated pages (from pre-mem_init stram_alloc()) */
554 p->lowest_bit = 0;
555 p->highest_bit = 0;
556 for( i = 1, addr = SWAP_ADDR(1); i < p->max;
557 i++, addr += PAGE_SIZE ) {
558 if (in_some_region( addr )) {
559 p->swap_map[i] = SWAP_MAP_BAD;
560 ++k;
561 }
562 else if (kernel_in_stram && addr < start_mem ) {
563 p->swap_map[i] = SWAP_MAP_BAD;
564 }
565 else {
566 p->swap_map[i] = 0;
567 ++j;
568 if (!p->lowest_bit) p->lowest_bit = i;
569 p->highest_bit = i;
570 }
571 }
572 /* first page always reserved (and doesn't really belong to swap space) */
573 p->swap_map[0] = SWAP_MAP_BAD;
574
575 /* now swapping to this device ok */
576 p->pages = j + k;
577 swap_list_lock();
578 nr_swap_pages += j;
579 p->flags = SWP_WRITEOK;
580
581 /* insert swap space into swap_list */
582 prev = -1;
583 for (i = swap_list.head; i >= 0; i = swap_info[i].next) {
584 if (p->prio >= swap_info[i].prio) {
585 break;
586 }
587 prev = i;
588 }
589 p->next = i;
590 if (prev < 0) {
591 swap_list.head = swap_list.next = p - swap_info;
592 } else {
593 swap_info[prev].next = p - swap_info;
594 }
595 swap_list_unlock();
596
597 printk( KERN_INFO "Using %dk (%d pages) of ST-RAM as swap space.\n",
598 p->pages << 2, p->pages );
599 return( 1 );
600}
601
602
603/*
604 * The swap entry has been read in advance, and we return 1 to indicate
605 * that the page has been used or is no longer needed.
606 *
607 * Always set the resulting pte to be nowrite (the same as COW pages
608 * after one process has exited). We don't know just how many PTEs will
609 * share this swap entry, so be cautious and let do_wp_page work out
610 * what to do if a write is requested later.
611 */
612static inline void unswap_pte(struct vm_area_struct * vma, unsigned long
613 address, pte_t *dir, swp_entry_t entry,
614 struct page *page)
615{
616 pte_t pte = *dir;
617
618 if (pte_none(pte))
619 return;
620 if (pte_present(pte)) {
621 /* If this entry is swap-cached, then page must already
622 hold the right address for any copies in physical
623 memory */
624 if (pte_page(pte) != page)
625 return;
626 /* We will be removing the swap cache in a moment, so... */
627 set_pte(dir, pte_mkdirty(pte));
628 return;
629 }
630 if (pte_val(pte) != entry.val)
631 return;
632
633 DPRINTK("unswap_pte: replacing entry %08lx by new page %p",
634 entry.val, page);
635 set_pte(dir, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
636 swap_free(entry);
637 get_page(page);
638 inc_mm_counter(vma->vm_mm, rss);
639}
640
641static inline void unswap_pmd(struct vm_area_struct * vma, pmd_t *dir,
642 unsigned long address, unsigned long size,
643 unsigned long offset, swp_entry_t entry,
644 struct page *page)
645{
646 pte_t * pte;
647 unsigned long end;
648
649 if (pmd_none(*dir))
650 return;
651 if (pmd_bad(*dir)) {
652 pmd_ERROR(*dir);
653 pmd_clear(dir);
654 return;
655 }
656 pte = pte_offset_kernel(dir, address);
657 offset += address & PMD_MASK;
658 address &= ~PMD_MASK;
659 end = address + size;
660 if (end > PMD_SIZE)
661 end = PMD_SIZE;
662 do {
663 unswap_pte(vma, offset+address-vma->vm_start, pte, entry, page);
664 address += PAGE_SIZE;
665 pte++;
666 } while (address < end);
667}
668
669static inline void unswap_pgd(struct vm_area_struct * vma, pgd_t *dir,
670 unsigned long address, unsigned long size,
671 swp_entry_t entry, struct page *page)
672{
673 pmd_t * pmd;
674 unsigned long offset, end;
675
676 if (pgd_none(*dir))
677 return;
678 if (pgd_bad(*dir)) {
679 pgd_ERROR(*dir);
680 pgd_clear(dir);
681 return;
682 }
683 pmd = pmd_offset(dir, address);
684 offset = address & PGDIR_MASK;
685 address &= ~PGDIR_MASK;
686 end = address + size;
687 if (end > PGDIR_SIZE)
688 end = PGDIR_SIZE;
689 do {
690 unswap_pmd(vma, pmd, address, end - address, offset, entry,
691 page);
692 address = (address + PMD_SIZE) & PMD_MASK;
693 pmd++;
694 } while (address < end);
695}
696
697static void unswap_vma(struct vm_area_struct * vma, pgd_t *pgdir,
698 swp_entry_t entry, struct page *page)
699{
700 unsigned long start = vma->vm_start, end = vma->vm_end;
701
702 do {
703 unswap_pgd(vma, pgdir, start, end - start, entry, page);
704 start = (start + PGDIR_SIZE) & PGDIR_MASK;
705 pgdir++;
706 } while (start < end);
707}
708
709static void unswap_process(struct mm_struct * mm, swp_entry_t entry,
710 struct page *page)
711{
712 struct vm_area_struct* vma;
713
714 /*
715 * Go through process' page directory.
716 */
717 if (!mm)
718 return;
719 for (vma = mm->mmap; vma; vma = vma->vm_next) {
720 pgd_t * pgd = pgd_offset(mm, vma->vm_start);
721 unswap_vma(vma, pgd, entry, page);
722 }
723}
724
725
726static int unswap_by_read(unsigned short *map, unsigned long max,
727 unsigned long start, unsigned long n_pages)
728{
729 struct task_struct *p;
730 struct page *page;
731 swp_entry_t entry;
732 unsigned long i;
733
734 DPRINTK( "unswapping %lu..%lu by reading in\n",
735 start, start+n_pages-1 );
736
737 for( i = start; i < start+n_pages; ++i ) {
738 if (map[i] == SWAP_MAP_BAD) {
739 printk( KERN_ERR "get_stram_region: page %lu already "
740 "reserved??\n", i );
741 continue;
742 }
743
744 if (map[i]) {
745 entry = swp_entry(stram_swap_type, i);
746 DPRINTK("unswap: map[i=%lu]=%u nr_swap=%ld\n",
747 i, map[i], nr_swap_pages);
748
749 swap_device_lock(stram_swap_info);
750 map[i]++;
751 swap_device_unlock(stram_swap_info);
752 /* Get a page for the entry, using the existing
753 swap cache page if there is one. Otherwise,
754 get a clean page and read the swap into it. */
755 page = read_swap_cache_async(entry, NULL, 0);
756 if (!page) {
757 swap_free(entry);
758 return -ENOMEM;
759 }
760 read_lock(&tasklist_lock);
761 for_each_process(p)
762 unswap_process(p->mm, entry, page);
763 read_unlock(&tasklist_lock);
764 shmem_unuse(entry, page);
765 /* Now get rid of the extra reference to the
766 temporary page we've been using. */
767 if (PageSwapCache(page))
768 delete_from_swap_cache(page);
769 __free_page(page);
770 #ifdef DO_PROC
771 stat_swap_force++;
772 #endif
773 }
774
775 DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%ld\n",
776 i, map[i], nr_swap_pages );
777 swap_list_lock();
778 swap_device_lock(stram_swap_info);
779 map[i] = SWAP_MAP_BAD;
780 if (stram_swap_info->lowest_bit == i)
781 stram_swap_info->lowest_bit++;
782 if (stram_swap_info->highest_bit == i)
783 stram_swap_info->highest_bit--;
784 --nr_swap_pages;
785 swap_device_unlock(stram_swap_info);
786 swap_list_unlock();
787 }
788
789 return 0;
790}
791
792/*
793 * reserve a region in ST-RAM swap space for an allocation
794 */
795static void *get_stram_region( unsigned long n_pages )
796{
797 unsigned short *map = stram_swap_info->swap_map;
798 unsigned long max = stram_swap_info->max;
799 unsigned long start, total_free, region_free;
800 int err;
801 void *ret = NULL;
802
803 DPRINTK( "get_stram_region(n_pages=%lu)\n", n_pages );
804
805 down(&stram_swap_sem);
806
807 /* disallow writing to the swap device now */
808 stram_swap_info->flags = SWP_USED;
809
810 /* find a region of n_pages pages in the swap space including as much free
811 * pages as possible (and excluding any already-reserved pages). */
812 if (!(start = find_free_region( n_pages, &total_free, &region_free )))
813 goto end;
814 DPRINTK( "get_stram_region: region starts at %lu, has %lu free pages\n",
815 start, region_free );
816
817 err = unswap_by_read(map, max, start, n_pages);
818 if (err)
819 goto end;
820
821 ret = SWAP_ADDR(start);
822 end:
823 /* allow using swap device again */
824 stram_swap_info->flags = SWP_WRITEOK;
825 up(&stram_swap_sem);
826 DPRINTK( "get_stram_region: returning %p\n", ret );
827 return( ret );
828}
829
830
831/*
832 * free a reserved region in ST-RAM swap space
833 */
834static void free_stram_region( unsigned long offset, unsigned long n_pages )
835{
836 unsigned short *map = stram_swap_info->swap_map;
837
838 DPRINTK( "free_stram_region(offset=%lu,n_pages=%lu)\n", offset, n_pages );
839
840 if (offset < 1 || offset + n_pages > stram_swap_info->max) {
841 printk( KERN_ERR "free_stram_region: Trying to free non-ST-RAM\n" );
842 return;
843 }
844
845 swap_list_lock();
846 swap_device_lock(stram_swap_info);
847 /* un-reserve the freed pages */
848 for( ; n_pages > 0; ++offset, --n_pages ) {
849 if (map[offset] != SWAP_MAP_BAD)
850 printk( KERN_ERR "free_stram_region: Swap page %lu was not "
851 "reserved\n", offset );
852 map[offset] = 0;
853 }
854
855 /* update swapping meta-data */
856 if (offset < stram_swap_info->lowest_bit)
857 stram_swap_info->lowest_bit = offset;
858 if (offset+n_pages-1 > stram_swap_info->highest_bit)
859 stram_swap_info->highest_bit = offset+n_pages-1;
860 if (stram_swap_info->prio > swap_info[swap_list.next].prio)
861 swap_list.next = swap_list.head;
862 nr_swap_pages += n_pages;
863 swap_device_unlock(stram_swap_info);
864 swap_list_unlock();
865}
866
867
868/* ------------------------------------------------------------------------ */
869/* Utility Functions for Swapping */
870/* ------------------------------------------------------------------------ */
871
872
873/* is addr in some of the allocated regions? */
874static int in_some_region(void *addr)
875{
876 BLOCK *p;
877
878 for( p = alloc_list; p; p = p->next ) {
879 if (p->start <= addr && addr < p->start + p->size)
880 return( 1 );
881 }
882 return( 0 );
883}
884
885
886static unsigned long find_free_region(unsigned long n_pages,
887 unsigned long *total_free,
888 unsigned long *region_free)
889{
890 unsigned short *map = stram_swap_info->swap_map;
891 unsigned long max = stram_swap_info->max;
892 unsigned long head, tail, max_start;
893 long nfree, max_free;
894
895 /* first scan the swap space for a suitable place for the allocation */
896 head = 1;
897 max_start = 0;
898 max_free = -1;
899 *total_free = 0;
900
901 start_over:
902 /* increment tail until final window size reached, and count free pages */
903 nfree = 0;
904 for( tail = head; tail-head < n_pages && tail < max; ++tail ) {
905 if (map[tail] == SWAP_MAP_BAD) {
906 head = tail+1;
907 goto start_over;
908 }
909 if (!map[tail]) {
910 ++nfree;
911 ++*total_free;
912 }
913 }
914 if (tail-head < n_pages)
915 goto out;
916 if (nfree > max_free) {
917 max_start = head;
918 max_free = nfree;
919 if (max_free >= n_pages)
920 /* don't need more free pages... :-) */
921 goto out;
922 }
923
924 /* now shift the window and look for the area where as much pages as
925 * possible are free */
926 while( tail < max ) {
927 nfree -= (map[head++] == 0);
928 if (map[tail] == SWAP_MAP_BAD) {
929 head = tail+1;
930 goto start_over;
931 }
932 if (!map[tail]) {
933 ++nfree;
934 ++*total_free;
935 }
936 ++tail;
937 if (nfree > max_free) {
938 max_start = head;
939 max_free = nfree;
940 if (max_free >= n_pages)
941 /* don't need more free pages... :-) */
942 goto out;
943 }
944 }
945
946 out:
947 if (max_free < 0) {
948 printk( KERN_NOTICE "get_stram_region: ST-RAM too full or fragmented "
949 "-- can't allocate %lu pages\n", n_pages );
950 return( 0 );
951 }
952
953 *region_free = max_free;
954 return( max_start );
955}
956
957
958/* setup parameters from command line */
959void __init stram_swap_setup(char *str, int *ints)
960{
961 if (ints[0] >= 1)
962 max_swap_size = ((ints[1] < 0 ? 0 : ints[1]) * 1024) & PAGE_MASK;
963}
964
965
966/* ------------------------------------------------------------------------ */
967/* ST-RAM device */
968/* ------------------------------------------------------------------------ */
969
970static int refcnt;
971
972static void do_stram_request(request_queue_t *q)
973{
974 struct request *req;
975
976 while ((req = elv_next_request(q)) != NULL) {
977 void *start = swap_start + (req->sector << 9);
978 unsigned long len = req->current_nr_sectors << 9;
979 if ((start + len) > swap_end) {
980 printk( KERN_ERR "stram: bad access beyond end of device: "
981 "block=%ld, count=%d\n",
982 req->sector,
983 req->current_nr_sectors );
984 end_request(req, 0);
985 continue;
986 }
987
988 if (req->cmd == READ) {
989 memcpy(req->buffer, start, len);
990#ifdef DO_PROC
991 stat_swap_read += N_PAGES(len);
992#endif
993 }
994 else {
995 memcpy(start, req->buffer, len);
996#ifdef DO_PROC
997 stat_swap_write += N_PAGES(len);
998#endif
999 }
1000 end_request(req, 1);
1001 }
1002}
1003
1004
1005static int stram_open( struct inode *inode, struct file *filp )
1006{
1007 if (filp != MAGIC_FILE_P) {
1008 printk( KERN_NOTICE "Only kernel can open ST-RAM device\n" );
1009 return( -EPERM );
1010 }
1011 if (refcnt)
1012 return( -EBUSY );
1013 ++refcnt;
1014 return( 0 );
1015}
1016
1017static int stram_release( struct inode *inode, struct file *filp )
1018{
1019 if (filp != MAGIC_FILE_P) {
1020 printk( KERN_NOTICE "Only kernel can close ST-RAM device\n" );
1021 return( -EPERM );
1022 }
1023 if (refcnt > 0)
1024 --refcnt;
1025 return( 0 );
1026}
1027
1028
1029static struct block_device_operations stram_fops = {
1030 .open = stram_open,
1031 .release = stram_release,
1032};
1033
1034static struct gendisk *stram_disk;
1035static struct request_queue *stram_queue;
1036static DEFINE_SPINLOCK(stram_lock);
1037
1038int __init stram_device_init(void)
1039{
1040 if (!MACH_IS_ATARI)
1041 /* no point in initializing this, I hope */
1042 return -ENXIO;
1043
1044 if (!max_swap_size)
1045 /* swapping not enabled */
1046 return -ENXIO;
1047 stram_disk = alloc_disk(1);
1048 if (!stram_disk)
1049 return -ENOMEM;
1050
1051 if (register_blkdev(STRAM_MAJOR, "stram")) {
1052 put_disk(stram_disk);
1053 return -ENXIO;
1054 }
1055
1056 stram_queue = blk_init_queue(do_stram_request, &stram_lock);
1057 if (!stram_queue) {
1058 unregister_blkdev(STRAM_MAJOR, "stram");
1059 put_disk(stram_disk);
1060 return -ENOMEM;
1061 }
1062
1063 stram_disk->major = STRAM_MAJOR;
1064 stram_disk->first_minor = STRAM_MINOR;
1065 stram_disk->fops = &stram_fops;
1066 stram_disk->queue = stram_queue;
1067 sprintf(stram_disk->disk_name, "stram");
1068 set_capacity(stram_disk, (swap_end - swap_start)/512);
1069 add_disk(stram_disk);
1070 return 0;
1071}
1072
1073
1074
1075/* ------------------------------------------------------------------------ */
1076/* Misc Utility Functions */
1077/* ------------------------------------------------------------------------ */
1078
1079/* reserve a range of pages */
1080static void reserve_region(void *start, void *end)
1081{
1082 reserve_bootmem (virt_to_phys(start), end - start);
1083}
1084
1085#endif /* CONFIG_STRAM_SWAP */
1086
1087 242
1088/* ------------------------------------------------------------------------ */ 243/* ------------------------------------------------------------------------ */
1089/* Region Management */ 244/* Region Management */
@@ -1173,50 +328,9 @@ int get_stram_list( char *buf )
1173{ 328{
1174 int len = 0; 329 int len = 0;
1175 BLOCK *p; 330 BLOCK *p;
1176#ifdef CONFIG_STRAM_SWAP
1177 int i;
1178 unsigned short *map = stram_swap_info->swap_map;
1179 unsigned long max = stram_swap_info->max;
1180 unsigned free = 0, used = 0, rsvd = 0;
1181#endif
1182 331
1183#ifdef CONFIG_STRAM_SWAP 332 PRINT_PROC("Total ST-RAM: %8u kB\n",
1184 if (max_swap_size) {
1185 for( i = 1; i < max; ++i ) {
1186 if (!map[i])
1187 ++free;
1188 else if (map[i] == SWAP_MAP_BAD)
1189 ++rsvd;
1190 else
1191 ++used;
1192 }
1193 PRINT_PROC(
1194 "Total ST-RAM: %8u kB\n"
1195 "Total ST-RAM swap: %8lu kB\n"
1196 "Free swap: %8u kB\n"
1197 "Used swap: %8u kB\n"
1198 "Allocated swap: %8u kB\n"
1199 "Swap Reads: %8u\n"
1200 "Swap Writes: %8u\n"
1201 "Swap Forced Reads: %8u\n",
1202 (stram_end - stram_start) >> 10,
1203 (max-1) << (PAGE_SHIFT-10),
1204 free << (PAGE_SHIFT-10),
1205 used << (PAGE_SHIFT-10),
1206 rsvd << (PAGE_SHIFT-10),
1207 stat_swap_read,
1208 stat_swap_write,
1209 stat_swap_force );
1210 }
1211 else {
1212#endif
1213 PRINT_PROC( "ST-RAM swapping disabled\n" );
1214 PRINT_PROC("Total ST-RAM: %8u kB\n",
1215 (stram_end - stram_start) >> 10); 333 (stram_end - stram_start) >> 10);
1216#ifdef CONFIG_STRAM_SWAP
1217 }
1218#endif
1219
1220 PRINT_PROC( "Allocated regions:\n" ); 334 PRINT_PROC( "Allocated regions:\n" );
1221 for( p = alloc_list; p; p = p->next ) { 335 for( p = alloc_list; p; p = p->next ) {
1222 if (len + 50 >= PAGE_SIZE) 336 if (len + 50 >= PAGE_SIZE)
@@ -1227,8 +341,6 @@ int get_stram_list( char *buf )
1227 p->owner); 341 p->owner);
1228 if (p->flags & BLOCK_GFP) 342 if (p->flags & BLOCK_GFP)
1229 PRINT_PROC( "page-alloced)\n" ); 343 PRINT_PROC( "page-alloced)\n" );
1230 else if (p->flags & BLOCK_INSWAP)
1231 PRINT_PROC( "in swap)\n" );
1232 else 344 else
1233 PRINT_PROC( "??)\n" ); 345 PRINT_PROC( "??)\n" );
1234 } 346 }