ARM10C 55주차 후기
일시 : 2014.05.24 (55주차)
모임명 : NAVER개발자커뮤니티지원_IAMROOT.ORG_10차ARM-C
장소 : 토즈 타워점
장소지원 : NAVER 개발자 커뮤니티 지원 프로그램
참여인원 : 5명
스터디 진도 :
- 지난 스터디에 이어서 mem_init()을 계속 분석합니다.
- start_kernel()-> mm_init()->kmem_cache_init()->create_boot_cache() 분석중
- kmem_cache_init()이 분석 중이어서 이번 후기는 내용이 짧습니다.
- 내용이 복잡해서 slub()이 끝나는 시점에서 내용 정리를 함께 다시 하기로 했습니다.
- 자세한 후기도 그때 다시 정리하려고 합니다.
스터디 주요 내용
- __mod_zone_page_state()가 여러번 반복 호출 되는데, 이 중요한 함수를 복습하자.
buffered_rmqueue()
- __mod_zone_page_state(zone, NR_ALLOC_BATCH, -(1 << order));
- __count_zone_vm_events(PGALLOC, zone, 1 << order);
// - zone_statistics(preferred_zone, zone, gfp_flags);
// NULL function - local_irq_restore(flags);
// cpsr 복원 - VM_BUG_ON(bad_range(zone, page));
// return 0; VM_BUG_ON : 부정되어 패스 - if (prep_new_page(page, order, gfp_flags))
- prep_new_page(page, order, gfp_flags)
// page migratetype이 MIGRATE_UNMOVABLE인 page, order:0, gfp_flags: 0x221200
- prep_new_page(page, order, gfp_flags)
static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
{
int i;
for (i = 0; i < (1 << order); i++) {
struct page *p = page + i;
if (unlikely(check_new_page(p)))
return 1;
}
set_page_private(page, 0);
set_page_refcounted(page);
arch_alloc_page(page, order);
kernel_map_pages(page, 1 << order, 1);
if (gfp_flags & __GFP_ZERO)
prep_zero_page(page, order, gfp_flags);
if (order && (gfp_flags & __GFP_COMP))
prep_compound_page(page, order);
return 0;
}
if (unlikely(check_new_page(p)))
static inline int check_new_page(struct page *page)
{
if (unlikely(page_mapcount(page) |
(page->mapping != NULL) |
(atomic_read(&page->_count) != 0) |
(page->flags & PAGE_FLAGS_CHECK_AT_PREP) |
(mem_cgroup_bad_page_check(page)))) {
bad_page(page);
// page->mapping != NULL :
// atomic_read(&page->_count) != 0
// page->flags & PAGE_FLAGS_CHECK_AT_PREP :
// mem_cgroup_bad_page_check : FALSE
return 1;
}
return 0;
}
- // page->mapping != NULL :
- _mapcount : to show when pag is mapped & limit reverse map searches
- -127 초기화는
- -1 사용하려고 할당받았지만, 참조는 되지 않음 (-1) : 0xffff ffff, 1111 …. 1111
- mapping
- _mapcount : to show when pag is mapped & limit reverse map searches
- // atomic_read(&page->_count) != 0
- __free_pages_bootmem()->set_page_count(p,0);
- free_pages->put_pagetestzero(page)
// page->count: 0
이값은 buddy초기화(free_pages()에서 0으로 초기화를 했다.
- // page->flags & PAGE_FLAGS_CHECK_AT_PREP :
- // mem_cgroup_bad_page_check : FALSE
- check_new_page()
- 이 의미가 bad pages가 되지 조건이다.
// page->_mapcount : - 1 사용하기 위해 할당받았지만 참조되어 사용하지는 않음
// page->mapping 할당 받았으면 NULL로 디, 사용중인 page는 vam, inode등의 address apace로 매핑된다.
// page->_count :
set_page_private(page, 0);
- page : migragtetype이 MIGRATE_UNMOVEABLE인 page
- page->private: 0
- 왜 private : order값을 0으로 했을까? FIX me!
set_page_refcounted(page);
- page->_count를 1로 set
arch_alloc_page(page, order);
- null function
kernel_map_pages(page, 1 << order, 1);
- null function
if (gfp_flags & __GFP_ZERO) prep_zero_page(page, order, gfp_flags);
- gfp_flags : 0x221200
- __GFP_ZERO : 0x 8000
- gfp_flags & __GFP_ZERO : 0
if (order && (gfp_flags & __GFP_COMP)) prep_compound_page(page, order);
- order : 0
return 0;
- 이것으로 get_page_from_freelist() 함수의
this_zone_full: 의 조건인 함수의
if(page) break;를 통해서 loop를 빠져 나옴.get_page_from_freelist() - alloc_pages_nodemask()->
page = get_page_from_freelist(gfp_mask|GFP_HARDWALL, nodemask, order,zonelist, high_zoneidx, alloc_flags, preferred_zone, migratetype);
__alloc_pages_nodemask()
- if (unlikely(!page)) // false
- out : if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page)) goto retry_cpuset;
// cpuset_mems_cookie : 0 - put_mems_allowed(0) // true
- memcg_kmem_commit_charge(page, memcg, order);
// * page : migragtetype이 MIGRATE_UNMOVEABLE인 page , memcg : null , order : 0
// memcg_kme_commit_charge () // null function - return * page
// migragtetype이 MIGRATE_UNMOVEABLE인 page로 할당 받음alloc_pages_exact_node()
// return * page : migragtetype이 MIGRATE_UNMOVEABLE인 page
alloc_slab_page()
// return * page : migragtetype이 MIGRATE_UNMOVEABLE인 page
allocate_slab()
page = alloc_slab_page(alloc_gfp, node, oo);
// return * page : migragtetype이 MIGRATE_UNMOVEABLE인 page
// return * page : migragtetype이 MIGRATE_UNMOVEABLE인 page
if (unlikely(!page))
// faluse
// faluse
if (kmemcheck_enabled && page && !(s->flags & (SLAB_NOTRACK | DEBUG_DEFAULT_FLAGS)))
// kmemcheck_enabled: 0, page: migratetype이 MIGRAT_UNMOVEABLE으로 할당 받은 page
// s->flags : SLAB_HWCACHE_ALIGN : 0x00002000
// SLAB_NOTRACK : 0x000000000UL
// #define DEBUG_DEFAULT_FLAGS (SLAB_DEBUG_FREE | SLAB_RED_ZONE | \
SLAB_POISON | SLAB_STORE_USER)
// SLAB_DEBUG_FREE 0x00000100UL
// SLAB_RED_ZONE 0x00000400UL
// SLAB_POISON 0x00000800UL
// SLAB_STORE_USER 0x00010000UL
// 0x00010d00 : 0x00000100UL | 0x00000400UL | 0x00000800UL | 0x00010000UL
// kmemcheck_enabled: 0, page: migratetype이 MIGRAT_UNMOVEABLE으로 할당 받은 page
// s->flags : SLAB_HWCACHE_ALIGN : 0x00002000
// SLAB_NOTRACK : 0x000000000UL
// #define DEBUG_DEFAULT_FLAGS (SLAB_DEBUG_FREE | SLAB_RED_ZONE | \
SLAB_POISON | SLAB_STORE_USER)
// SLAB_DEBUG_FREE 0x00000100UL
// SLAB_RED_ZONE 0x00000400UL
// SLAB_POISON 0x00000800UL
// SLAB_STORE_USER 0x00010000UL
// 0x00010d00 : 0x00000100UL | 0x00000400UL | 0x00000800UL | 0x00010000UL
if (flags & __GFP_WAIT)
local_irq_disable();
// (flags : 0 & GRP_WAIT : 0x10 ) : false
local_irq_disable();
// (flags : 0 & GRP_WAIT : 0x10 ) : false
if (!page)
return NULL;
return NULL;
page->objects = oo_objects(oo);
// oo: boot_mem_cache_node.oo
// oo_objects(oo) : 64
// page->objects : 64
// page-> union struct { //slub :
inuse : 16;
object : 15;
frozen : 1;
// page->_mapcount : 0x0040 00000
// oo: boot_mem_cache_node.oo
// oo_objects(oo) : 64
// page->objects : 64
// page-> union struct { //slub :
inuse : 16;
object : 15;
frozen : 1;
// page->_mapcount : 0x0040 00000
- object의 의미는 무엇일까?
4k안에 64짜리 object가 64개 있다.
mod_zone_page_state(page_zone(page),
(s->flags & SLAB_RECLAIM_ACCOUNT) ?
NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
1 << oo_order(oo));
// page_zone(page) : &(&contig_page_data)->node_zones[ZONE_NORMAL]
// s->flags : (&boot_kmem_cache_node)->flags: SLAB_HWCACHE_ALIGN: 0x00002000
// NR_SLAB_RECLIMABLE : 13, NR_SLAB_UNRECLAIMABLE : 14
// oo_order(boot_kmem_cache_node.oo) : 0
// 따라서 &(&contig_page_data)->node_zones[ZONE_NORMAL],NR_SLAB_UNRECLAIMABLE : 14, 0
// __mod_zone_page_state()를 호출
// zone->vm_stat[14] : (&contig_page_data)->node_zones[ZONE_NORMAL].vm_stat[14]:1
// NR_SLAB_UNRECLAIMABLE : 14, vm_stat[14]:1
(s->flags & SLAB_RECLAIM_ACCOUNT) ?
NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
1 << oo_order(oo));
// page_zone(page) : &(&contig_page_data)->node_zones[ZONE_NORMAL]
// s->flags : (&boot_kmem_cache_node)->flags: SLAB_HWCACHE_ALIGN: 0x00002000
// NR_SLAB_RECLIMABLE : 13, NR_SLAB_UNRECLAIMABLE : 14
// oo_order(boot_kmem_cache_node.oo) : 0
// 따라서 &(&contig_page_data)->node_zones[ZONE_NORMAL],NR_SLAB_UNRECLAIMABLE : 14, 0
// __mod_zone_page_state()를 호출
// zone->vm_stat[14] : (&contig_page_data)->node_zones[ZONE_NORMAL].vm_stat[14]:1
// NR_SLAB_UNRECLAIMABLE : 14, vm_stat[14]:1
new_slab()
order = compound_order(page);
// page->flags
// compound가 접착이라는 의미이므로 page가 붙여서 할당 받았는지 여부를 나타내는 것으로 추정된다.
// 우리는 작은 것을 받았으므로 0일것이다. 하지만 의미는 분명하게 확인해 보자.
// free_pages_check에서 버디를 활성화하기 전에 모두 0으로 초기화 하고 왔다.
// page->flags의 NR_PAGEFLAGS 만큼의 하위 비트를 전부 지워줌.
// page->flags
// compound가 접착이라는 의미이므로 page가 붙여서 할당 받았는지 여부를 나타내는 것으로 추정된다.
// 우리는 작은 것을 받았으므로 0일것이다. 하지만 의미는 분명하게 확인해 보자.
// free_pages_check에서 버디를 활성화하기 전에 모두 0으로 초기화 하고 왔다.
// page->flags의 NR_PAGEFLAGS 만큼의 하위 비트를 전부 지워줌.
static inline int compound_order(struct page *page)
{
// PageHead(page): 0
if (!PageHead(page))
return 0;
return (unsigned long)page[1].lru.prev;
}
git log
Updating d9a9639..f3708db
Fast-forward
include/linux/cpuset.h | 1 +
include/linux/gfp.h | 12 +
include/linux/kmemcheck.h | 1 +
include/linux/memcontrol.h | 2
include/linux/mm.h | 3 +
include/linux/mmzone.h | 2
include/linux/page-flags.h | 1 +
include/linux/slab.h | 8 +++-
include/linux/vmstat.h | 15 ++-
include/trace/events/kmem.h | 1 +
mm/bootmem.c | 2
mm/internal.h | 3 +
mm/page_alloc.c | 77 ++———
mm/slub.c | 40 +++—
mm/vmstat.c | 64 +++—————-
15 files changed, 205 insertions(+), 27 deletions(-)
Fast-forward
include/linux/cpuset.h | 1 +
include/linux/gfp.h | 12 +
include/linux/kmemcheck.h | 1 +
include/linux/memcontrol.h | 2
include/linux/mm.h | 3 +
include/linux/mmzone.h | 2
include/linux/page-flags.h | 1 +
include/linux/slab.h | 8 +++-
include/linux/vmstat.h | 15 ++-
include/trace/events/kmem.h | 1 +
mm/bootmem.c | 2
mm/internal.h | 3 +
mm/page_alloc.c | 77 ++———
mm/slub.c | 40 +++—
mm/vmstat.c | 64 +++—————-
15 files changed, 205 insertions(+), 27 deletions(-)
댓글 없음:
댓글 쓰기