LinuxÄÚ´æ¹ÜÀíÏê½â(2)

2019-08-31 09:47

min_free_kbytes = int_sqrt(lowmem_kbytes * 16);

min_free_kbytesÓɵ±Ç°Ö±½ÓÓ³ÉäÇøµÄÎïÀíÄÚ´æÊýÁ¿¾ö¶¨¡£Ò²¼´ZONE_DMAºÍZONE_NORMALÄÚ´æ¹ÜÀíÇøµÄ¿ÉÓÃÒ³¿òÊý¾ö¶¨£¬Õâ¿ÉÒÔ Í¨¹ý

nr_free_buffer_pages»ñÈ¡¡£¾¡¹Ü¿ÉÒÔͨ¹ý/proc/sys/vm/min_free_kbytesÀ´Ð޸ĸÃËüµÄ´óС£¬µ«ÊÇ min_free_kbytesµÄ³õʼֵ·¶Î§±ØÐëÊÇ[128K, 64M]¡£¹ÜÀíÇøÃèÊö·ûÖеÄpages_min³ÉÔ±´æ´¢Á˹ÜÀíÇøÄÚ±£ÁôÒ³¿òµÄÊýÄ¿¡£Õâ¸ö×Ö¶ÎÓëpages_lowºÍpages_high×Ö¶ÎÒ»Æð±»ÓÃÔÚÄÚ ´æ·ÖÅäºÍ»ØÊÕËã·¨ÖС£pages_low×Ö¶Î×ÜÊDZ»ÉèΪpages_minµÄÖµµÄ5/4£¬¶øpages_highÔò×ÜÊDZ»ÉèΪpages_minµÄÖµµÄ3 /2¡£ÕâЩֵÔÚÄ£¿é¿ì³õʼ»¯module_initµ÷ÓõÄinit_per_zone_pages_minÖб»ÉèÖᣠ±í 27. Ò³Ãæ·ÖÅä¿ØÖÆ Ãû³Æ pages_low pages_min * 5 / 4 pages_high pages_min * 3 / 2

free_area_init_coreÖжԹÜÀíÇø³õʼ»¯µÄ´úÂ벿·ÖÈçÏ£¬ºóÐøÕ½ڽ«¶Ô¸Ãº¯Êý½øÒ»²½·ÖÎö¡£

zone->spanned_pages = size; zone->present_pages = realsize; zone->name = zone_names[j]; spin_lock_init(&zone->lock); spin_lock_init(&zone->lru_lock); zone_seqlock_init(zone); zone->zone_pgdat = pgdat;

zone->prev_priority = DEF_PRIORITY; zone_pcp_init(zone); for_each_lru(l) { INIT_LIST_HEAD(&zone->lru[l].list); zone->lru[l].nr_scan = 0; }

zone->recent_rotated[0] = 0; zone->recent_rotated[1] = 0; zone->recent_scanned[0] = 0; zone->recent_scanned[1] = 0; zap_zone_vm_stats(zone);

´óС pages_min min_free_kbytes >> (PAGE_SHIFT - 10) zone->flags = 0;

13.2. page¹ÜÀíÏî

