当对一个page做I/O操作的时候,I/O操作需要被锁住,防止不正确的数据被访问。
进程在访问page前,wait_on_page_locked函数,使进程加入一个等待队列。
不必要page被唤醒:每次找到的page不一定是希望的page,而只是哈希值一样。
锁定页面
lock_page(struct page *page)
=>might_sleep();
=>if (TestSetPageLocked(page))
__lock_page(page);
=>DEFINE_WAIT_BIT(wait, &page->flags, PG_locked);//加入到等待队列
=>__wait_on_bit_lock(page_waitqueue(page), &wait, sync_page, TASK_UNINTERRUPTIBLE);//当前进程进入TASK_UNINTERRUPTIBLE状态
解锁页面
unlock_page(struct page *page)
=>wake_up_page(page, PG_locked);
=>__wake_up_bit(page_waitqueue(page), &page->flags, bit);
zone和页面初始化
free_area_init_core
=>pgdat->nr_zones = 0;
=>init_waitqueue_head(&pgdat->kswapd_wait);
=>pgdat->kswapd_max_order = 0;
=>for (j = 0; j < MAX_NR_ZONES; j++)
size = zone_spanned_pages_in_node(nid, j, zones_size);
realsize = size - zone_absent_pages_in_node(nid, j, zholes_size);
zone->spanned_pages = size;
zone->present_pages = realsize;
zone_pcp_init(zone);//初始化页缓存
ret = init_currently_empty_zone(zone, zone_start_pfn, size, MEMMAP_EARLY);
=>ret = zone_wait_table_init(zone, size);
=>pgdat->nr_zones = zone_idx(zone) + 1;
=>zone->zone_start_pfn = zone_start_pfn;
=>memmap_init(size, pgdat->node_id, zone_idx(zone), zone_start_pfn);
=>zone_init_free_lists(pgdat, zone, zone->spanned_pages);
=>for (order = 0; order < MAX_ORDER ; order++)
INIT_LIST_HEAD(&zone->free_area[order].free_list);
zone->free_area[order].nr_free = 0;
参考文章
Linux内存描述之内存区域zone–Linux内存管理(三)
http://blog.youkuaiyun.com/gatieme/article/details/52384529
本文深入探讨了Linux内核中页面的锁定与解锁机制,包括进程如何通过wait_on_page_locked函数加入等待队列来确保I/O操作的安全性。此外,还介绍了zone和页面初始化的过程,涉及free_area_init_core函数的具体实现细节。
3489

被折叠的 条评论
为什么被折叠?



