Annotation of linux/mm/swap.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *  linux/mm/swap.c
        !             3:  *
        !             4:  *  (C) 1991  Linus Torvalds
        !             5:  */
        !             6: 
        !             7: /*
        !             8:  * This file should contain most things doing the swapping from/to disk.
        !             9:  * Started 18.12.91
        !            10:  */
        !            11: 
        !            12: #include <string.h>
        !            13: 
        !            14: #include <linux/mm.h>
        !            15: #include <linux/sched.h>
        !            16: #include <linux/head.h>
        !            17: #include <linux/kernel.h>
        !            18: 
        !            19: #define SWAP_BITS (4096<<3)
        !            20: 
        !            21: #define bitop(name,op) \
        !            22: static inline int name(char * addr,unsigned int nr) \
        !            23: { \
        !            24: int __res; \
        !            25: __asm__ __volatile__("bt" op " %1,%2; adcl $0,%0" \
        !            26: :"=g" (__res) \
        !            27: :"r" (nr),"m" (*(addr)),"0" (0)); \
        !            28: return __res; \
        !            29: }
        !            30: 
        !            31: bitop(bit,"")
        !            32: bitop(setbit,"s")
        !            33: bitop(clrbit,"r")
        !            34: 
        !            35: static char * swap_bitmap = NULL;
        !            36: int SWAP_DEV = 0;
        !            37: 
        !            38: /*
        !            39:  * We never page the pages in task[0] - kernel memory.
        !            40:  * We page all other pages.
        !            41:  */
        !            42: #define FIRST_VM_PAGE (TASK_SIZE>>12)
        !            43: #define LAST_VM_PAGE (1024*1024)
        !            44: #define VM_PAGES (LAST_VM_PAGE - FIRST_VM_PAGE)
        !            45: 
        !            46: static int get_swap_page(void)
        !            47: {
        !            48:        int nr;
        !            49: 
        !            50:        if (!swap_bitmap)
        !            51:                return 0;
        !            52:        for (nr = 1; nr < 32768 ; nr++)
        !            53:                if (clrbit(swap_bitmap,nr))
        !            54:                        return nr;
        !            55:        return 0;
        !            56: }
        !            57: 
        !            58: void swap_free(int swap_nr)
        !            59: {
        !            60:        if (!swap_nr)
        !            61:                return;
        !            62:        if (swap_bitmap && swap_nr < SWAP_BITS)
        !            63:                if (!setbit(swap_bitmap,swap_nr))
        !            64:                        return;
        !            65:        printk("Swap-space bad (swap_free())\n\r");
        !            66:        return;
        !            67: }
        !            68: 
        !            69: void swap_in(unsigned long *table_ptr)
        !            70: {
        !            71:        int swap_nr;
        !            72:        unsigned long page;
        !            73: 
        !            74:        if (!swap_bitmap) {
        !            75:                printk("Trying to swap in without swap bit-map");
        !            76:                return;
        !            77:        }
        !            78:        if (1 & *table_ptr) {
        !            79:                printk("trying to swap in present page\n\r");
        !            80:                return;
        !            81:        }
        !            82:        swap_nr = *table_ptr >> 1;
        !            83:        if (!swap_nr) {
        !            84:                printk("No swap page in swap_in\n\r");
        !            85:                return;
        !            86:        }
        !            87:        if (!(page = get_free_page()))
        !            88:                oom();
        !            89:        read_swap_page(swap_nr, (char *) page);
        !            90:        if (setbit(swap_bitmap,swap_nr))
        !            91:                printk("swapping in multiply from same page\n\r");
        !            92:        *table_ptr = page | (PAGE_DIRTY | 7);
        !            93: }
        !            94: 
        !            95: int try_to_swap_out(unsigned long * table_ptr)
        !            96: {
        !            97:        unsigned long page;
        !            98:        unsigned long swap_nr;
        !            99: 
        !           100:        page = *table_ptr;
        !           101:        if (!(PAGE_PRESENT & page))
        !           102:                return 0;
        !           103:        if (page - LOW_MEM > PAGING_MEMORY)
        !           104:                return 0;
        !           105:        if (PAGE_DIRTY & page) {
        !           106:                page &= 0xfffff000;
        !           107:                if (mem_map[MAP_NR(page)] != 1)
        !           108:                        return 0;
        !           109:                if (!(swap_nr = get_swap_page()))
        !           110:                        return 0;
        !           111:                *table_ptr = swap_nr<<1;
        !           112:                invalidate();
        !           113:                write_swap_page(swap_nr, (char *) page);
        !           114:                free_page(page);
        !           115:                return 1;
        !           116:        }
        !           117:        *table_ptr = 0;
        !           118:        invalidate();
        !           119:        free_page(page);
        !           120:        return 1;
        !           121: }
        !           122: 
        !           123: /*
        !           124:  * Ok, this has a rather intricate logic - the idea is to make good
        !           125:  * and fast machine code. If we didn't worry about that, things would
        !           126:  * be easier.
        !           127:  */
        !           128: int swap_out(void)
        !           129: {
        !           130:        static int dir_entry = FIRST_VM_PAGE>>10;
        !           131:        static int page_entry = -1;
        !           132:        int counter = VM_PAGES;
        !           133:        int pg_table;
        !           134: 
        !           135:        while (counter>0) {
        !           136:                pg_table = pg_dir[dir_entry];
        !           137:                if (pg_table & 1)
        !           138:                        break;
        !           139:                counter -= 1024;
        !           140:                dir_entry++;
        !           141:                if (dir_entry >= 1024)
        !           142:                        dir_entry = FIRST_VM_PAGE>>10;
        !           143:        }
        !           144:        pg_table &= 0xfffff000;
        !           145:        while (counter-- > 0) {
        !           146:                page_entry++;
        !           147:                if (page_entry >= 1024) {
        !           148:                        page_entry = 0;
        !           149:                repeat:
        !           150:                        dir_entry++;
        !           151:                        if (dir_entry >= 1024)
        !           152:                                dir_entry = FIRST_VM_PAGE>>10;
        !           153:                        pg_table = pg_dir[dir_entry];
        !           154:                        if (!(pg_table&1))
        !           155:                                if ((counter -= 1024) > 0)
        !           156:                                        goto repeat;
        !           157:                                else
        !           158:                                        break;
        !           159:                        pg_table &= 0xfffff000;
        !           160:                }
        !           161:                if (try_to_swap_out(page_entry + (unsigned long *) pg_table))
        !           162:                        return 1;
        !           163:        }
        !           164:        printk("Out of swap-memory\n\r");
        !           165:        return 0;
        !           166: }
        !           167: 
        !           168: /*
        !           169:  * Get physical address of first (actually last :-) free page, and mark it
        !           170:  * used. If no free pages left, return 0.
        !           171:  */
        !           172: unsigned long get_free_page(void)
        !           173: {
        !           174: register unsigned long __res asm("ax");
        !           175: 
        !           176: repeat:
        !           177:        __asm__("std ; repne ; scasb\n\t"
        !           178:                "jne 1f\n\t"
        !           179:                "movb $1,1(%%edi)\n\t"
        !           180:                "sall $12,%%ecx\n\t"
        !           181:                "addl %2,%%ecx\n\t"
        !           182:                "movl %%ecx,%%edx\n\t"
        !           183:                "movl $1024,%%ecx\n\t"
        !           184:                "leal 4092(%%edx),%%edi\n\t"
        !           185:                "rep ; stosl\n\t"
        !           186:                "movl %%edx,%%eax\n"
        !           187:                "1:"
        !           188:                :"=a" (__res)
        !           189:                :"0" (0),"i" (LOW_MEM),"c" (PAGING_PAGES),
        !           190:                "D" (mem_map+PAGING_PAGES-1)
        !           191:                :"di","cx","dx");
        !           192:        if (__res >= HIGH_MEMORY)
        !           193:                goto repeat;
        !           194:        if (!__res && swap_out())
        !           195:                goto repeat;
        !           196:        return __res;
        !           197: }
        !           198: 
        !           199: void init_swapping(void)
        !           200: {
        !           201:        extern int *blk_size[];
        !           202:        int swap_size,i,j;
        !           203: 
        !           204:        if (!SWAP_DEV)
        !           205:                return;
        !           206:        if (!blk_size[MAJOR(SWAP_DEV)]) {
        !           207:                printk("Unable to get size of swap device\n\r");
        !           208:                return;
        !           209:        }
        !           210:        swap_size = blk_size[MAJOR(SWAP_DEV)][MINOR(SWAP_DEV)];
        !           211:        if (!swap_size)
        !           212:                return;
        !           213:        if (swap_size < 100) {
        !           214:                printk("Swap device too small (%d blocks)\n\r",swap_size);
        !           215:                return;
        !           216:        }
        !           217:        swap_size >>= 2;
        !           218:        if (swap_size > SWAP_BITS)
        !           219:                swap_size = SWAP_BITS;
        !           220:        swap_bitmap = (char *) get_free_page();
        !           221:        if (!swap_bitmap) {
        !           222:                printk("Unable to start swapping: out of memory :-)\n\r");
        !           223:                return;
        !           224:        }
        !           225:        read_swap_page(0,swap_bitmap);
        !           226:        if (strncmp("SWAP-SPACE",swap_bitmap+4086,10)) {
        !           227:                printk("Unable to find swap-space signature\n\r");
        !           228:                free_page((long) swap_bitmap);
        !           229:                swap_bitmap = NULL;
        !           230:                return;
        !           231:        }
        !           232:        memset(swap_bitmap+4086,0,10);
        !           233:        for (i = 0 ; i < SWAP_BITS ; i++) {
        !           234:                if (i == 1)
        !           235:                        i = swap_size;
        !           236:                if (bit(swap_bitmap,i)) {
        !           237:                        printk("Bad swap-space bit-map\n\r");
        !           238:                        free_page((long) swap_bitmap);
        !           239:                        swap_bitmap = NULL;
        !           240:                        return;
        !           241:                }
        !           242:        }
        !           243:        j = 0;
        !           244:        for (i = 1 ; i < swap_size ; i++)
        !           245:                if (bit(swap_bitmap,i))
        !           246:                        j++;
        !           247:        if (!j) {
        !           248:                free_page((long) swap_bitmap);
        !           249:                swap_bitmap = NULL;
        !           250:                return;
        !           251:        }
        !           252:        printk("Swap device ok: %d pages (%d bytes) swap-space\n\r",j,j*4096);
        !           253: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.