struct page { unsigned long flags; /* Atomic flags, some possibly * updated asynchronously */ atomic_t _count; /* Usage count, see below. */ union { atomic_t _mapcount; /* Count of ptes mapped in mms, * to show when page is mapped * & limit reverse map searches. */ struct { /* SLUB */ u16 inuse; u16 objects; }; };

ÿһ¸öÎïÀíÒ³¿ò¶¼ÐèÒªÒ»¸ö¶ÔÓ¦µÄpage½á¹¹À´½øÐйÜÀí£º¼Ç¼·ÖÅä״̬£¬·ÖÅäºÍ»ØÊÕ£¬»¥³âÒÔ¼°Í¬²½²Ù×÷¡£¶Ô¸Ã½á¹¹³ÉÔ±µÄ½âÊÍÈçÏ£º

flagÓò´æ·Åµ±Ç°Ò³¿òµÄÒ³±êÖ¾£¬Ëü´æ´¢ÁËÌåϵ½á¹¹Î޹صÄ״̬£¬×¨ÃŹ©LinuxÄÚºË×ÔÉíʹÓ᣸ñêÖ¾¿ÉÄܵÄÖµ¶¨ÒåÔÚinclude/linux/page-flags.hÖС£ ? Ô­×Ó¼ÆÊý³ÉÔ±_countÔòÖ¸Ã÷Á˵±Ç°Ò³¿òµÄÒýÓüÆÊý£¬µ±¸ÃֵΪ0ʱ£¬¾Í˵Ã÷ËüûÓб»Ê¹Ó㬴ËʱÔÚзÖÅäÄÚ´æÊ±Ëü¾Í¿ÉÒÔ±»Ê¹Óá£Äں˴úÂëÓ¦¸Ãͨ¹ýpage_countÀ´·ÃÎÊËü£¬¶ø·ÇÖ±½Ó·ÃÎÊ¡£

? Ô­×Ó¼ÆÊý³ÉÔ±_mapcount±íʾÔÚÒ³±íÖÐÓжàÉÙÒ³Ö¸Ïò¸ÃÒ³¿ò¡£ÔÚSLUBÖÐËü±»inuseºÍobjects´úÌæ¡£

?

include/linux/page-flags.h enum pageflags {

PG_locked, /* Page is locked. Don't touch. */ PG_error,

PG_referenced, PG_uptodate, PG_dirty, PG_lru, PG_active, ......

__NR_PAGEFLAGS, ...... }

ÒÔÉÏÊÇÒ³±ê־λµÄ¿ÉÄÜȡֵ£¬Í¨³£²»Ó¦¸ÃÖ±½ÓʹÓÃÕâЩ±ê־룬¶øÓ¦¸ÃÄÚºËÔ¤¶¨ÒåºÃµÄºê£¬ËüÃÇÔÚÏàͬµÄÍ·ÎļþÖб»¶¨Ò壬µ«ÊÇËüÃÇÊDZ»¼ä½Ó¶¨ÒåµÄ£¬Ò²¼´Í¨¹ý##Á¬×Ö·ûÀ´Í³Ò»¶ÔËüÃǽøÐж¨Òå¡£ #define TESTPAGEFLAG(uname, lname) \\

static inline int Page##uname(struct page *page) \\ { return test_bit(PG_##lname, &page->flags); } ......

TESTPAGEFLAG(Locked, locked) PAGEFLAG(Error, error)

PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced) ±í 28. Ò³±êÖ¾ºêº¯Êý

ºê TESTPAGEFLAG(uname, lname) SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname)[a] TESTSETFLAG(uname, lname) TESTCLEARFLAG(uname, lname) [b]À©Õ¹º¯Êý/ºê Page##uname SetPage##uname ClearPage##uname TestSetPage##uname TestClearPage##uname TESTPAGEFLAG SETPAGEFLAG CLEARPAGEFLAG Page##uname TESTSETFLAG TESTCLEARFLAG SetPage##uname ClearPage##unam __ClearPage##uname ÓÃ; ²âÊÔPG_##lnameλ ÉèÖÃPG_##lnameλ Çå³ýPG_##lnameλ ²âÊÔ²¢ÉèÖÃPG_##lname ²âÊÔ²¢Çå³ýPG_##lname µ±ÓÚͬʱÀ©Õ¹ÁËÈý¸öºê£¬Ò²¼´Èý¸öº¯Êý ÓÀÔ¶·µ»Ø0 µ±ÓÚͬʱÀ©Õ¹ÁËÁ½¸öºê£¬Ò²¼´Á½¸öº¯Êý ¿Õ²Ù×÷ ¿Õ²Ù×÷ ¿Õ²Ù×÷ PAGEFLAG(uname, lname) PAGEFLAG_FALSE(uname) TESTSCFLAG(uname, lname) SETPAGEFLAG_NOOP(uname) CLEARPAGEFLAG_NOOP(uname) __CLEARPAGEFLAG_NOOP(uname) TESTCLEARFLAG_FALSE(uname) [a] TestClearPage##uname ÓÀÔ¶·µ»Ø0 ÒÔÉÏÈý¸öºê·Ö±ð¶ÔÓ¦test_bit£¬set_bitºÍclear_bit£¬ÊÇÔ­×Ó²Ù×÷£¬ÓëËüÃǶÔÓ¦µÄÊÇÓÐÈý¸ö¿ªÍ· ΪÏ»®ÏßµÄͬÃûº¯Êý__SETPAGEFLAGµÈÓëËüÃÇÏà¶ÔÓ¦£¬µ«²»ºê ÊÇÔ­×Ó²Ù×÷£¬ÕâÀï²»ÔÙÁгö¡£ [b] À©Õ¹º¯Êý/ºê ÓÃ; Óë´Ë¶ÔÓ¦Ò²ÓÐ__PAGEFLAGµÄºê´æÔÚ¡£ flagsʵ¼ÊÉÏΪÁ½²¿·Ö£º±êÖ¾Çø(Flags Area)´Ó×îµÍ´¦ÏòÉÏÀ©Õ¹µ½µÚ

