Chinaunix首页 | 论坛 | 博客
  • 博客访问: 602479
  • 博文数量: 113
  • 博客积分: 2554
  • 博客等级: 少校
  • 技术积分: 1428
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-21 19:53
文章分类

全部博文(113)

文章存档

2014年(1)

2013年(2)

2012年(94)

2011年(16)

分类: LINUX

2011-12-22 10:36:11

  1. static inline int handle_pte_fault(struct mm_struct *mm,
  2.     struct vm_area_struct * vma, unsigned long address,
  3.     int write_access, pte_t * pte)
  4. {
  5.     pte_t entry;

  6.     /*
  7.      * We need the page table lock to synchronize with kswapd
  8.      * and the SMP-safe atomic PTE updates.
  9.      */
  10.     spin_lock(&mm->page_table_lock);
  11.     entry = *pte;
  12.     if (!pte_present(entry)) {检查是否在内存中
  13.         /*
  14.          * If it truly wasn't present, we know that kswapd
  15.          * and the PTE updates will not touch it later. So
  16.          * drop the lock.
  17.          */
  18.         spin_unlock(&mm->page_table_lock);
  19.         if (pte_none(entry))
  20.             return do_no_page(mm, vma, address, write_access, pte);//映射没有建立
  21.         return do_swap_page(mm, vma, address, pte, pte_to_swp_entry(entry), write_access);//没有建立映射,从交换设备换入
  22.     }

  23.     if (write_access) {
  24.         if (!pte_write(entry))
  25.             return do_wp_page(mm, vma, address, pte, entry);

  26.         entry = pte_mkdirty(entry);
  27.     }
  28.     entry = pte_mkyoung(entry);
  29.     establish_pte(vma, address, pte, entry);
  30.     spin_unlock(&mm->page_table_lock);
  31.     return 1;
  32. }


  33. static int do_swap_page(struct mm_struct * mm,
  34.     struct vm_area_struct * vma, unsigned long address,
  35.     pte_t * page_table, swp_entry_t entry, int write_access)
  36. {
  37.     struct page *page = lookup_swap_cache(entry);//是否还在交换区中
  38.     pte_t pte;

  39.     if (!page) {
  40.         lock_kernel();
  41.         swapin_readahead(entry);//预读
  42.         page = read_swap_cache(entry);//再读
  43.         unlock_kernel();
  44.         if (!page)
  45.             return -1;
  46. /*对i386为空操作*/
  47.         flush_page_to_ram(page);
  48.         flush_icache_page(vma, page);
  49.     }

  50.     mm->rss++;

  51.     pte = mk_pte(page, vma->vm_page_prot);

  52.     /*
  53.      * Freeze the "shared"ness of the page, ie page_count + swap_count.
  54.      * Must lock page before transferring our swap count to already
  55.      * obtained page count.
  56.      */
  57.     lock_page(page);
  58.     swap_free(entry);
  59.     if (write_access && !is_page_shared(page))
  60.         pte = pte_mkwrite(pte_mkdirty(pte));
  61.     UnlockPage(page);

  62.     set_pte(page_table, pte);
  63.     /* No need to invalidate - it was non-present before */
  64.     update_mmu_cache(vma, address, pte);//空操作
  65.     return 1;    /* Minor fault */
  66. }

  67. #define read_swap_cache(entry) read_swap_cache_async(entry, 1);
  68. /*
  69.  * Locate a page of swap in physical memory, reserving swap cache space
  70.  * and reading the disk if it is not already cached. If wait==0, we are
  71.  * only doing readahead, so don't worry if the page is already locked.
  72.  *
  73.  * A failure return means that either the page allocation failed or that
  74.  * the swap entry is no longer in use.
  75.  */

  76. struct page * read_swap_cache_async(swp_entry_t entry, int wait)
  77. {
  78.     struct page *found_page = 0, *new_page;
  79.     unsigned long new_page_addr;
  80.     
  81.     /*
  82.      * Make sure the swap entry is still in use.
  83.      */
  84.     if (!swap_duplicate(entry))    /* Account for the swap cache */递增页面共享技术
  85.         goto out;
  86.     /*
  87.      * Look for the page in the swap cache.
  88.      */
  89.     found_page = lookup_swap_cache(entry);
  90.     if (found_page)
  91.         goto out_free_swap;

  92.     new_page_addr = __get_free_page(GFP_USER);
  93.     if (!new_page_addr)
  94.         goto out_free_swap;    /* Out of memory */
  95.     new_page = virt_to_page(new_page_addr);

  96.     /*
  97.      * Check the swap cache again, in case we stalled above.
  98.      */
  99.     found_page = lookup_swap_cache(entry);
  100.     if (found_page)
  101.         goto out_free_page;
  102.     /*
  103.      * Add it to the swap cache and read its contents.
  104.      */
  105.     lock_page(new_page);
  106.     add_to_swap_cache(new_page, entry);
  107.     rw_swap_page(READ, new_page, wait);
  108.     return new_page;

  109. out_free_page:
  110.     page_cache_release(new_page);
  111. out_free_swap:
  112.     swap_free(entry);
  113. out:
  114.     return found_page;
  115. }
阅读(2077) | 评论(0) | 转发(0) |
0

上一篇:buddy算法

下一篇:页面换出

给主人留下些什么吧!~~