zone_watermark_ok
函数定义:
693 int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
694 int classzone_idx, int can_try_harder, int gfp_high)
695 {
696 /* free_pages my go negative - that's OK */
697 long min = mark, free_pages = z->free_pages - (1 << order) + 1;
698 int o;
699
700 if (gfp_high)
701 min -= min / 2;
702 if (can_try_harder)
703 min -= min / 4;
704
705 if (free_pages <= min + z->lowmem_reserve[classzone_idx])
706 return 0;
707 for (o = 0; o < order; o++) {
708 /* At the next order, this order's pages become unavailable */
709 free_pages -= z->free_area[o].nr_free << o;
710
711 /* Require fewer higher order pages to be free */
712 min >>= 1;
713
714 if (free_pages <= min)
715 return 0;
716 }
717 return 1;
718 }
说明:在函数__alloc_pages中的restart第一次调用zone_watermark_ok(z, order, z->pages_low, classzone_idx,0 ,0))
需要满足下面两个条件:
- 除了被分配的页框,free_pages要大于这个区的mark和保留的大小的和。
- free_pages包含的是整个区可用内存,我现在申请的是2^order大小内存,则减去1-order大小的内存,
每次min变成1/2。
__alloc_pages()
723 struct page * fastcall
724 __alloc_pages(unsigned int gfp_mask, unsigned int order,
725 struct zonelist *zonelist)
726 {
727 const int wait = gfp_mask & __GFP_WAIT;
728 struct zone **zones, *z;
729 struct page *page;
730 struct reclaim_state reclaim_state;
731 struct task_struct *p = current;
732 int i;
733 int classzone_idx;
734 int do_retry;
735 int can_try_harder;
736 int did_some_progress;
737
738 might_sleep_if(wait);
739
740 /*
741 * The caller may dip into page reserves a bit more if the caller
742 * cannot run direct reclaim, or is the caller has realtime scheduling
743 * policy
744 */
745 can_try_harder = (unlikely(rt_task(p)) && !in_interrupt()) || !wait;
746
747 zones = zonelist->zones; /* the list of zones suitable for gfp_mask */
748
749 if (unlikely(zones[0] == NULL)) {
750 /* Should this ever happen?? */
751 return NULL;
752 }
753
754 classzone_idx = zone_idx(zones[0]);
755
756 /*printk(KERN_ERR "tom invork 000 zone_idx=%x order=%x\r\n",zone_idx(z),order);*/
757 restart:
758 /* Go through the zonelist once, looking for a zone with enough free */
759 for (i = 0; (z = zones[i]) != NULL; i++) {
760
761 if (!zone_watermark_ok(z, order, z->pages_low,
762 classzone_idx, 0, 0))
763 {
764 printk(KERN_ERR "tom invork 111 i=%x zone_idx=%x order=%x\r\n",i,zone_idx(z),order);
765 continue;
766 }
767
768 printk(KERN_ERR "tom 111-2222\r\n");
769 page = buffered_rmqueue(z, order, gfp_mask);
770 if (page)
771 goto got_pg;
772 }
773
774
775 for (i = 0; (z = zones[i]) != NULL; i++)
776 {
777 printk(KERN_ERR "tom invork wakeup_kswapd\r\n");
778 wakeup_kswapd(z, order);
779 }
780
781 /*
782 * Go through the zonelist again. Let __GFP_HIGH and allocations
783 * coming from realtime tasks to go deeper into reserves
784 */
785 for (i = 0; (z = zones[i]) != NULL; i++) {
786 printk(KERN_ERR "tom invork 222 zone_idx=%x\r\n",zone_idx(zones[i]));
787 if (!zone_watermark_ok(z, order, z->pages_min,
788 classzone_idx, can_try_harder,
789 gfp_mask & __GFP_HIGH))
790 continue;
791
792 page = buffered_rmqueue(z, order, gfp_mask);
793 if (page)
794 goto got_pg;
795 }
796
797 printk(KERN_ERR "666=%x\r\n",((p->flags & PF_MEMALLOC) || unlikely(test_thread_flag(TIF_MEMDIE))) && !in_interrupt());
798 /* This allocation should allow future memory freeing. */
799 if (((p->flags & PF_MEMALLOC) || unlikely(test_thread_flag(TIF_MEMDIE))) && !in_interrupt()) {
800 /* go through the zonelist yet again, ignoring mins */
801 /*printk(KERN_ERR "tom invork 333 zone_idx=%x\r\n",zone_idx(zones[i]));*/
802 printk(KERN_ERR "tom invork 10000\r\n");
803 for (i = 0; (z = zones[i]) != NULL; i++) {
804 printk(KERN_ERR "tom invork 888 zone_idx=%x\r\n",zone_idx(zones[i]));
805 page = buffered_rmqueue(z, order, gfp_mask);
806 if (page)
807 goto got_pg;
808 }
809 goto nopage;
810 }
811
812 printk(KERN_ERR "777\r\n");
813 /* Atomic allocations - we can't balance anything */
814 if (!wait)
815 {
816 printk(KERN_ERR "tom invork 444 zone_idx=%x\r\n",zone_idx(zones[i]));
817 goto nopage;
818 }
819
820 rebalance:
821 cond_resched();
822
823 /* We now go into synchronous reclaim */
824 p->flags |= PF_MEMALLOC;
825 reclaim_state.reclaimed_slab = 0;
826 p->reclaim_state = &reclaim_state;
827
828 did_some_progress = try_to_free_pages(zones, gfp_mask, order);
829
830 p->reclaim_state = NULL;
831 p->flags &= ~PF_MEMALLOC;
832
833 cond_resched();
834
835 if (likely(did_some_progress)) {
836 /*
837 * Go through the zonelist yet one more time, keep
838 * very high watermark here, this is only to catch
839 * a parallel oom killing, we must fail if we're still
840 * under heavy pressure.
841 */
842 for (i = 0; (z = zones[i]) != NULL; i++) {
843 if (!zone_watermark_ok(z, order, z->pages_min,
844 classzone_idx, can_try_harder,
845 gfp_mask & __GFP_HIGH))
846 continue;
847
848 page = buffered_rmqueue(z, order, gfp_mask);
849 if (page)
850 goto got_pg;
851 }
852 } else if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) {
853 /*
854 * Go through the zonelist yet one more time, keep
855 * very high watermark here, this is only to catch
856 * a parallel oom killing, we must fail if we're still
857 * under heavy pressure.
858 */
859 for (i = 0; (z = zones[i]) != NULL; i++) {
860 if (!zone_watermark_ok(z, order, z->pages_high,
861 classzone_idx, 0, 0))
862 continue;
863
864 page = buffered_rmqueue(z, order, gfp_mask);
865 if (page)
866 goto got_pg;
867 }
868
869 out_of_memory(gfp_mask);
870 goto restart;
870 goto restart;
871 }
872
873 /*
874 * Don't let big-order allocations loop unless the caller explicitly
875 * requests that. Wait for some write requests to complete then retry.
876 *
877 * In this implementation, __GFP_REPEAT means __GFP_NOFAIL for order
878 * <= 3, but that may not be true in other implementations.
879 */
880 do_retry = 0;
881 if (!(gfp_mask & __GFP_NORETRY)) {
882 if ((order <= 3) || (gfp_mask & __GFP_REPEAT))
883 do_retry = 1;
884 if (gfp_mask & __GFP_NOFAIL)
885 do_retry = 1;
886 }
887 if (do_retry) {
888 blk_congestion_wait(WRITE, HZ/50);
889 goto rebalance;
890 }
891
892 nopage:
893 if (!(gfp_mask & __GFP_NOWARN) && printk_ratelimit()) {
894 /*printk(KERN_WARNING "%s: page allocation failure."*/
895 printk(KERN_ERR "%s: page allocation failure."
896 " order:%d, mode:0x%x\n",
897 p->comm, order, gfp_mask);
898 dump_stack();
899 }
900 return NULL;
901 got_pg:
902 zone_statistics(zonelist, z);
903 return page;
904 }
说明:
我现在分配内存策略用的是从high–>normal—>dma的顺序
1)虚拟分配内存 2G,使用memtester 1900M,进行这个函数的逻辑测试。
2)在761行进行zone_watermark_ok水位检测,传入的参数zone->pages_low,进行检查,首先分配完HIGH ZONE,接着分配完NORMAL ZONE,最后DMA ZONE,等到DMA ZONE的水位检测不OK时候。
3)在755行,进入wakeup_kswapd唤醒kswapd,进行内存释放。
4)进入785行,减低水位,进行水位检查。
5)