__NR_PAGEFLAGSλ;×Ö¶ÎÇø(Fields Area)Ôò´Ó×î¸ßλÏòµÍλÀ©Õ¹¡£×Ö¶ÎÇøÓÃÀ´ÊµÏÖ¹ÜÀíÇø£¬ÄÚ´æ½ÚµãºÍÏ¡ÊèÄÚ´æµÄÓ³Éä¡£ | FIELD | ... | FLAGS |

N-1 ^ 0

(__NR_PAGEFLAGS)

_countÒýÓüÆÊý²»Ó¦±»Ö±½ÓÒýÓã¬ÄÚºËÌṩÁËһϵÁеÄÄÚÁªº¯ÊýÀ´²Ù×÷Ëü£¬Í¨³£ËüÃDZ»¶¨ÒåÔÚinclude/linux/mm.hÖС£ ±í 29. Ò³ÒýÓüÆÊýº¯Êý

º¯ÊýÃû page_count get_page ÓÃ; ¶ÁÈ¡ÒýÓüÆÊý ÒýÓüÆÊý¼Ó1 init_page_count ³õʼ»¯ÒýÓüÆÊýΪ1 _mapcountÓë_countÒýÓüÆÊýÀàËÆ£¬²»Ó¦±»Ö±½ÓÒýÓã¬ÄÚºËÌṩÁËһϵÁеÄÄÚÁªº¯ÊýÀ´²Ù×÷Ëü£¬ËüÃÇÒ²±»¶¨ÒåÔÚinclude/linux/mm.hÖС£ ±í 30. Ò³ÒýÓüÆÊýº¯Êý

º¯ÊýÃû reset_page_mapcount page_mapcount page_mapped [a] ÓÃ; ³õʼ»¯ÒýÓüÆÊýΪ-1[a] ¶ÁÈ¡ÒýÓüÆÊý²¢¼Ó1µÄÖµ ¸Ãº¯Êý¸ù¾ÝÒýÓüÆÊýÖµÊÇ·ñ´óÓÚµÈÓÚ0£¬ÅжϸÃÒ³¿òÊÇ·ñ±»Ó³Éä¡£ ûÓгõʼ»¯Îª0ÊÇÒòΪatomic_inc_and_testºÍatomic_add_negativeµÄ²Ù×÷£¬¶Ô¸ÃÒýÓüÆÊýµÄ¼Ó¼õÊÇÓÉÕâÁ½¸öº¯ÊýÍê³ÉµÄ¡£

