buddy页分配

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))
需要满足下面两个条件:

  1. 除了被分配的页框,free_pages要大于这个区的mark和保留的大小的和。
  2. 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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值