This source file includes following definitions.
- rw_swap_page
- get_swap_page
- swap_duplicate
- swap_free
- swap_in
- try_to_swap_out
- sys_idle
- swap_out
- swap_out
- try_to_free_page
- add_mem_queue
- free_page
- __get_free_page
- try_to_unuse
- sys_swapoff
- sys_swapon
- si_swapinfo
1
2
3
4
5
6
7
8
9
10
11
12 #include <linux/mm.h>
13 #include <linux/sched.h>
14 #include <linux/head.h>
15 #include <linux/kernel.h>
16 #include <linux/errno.h>
17 #include <linux/string.h>
18 #include <linux/stat.h>
19
20 #include <asm/system.h>
21 #include <asm/bitops.h>
22
23 #define MAX_SWAPFILES 8
24
25 #define SWP_USED 1
26 #define SWP_WRITEOK 3
27
28 #define SWP_TYPE(entry) (((entry) & 0xfe) >> 1)
29 #define SWP_OFFSET(entry) ((entry) >> PAGE_SHIFT)
30 #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << PAGE_SHIFT))
31
32 static int nr_swapfiles = 0;
33 static struct wait_queue * lock_queue = NULL;
34
35 static struct swap_info_struct {
36 unsigned long flags;
37 struct inode * swap_file;
38 unsigned int swap_device;
39 unsigned char * swap_map;
40 unsigned char * swap_lockmap;
41 int pages;
42 int lowest_bit;
43 int highest_bit;
44 } swap_info[MAX_SWAPFILES];
45
46 extern unsigned long free_page_list;
47 extern int shm_swap (int);
48
49
50
51
52
53 #define NR_LAST_FREE_PAGES 32
54 static unsigned long last_free_pages[NR_LAST_FREE_PAGES] = {0,};
55
56 #define SWAP_BITS PAGE_SIZE
57
58 void rw_swap_page(int rw, unsigned long entry, char * buf)
59 {
60 unsigned long type, offset;
61 struct swap_info_struct * p;
62
63 type = SWP_TYPE(entry);
64 if (type >= nr_swapfiles) {
65 printk("Internal error: bad swap-device\n");
66 return;
67 }
68 p = &swap_info[type];
69 offset = SWP_OFFSET(entry);
70 if (offset >= SWAP_BITS) {
71 printk("rw_swap_page: weirdness\n");
72 return;
73 }
74 if (!(p->flags & SWP_USED)) {
75 printk("Trying to swap to unused swap-device\n");
76 return;
77 }
78 while (set_bit(offset,p->swap_lockmap))
79 sleep_on(&lock_queue);
80 if (p->swap_device) {
81 ll_rw_page(rw,p->swap_device,offset,buf);
82 } else if (p->swap_file) {
83 unsigned int zones[8];
84 unsigned int block;
85 int i, j;
86
87 block = offset << (12 - p->swap_file->i_sb->s_blocksize_bits);
88
89 for (i=0, j=0; j< PAGE_SIZE ; i++, j +=p->swap_file->i_sb->s_blocksize)
90 if (!(zones[i] = bmap(p->swap_file,block++))) {
91 printk("rw_swap_page: bad swap file\n");
92 return;
93 }
94 ll_rw_swap_file(rw,p->swap_file->i_dev, zones, i,buf);
95 } else
96 printk("re_swap_page: no swap file or device\n");
97 if (!clear_bit(offset,p->swap_lockmap))
98 printk("rw_swap_page: lock already cleared\n");
99 wake_up(&lock_queue);
100 }
101
102 unsigned int get_swap_page(void)
103 {
104 struct swap_info_struct * p;
105 unsigned int offset, type;
106
107 p = swap_info;
108 for (type = 0 ; type < nr_swapfiles ; type++,p++) {
109 if ((p->flags & SWP_WRITEOK) != SWP_WRITEOK)
110 continue;
111 for (offset = p->lowest_bit; offset <= p->highest_bit ; offset++) {
112 if (p->swap_map[offset])
113 continue;
114 p->swap_map[offset] = 1;
115 nr_swap_pages--;
116 if (offset == p->highest_bit)
117 p->highest_bit--;
118 p->lowest_bit = offset;
119 return SWP_ENTRY(type,offset);
120 }
121 }
122 return 0;
123 }
124
125 unsigned long swap_duplicate(unsigned long entry)
126 {
127 struct swap_info_struct * p;
128 unsigned long offset, type;
129
130 if (!entry)
131 return 0;
132 offset = SWP_OFFSET(entry);
133 type = SWP_TYPE(entry);
134 if (type == SHM_SWP_TYPE)
135 return entry;
136 if (type >= nr_swapfiles) {
137 printk("Trying to duplicate nonexistent swap-page\n");
138 return 0;
139 }
140 p = type + swap_info;
141 if (offset >= SWAP_BITS) {
142 printk("swap_free: weirness\n");
143 return 0;
144 }
145 if (!p->swap_map[offset]) {
146 printk("swap_duplicate: trying to duplicate unused page\n");
147 return 0;
148 }
149 p->swap_map[offset]++;
150 return entry;
151 }
152
153 void swap_free(unsigned long entry)
154 {
155 struct swap_info_struct * p;
156 unsigned long offset, type;
157
158 if (!entry)
159 return;
160 type = SWP_TYPE(entry);
161 if (type == SHM_SWP_TYPE)
162 return;
163 if (type >= nr_swapfiles) {
164 printk("Trying to free nonexistent swap-page\n");
165 return;
166 }
167 p = & swap_info[type];
168 offset = SWP_OFFSET(entry);
169 if (offset >= SWAP_BITS) {
170 printk("swap_free: weirness\n");
171 return;
172 }
173 if (!(p->flags & SWP_USED)) {
174 printk("Trying to free swap from unused swap-device\n");
175 return;
176 }
177 while (set_bit(offset,p->swap_lockmap))
178 sleep_on(&lock_queue);
179 if (offset < p->lowest_bit)
180 p->lowest_bit = offset;
181 if (offset > p->highest_bit)
182 p->highest_bit = offset;
183 if (!p->swap_map[offset])
184 printk("swap_free: swap-space map bad (entry %08x)\n",entry);
185 else
186 if (!--p->swap_map[offset])
187 nr_swap_pages++;
188 if (!clear_bit(offset,p->swap_lockmap))
189 printk("swap_free: lock already cleared\n");
190 wake_up(&lock_queue);
191 }
192
193 void swap_in(unsigned long *table_ptr)
194 {
195 unsigned long entry;
196 unsigned long page;
197
198 entry = *table_ptr;
199 if (PAGE_PRESENT & entry) {
200 printk("trying to swap in present page\n");
201 return;
202 }
203 if (!entry) {
204 printk("No swap page in swap_in\n");
205 return;
206 }
207 if (SWP_TYPE(entry) == SHM_SWP_TYPE) {
208 shm_no_page ((unsigned long *) table_ptr);
209 return;
210 }
211 if (!(page = get_free_page(GFP_KERNEL))) {
212 oom(current);
213 page = BAD_PAGE;
214 } else
215 read_swap_page(entry, (char *) page);
216 if (*table_ptr != entry) {
217 free_page(page);
218 return;
219 }
220 *table_ptr = page | (PAGE_DIRTY | PAGE_PRIVATE);
221 swap_free(entry);
222 }
223
224 static inline int try_to_swap_out(unsigned long * table_ptr)
225 {
226 int i;
227 unsigned long page;
228 unsigned long entry;
229
230 page = *table_ptr;
231 if (!(PAGE_PRESENT & page))
232 return 0;
233 if (page >= high_memory)
234 return 0;
235 if (mem_map[MAP_NR(page)] & MAP_PAGE_RESERVED)
236 return 0;
237 if (PAGE_ACCESSED & page) {
238 *table_ptr &= ~PAGE_ACCESSED;
239 return 0;
240 }
241 for (i = 0; i < NR_LAST_FREE_PAGES; i++)
242 if (last_free_pages[i] == (page & PAGE_MASK))
243 return 0;
244 if (PAGE_DIRTY & page) {
245 page &= PAGE_MASK;
246 if (mem_map[MAP_NR(page)] != 1)
247 return 0;
248 if (!(entry = get_swap_page()))
249 return 0;
250 *table_ptr = entry;
251 invalidate();
252 write_swap_page(entry, (char *) page);
253 free_page(page);
254 return 1;
255 }
256 page &= PAGE_MASK;
257 *table_ptr = 0;
258 invalidate();
259 free_page(page);
260 return 1 + mem_map[MAP_NR(page)];
261 }
262
263
264
265
266
267
268 asmlinkage int sys_idle(void)
269 {
270 need_resched = 1;
271 return 0;
272 }
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287 #ifdef NEW_SWAP
288
289
290
291
292 #define SWAP_MIN 4
293 #define SWAP_MAX 32
294
295
296
297
298
299 #define SWAP_RATIO 128
300
301 static int swap_out(unsigned int priority)
302 {
303 static int swap_task;
304 int table;
305 int page;
306 long pg_table;
307 int loop;
308 int counter = NR_TASKS * 2 >> priority;
309 struct task_struct *p;
310
311 counter = NR_TASKS * 2 >> priority;
312 for(; counter >= 0; counter--, swap_task++) {
313
314
315
316
317 loop = 0;
318 while(1) {
319 if(swap_task >= NR_TASKS) {
320 swap_task = 1;
321 if(loop)
322
323 return 0;
324 loop = 1;
325 }
326
327 p = task[swap_task];
328 if(p && p->swappable && p->rss)
329 break;
330
331 swap_task++;
332 }
333
334
335
336
337 if(! p -> swap_cnt) {
338 p->dec_flt = (p->dec_flt * 3) / 4 + p->maj_flt - p->old_maj_flt;
339 p->old_maj_flt = p->maj_flt;
340
341 if(p->dec_flt >= SWAP_RATIO / SWAP_MIN) {
342 p->dec_flt = SWAP_RATIO / SWAP_MIN;
343 p->swap_cnt = SWAP_MIN;
344 } else if(p->dec_flt <= SWAP_RATIO / SWAP_MAX)
345 p->swap_cnt = SWAP_MAX;
346 else
347 p->swap_cnt = SWAP_RATIO / p->dec_flt;
348 }
349
350
351
352
353 for(table = p->swap_table; table < 1024; table++) {
354 pg_table = ((unsigned long *) p->tss.cr3)[table];
355 if(pg_table >= high_memory)
356 continue;
357 if(mem_map[MAP_NR(pg_table)] & MAP_PAGE_RESERVED)
358 continue;
359 if(!(PAGE_PRESENT & pg_table)) {
360 printk("swap_out: bad page-table at pg_dir[%d]: %08x\n",
361 table, pg_table);
362 ((unsigned long *) p->tss.cr3)[table] = 0;
363 continue;
364 }
365 pg_table &= 0xfffff000;
366
367
368
369
370 for(page = p->swap_page; page < 1024; page++) {
371 switch(try_to_swap_out(page + (unsigned long *) pg_table)) {
372 case 0:
373 break;
374
375 case 1:
376 p->rss--;
377
378 p->swap_table = table;
379 p->swap_page = page + 1;
380 if((--p->swap_cnt) == 0)
381 swap_task++;
382 return 1;
383
384 default:
385 p->rss--;
386 break;
387 }
388 }
389
390 p->swap_page = 0;
391 }
392
393
394
395
396
397 p->swap_table = 0;
398 }
399 return 0;
400 }
401
402 #else
403
404
405
406
407
408
409
410
411
412 static int swap_out(unsigned int priority)
413 {
414 static int swap_task = 1;
415 static int swap_table = 0;
416 static int swap_page = 0;
417 int counter = NR_TASKS*8;
418 int pg_table;
419 struct task_struct * p;
420
421 counter >>= priority;
422 check_task:
423 if (counter-- < 0)
424 return 0;
425 if (swap_task >= NR_TASKS) {
426 swap_task = 1;
427 goto check_task;
428 }
429 p = task[swap_task];
430 if (!p || !p->swappable) {
431 swap_task++;
432 goto check_task;
433 }
434 check_dir:
435 if (swap_table >= PTRS_PER_PAGE) {
436 swap_table = 0;
437 swap_task++;
438 goto check_task;
439 }
440 pg_table = ((unsigned long *) p->tss.cr3)[swap_table];
441 if (pg_table >= high_memory || (mem_map[MAP_NR(pg_table)] & MAP_PAGE_RESERVED)) {
442 swap_table++;
443 goto check_dir;
444 }
445 if (!(PAGE_PRESENT & pg_table)) {
446 printk("bad page-table at pg_dir[%d]: %08x\n",
447 swap_table,pg_table);
448 ((unsigned long *) p->tss.cr3)[swap_table] = 0;
449 swap_table++;
450 goto check_dir;
451 }
452 pg_table &= PAGE_MASK;
453 check_table:
454 if (swap_page >= PTRS_PER_PAGE) {
455 swap_page = 0;
456 swap_table++;
457 goto check_dir;
458 }
459 switch (try_to_swap_out(swap_page + (unsigned long *) pg_table)) {
460 case 0: break;
461 case 1: p->rss--; return 1;
462 default: p->rss--;
463 }
464 swap_page++;
465 goto check_table;
466 }
467
468 #endif
469
470 static int try_to_free_page(void)
471 {
472 int i=6;
473
474 while (i--) {
475 if (shrink_buffers(i))
476 return 1;
477 if (shm_swap(i))
478 return 1;
479 if (swap_out(i))
480 return 1;
481 }
482 return 0;
483 }
484
485
486
487
488
489
490 static inline void add_mem_queue(unsigned long addr, unsigned long * queue)
491 {
492 addr &= PAGE_MASK;
493 *(unsigned long *) addr = *queue;
494 *queue = addr;
495 }
496
497
498
499
500
501
502
503
504
505
506
507
508 void free_page(unsigned long addr)
509 {
510 if (addr < high_memory) {
511 unsigned short * map = mem_map + MAP_NR(addr);
512
513 if (*map) {
514 if (!(*map & MAP_PAGE_RESERVED)) {
515 unsigned long flag;
516
517 save_flags(flag);
518 cli();
519 if (!--*map) {
520 if (nr_secondary_pages < MAX_SECONDARY_PAGES) {
521 add_mem_queue(addr,&secondary_page_list);
522 nr_secondary_pages++;
523 restore_flags(flag);
524 return;
525 }
526 add_mem_queue(addr,&free_page_list);
527 nr_free_pages++;
528 }
529 restore_flags(flag);
530 }
531 return;
532 }
533 printk("Trying to free free memory (%08x): memory probabably corrupted\n",addr);
534 printk("PC = %08x\n",*(((unsigned long *)&addr)-1));
535 return;
536 }
537 }
538
539
540
541
542
543
544
545
546
547
548
549 #define REMOVE_FROM_MEM_QUEUE(queue,nr) \
550 cli(); \
551 if ((result = queue) != 0) { \
552 if (!(result & ~PAGE_MASK) && result < high_memory) { \
553 queue = *(unsigned long *) result; \
554 if (!mem_map[MAP_NR(result)]) { \
555 mem_map[MAP_NR(result)] = 1; \
556 nr--; \
557 last_free_pages[index = (index + 1) & (NR_LAST_FREE_PAGES - 1)] = result; \
558 restore_flags(flag); \
559 return result; \
560 } \
561 printk("Free page %08x has mem_map = %d\n", \
562 result,mem_map[MAP_NR(result)]); \
563 } else \
564 printk("Result = 0x%08x - memory map destroyed\n", result); \
565 queue = 0; \
566 nr = 0; \
567 } else if (nr) { \
568 printk(#nr " is %d, but " #queue " is empty\n",nr); \
569 nr = 0; \
570 } \
571 restore_flags(flag)
572
573
574
575
576
577
578
579
580
581
582 unsigned long __get_free_page(int priority)
583 {
584 unsigned long result, flag;
585 static unsigned long index = 0;
586
587
588
589
590
591
592 save_flags(flag);
593 repeat:
594 REMOVE_FROM_MEM_QUEUE(free_page_list,nr_free_pages);
595 if (priority == GFP_BUFFER)
596 return 0;
597 if (priority != GFP_ATOMIC)
598 if (try_to_free_page())
599 goto repeat;
600 REMOVE_FROM_MEM_QUEUE(secondary_page_list,nr_secondary_pages);
601 return 0;
602 }
603
604
605
606
607
608
609 static int try_to_unuse(unsigned int type)
610 {
611 int nr, pgt, pg;
612 unsigned long page, *ppage;
613 unsigned long tmp = 0;
614 struct task_struct *p;
615
616 nr = 0;
617
618
619
620
621 repeat:
622 for (; nr < NR_TASKS ; nr++) {
623 p = task[nr];
624 if (!p)
625 continue;
626 for (pgt = 0 ; pgt < PTRS_PER_PAGE ; pgt++) {
627 ppage = pgt + ((unsigned long *) p->tss.cr3);
628 page = *ppage;
629 if (!page)
630 continue;
631 if (!(page & PAGE_PRESENT) || (page >= high_memory))
632 continue;
633 if (mem_map[MAP_NR(page)] & MAP_PAGE_RESERVED)
634 continue;
635 ppage = (unsigned long *) (page & PAGE_MASK);
636 for (pg = 0 ; pg < PTRS_PER_PAGE ; pg++,ppage++) {
637 page = *ppage;
638 if (!page)
639 continue;
640 if (page & PAGE_PRESENT)
641 continue;
642 if (SWP_TYPE(page) != type)
643 continue;
644 if (!tmp) {
645 if (!(tmp = __get_free_page(GFP_KERNEL)))
646 return -ENOMEM;
647 goto repeat;
648 }
649 read_swap_page(page, (char *) tmp);
650 if (*ppage == page) {
651 *ppage = tmp | (PAGE_DIRTY | PAGE_PRIVATE);
652 ++p->rss;
653 swap_free(page);
654 tmp = 0;
655 }
656 goto repeat;
657 }
658 }
659 }
660 free_page(tmp);
661 return 0;
662 }
663
664 asmlinkage int sys_swapoff(const char * specialfile)
665 {
666 struct swap_info_struct * p;
667 struct inode * inode;
668 unsigned int type;
669 int i;
670
671 if (!suser())
672 return -EPERM;
673 i = namei(specialfile,&inode);
674 if (i)
675 return i;
676 p = swap_info;
677 for (type = 0 ; type < nr_swapfiles ; type++,p++) {
678 if ((p->flags & SWP_WRITEOK) != SWP_WRITEOK)
679 continue;
680 if (p->swap_file) {
681 if (p->swap_file == inode)
682 break;
683 } else {
684 if (!S_ISBLK(inode->i_mode))
685 continue;
686 if (p->swap_device == inode->i_rdev)
687 break;
688 }
689 }
690 iput(inode);
691 if (type >= nr_swapfiles)
692 return -EINVAL;
693 p->flags = SWP_USED;
694 i = try_to_unuse(type);
695 if (i) {
696 p->flags = SWP_WRITEOK;
697 return i;
698 }
699 nr_swap_pages -= p->pages;
700 iput(p->swap_file);
701 p->swap_file = NULL;
702 p->swap_device = 0;
703 free_page((long) p->swap_map);
704 p->swap_map = NULL;
705 free_page((long) p->swap_lockmap);
706 p->swap_lockmap = NULL;
707 p->flags = 0;
708 return 0;
709 }
710
711
712
713
714
715
716 asmlinkage int sys_swapon(const char * specialfile)
717 {
718 struct swap_info_struct * p;
719 struct inode * swap_inode;
720 unsigned int type;
721 unsigned char * tmp;
722 int i,j;
723
724 if (!suser())
725 return -EPERM;
726 p = swap_info;
727 for (type = 0 ; type < nr_swapfiles ; type++,p++)
728 if (!(p->flags & SWP_USED))
729 break;
730 if (type >= MAX_SWAPFILES)
731 return -EPERM;
732 if (type >= nr_swapfiles)
733 nr_swapfiles = type+1;
734 p->flags = SWP_USED;
735 p->swap_file = NULL;
736 p->swap_device = 0;
737 p->swap_map = NULL;
738 p->swap_lockmap = NULL;
739 p->lowest_bit = 0;
740 p->highest_bit = 0;
741 i = namei(specialfile,&swap_inode);
742 if (i) {
743 p->flags = 0;
744 return i;
745 }
746 if (swap_inode->i_count != 1) {
747 iput(swap_inode);
748 p->flags = 0;
749 return -EBUSY;
750 }
751 if (S_ISBLK(swap_inode->i_mode)) {
752 p->swap_device = swap_inode->i_rdev;
753 iput(swap_inode);
754 if (!p->swap_device) {
755 p->flags = 0;
756 return -ENODEV;
757 }
758 for (i = 0 ; i < nr_swapfiles ; i++) {
759 if (i == type)
760 continue;
761 if (p->swap_device == swap_info[i].swap_device) {
762 p->swap_device = 0;
763 p->flags = 0;
764 return -EBUSY;
765 }
766 }
767 } else if (S_ISREG(swap_inode->i_mode))
768 p->swap_file = swap_inode;
769 else {
770 iput(swap_inode);
771 p->flags = 0;
772 return -EINVAL;
773 }
774 tmp = (unsigned char *) get_free_page(GFP_USER);
775 p->swap_lockmap = (unsigned char *) get_free_page(GFP_USER);
776 if (!tmp || !p->swap_lockmap) {
777 printk("Unable to start swapping: out of memory :-)\n");
778 free_page((long) tmp);
779 free_page((long) p->swap_lockmap);
780 iput(p->swap_file);
781 p->swap_device = 0;
782 p->swap_file = NULL;
783 p->swap_map = NULL;
784 p->swap_lockmap = NULL;
785 p->flags = 0;
786 return -ENOMEM;
787 }
788 read_swap_page(SWP_ENTRY(type,0), (char *) tmp);
789 if (memcmp("SWAP-SPACE",tmp+4086,10)) {
790 printk("Unable to find swap-space signature\n");
791 free_page((long) tmp);
792 free_page((long) p->swap_lockmap);
793 iput(p->swap_file);
794 p->swap_device = 0;
795 p->swap_file = NULL;
796 p->swap_map = NULL;
797 p->swap_lockmap = NULL;
798 p->flags = 0;
799 return -EINVAL;
800 }
801 memset(tmp+PAGE_SIZE-10,0,10);
802 j = 0;
803 p->lowest_bit = 0;
804 p->highest_bit = 0;
805 for (i = 1 ; i < SWAP_BITS ; i++)
806 if (test_bit(i,tmp)) {
807 if (!p->lowest_bit)
808 p->lowest_bit = i;
809 p->highest_bit = i;
810 j++;
811 }
812 if (!j) {
813 printk("Empty swap-file\n");
814 free_page((long) tmp);
815 free_page((long) p->swap_lockmap);
816 iput(p->swap_file);
817 p->swap_device = 0;
818 p->swap_file = NULL;
819 p->swap_map = NULL;
820 p->swap_lockmap = NULL;
821 p->flags = 0;
822 return -EINVAL;
823 }
824 i = SWAP_BITS;
825 while (i--)
826 if (test_bit(i,tmp))
827 tmp[i] = 0;
828 else
829 tmp[i] = 0x80;
830 tmp[0] = 0x80;
831 p->swap_map = tmp;
832 p->flags = SWP_WRITEOK;
833 p->pages = j;
834 nr_swap_pages += j;
835 printk("Adding Swap: %dk swap-space\n",j<<2);
836 return 0;
837 }
838
839 void si_swapinfo(struct sysinfo *val)
840 {
841 unsigned int i, j;
842
843 val->freeswap = val->totalswap = 0;
844 for (i = 0; i < nr_swapfiles; i++) {
845 if (!(swap_info[i].flags & SWP_USED))
846 continue;
847 for (j = 0; j < SWAP_BITS; ++j)
848 switch (swap_info[i].swap_map[j]) {
849 case 128:
850 continue;
851 case 0:
852 ++val->freeswap;
853 default:
854 ++val->totalswap;
855 }
856 }
857 val->freeswap <<= PAGE_SHIFT;
858 val->totalswap <<= PAGE_SHIFT;
859 return;
860 }