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