union { struct {

unsigned long private;

/* Mapping-private opaque data: * usually used for buffer_heads * if PagePrivate set; used for

* swp_entry_t if PageSwapCache; * indicates order in the buddy * system if PG_buddy is set.

*/ struct address_space *mapping; /* If low bit clear, points to * inode address_space, or NULL. * If page mapped as anonymous * memory, low bit is set, and * it points to anon_vma object: * see PAGE_MAPPING_ANON below. */ };

#if USE_SPLIT_PTLOCKS spinlock_t ptl; #endif struct kmem_cache *slab; /* SLUB: Pointer to slab */ struct page *first_page; /* Compound tail pages */ }; union { pgoff_t index; /* Our offset within mapping. */ void *freelist; /* SLUB: freelist req. slab lock */ }; struct list_head lru; /* Pageout list, eg. active_list ÓÉÓÚÄÚºËÒýÈëÁ˺ܶàµÄ·ÖÅä»úÖÆ£¬ÒÔÍù¼ä¼òµ¥µÄpage½á¹¹±äµÃÔ½À´Ô½¸´ÔÓ¡£ÎªÁËÎÞ·ìÒýÈëslub·ÖÅäÆ÷À´·ÖÅäСÓÚ1¸öÒ³ÃæµÄÄڴ棬ÕâÀïʹÓù²ÓÃÌ彫 slabÖ¸ÕëºÍ¸´ºÏÒ³µÄÊ×Ò³Ö¸ÕëÓëprivateºÍmapping¹«Óô洢¿Õ¼ä¡£privateµÄÓÃ;Óëflags±ê־λϢϢÏà¹Ø¡£Èç¹ûÉèÖÃÁË PG_private£¬ÄÇôËü±»ÓÃÓÚbuffer_heads;Èç¹ûÉèÖÃÁËPG_swapcache£¬ÄÇôÓÃÓÚswp_entry_t;Èç¹ûÉèÖÃÁË PG_buddy£¬ÔòÓÃÓÚ»ï°éϵͳÖеĽ×(Order)¡£

Äں˿ÉÒÔ½«¶à¸öÏàÁÚµÄÒ³¿òºÏ²¢Îª¸´ºÏÒ³(Compound Page)¡£·Ö×éÖеĵÚÒ»¸öÒ²³ÉΪÊ×Ò³(Head Page)£¬¶øËùÓÐÆäÓà¸÷Ò³½Ð×öβҳ(Tail Page)¡£ËùÓÐβҳ¶ÔÓ¦µÄ¹ÜÀípageÊý¾Ý½á¹¹¶¼½«first_pageÖ¸ÏòÊ×Ò³¡£

mappingÖ¸¶¨ÁËÒ³¿òËùÔڵĵØÖ·¿Õ¼ä¡£indexÊÇÒ³¿òÔÚmappingÓ³ÉäÄÚ²¿µÄÆ«ÒÆÁ¿¡£mappingÖ¸Õëͨ³£ÊÇ¶ÔÆëµ½sizeof(long)µÄ£¬Õâ±£Ö¤ËüµÄ×îµÍλΪ0£¬µ«ÊÇËü²¢×ÜÊÇÈç´Ë¡£¿ÉÒÔÓÐÒÔÏÂÁ½ÖÖ¿ÉÄÜ£º

address_spaceµÄʵÀý

? µ±×îµÍλΪ1ʱ£¬Ö¸Ïòanon_vmaµÄʵÀý£¬´ËʱÍê³ÉÄäÃûÒ³µÄÄæÏòÓ³Éä¡£

?

lruÊÇÒ»¸ö±íÍ·£¬ÓÃÓÚÔÚ¸÷ÖÖÁ¿±íÉÏά»¤¸ÃÒ³¿ò£¬ÒԱ㽫Ëü°´²»Í¬Àà±ð·Ö×飬×îÖØÒªµÄ¾ÍÊÇzone->lru_lock±£»¤µÄ»î¶¯Ò³¿ò(active_list)ºÍ²»»î¶¯Ò³¿ò¡£ #if defined(WANT_PAGE_VIRTUAL)


LinuxÄÚ´æ¹ÜÀíÏê½â(2).doc ½«±¾ÎĵÄWordÎĵµÏÂÔØµ½µçÄÔ ÏÂÔØÊ§°Ü»òÕßÎĵµ²»ÍêÕû£¬ÇëÁªÏµ¿Í·þÈËÔ±½â¾ö£¡

ÏÂһƪ£º2018²¿±àÈ˽̰æÓïÎÄÒ»Ä꼶ϲᡶÐÕÊϸ衷˵¿Î¸å

Ïà¹ØÔĶÁ
±¾ÀàÅÅÐÐ
¡Á ×¢²á»áÔ±Ãâ·ÑÏÂÔØ£¨ÏÂÔØºó¿ÉÒÔ×ÔÓɸ´ÖƺÍÅŰ棩

ÂíÉÏ×¢²á»áÔ±

×¢£ºÏÂÔØÎĵµÓпÉÄÜ¡°Ö»ÓÐĿ¼»òÕßÄÚÈݲ»È«¡±µÈÇé¿ö£¬ÇëÏÂÔØÖ®Ç°×¢Òâ±æ±ð£¬Èç¹ûÄúÒѸ¶·ÑÇÒÎÞ·¨ÏÂÔØ»òÄÚÈÝÓÐÎÊÌ⣬ÇëÁªÏµÎÒÃÇЭÖúÄã´¦Àí¡£
΢ÐÅ£º QQ£º