--- linux-2.6.git-dave/mm/page_alloc.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff -puN mm/page_alloc.c~zone-list-seqlock mm/page_alloc.c --- linux-2.6.git/mm/page_alloc.c~zone-list-seqlock 2008-11-04 08:53:38.000000000 -0800 +++ linux-2.6.git-dave/mm/page_alloc.c 2008-11-04 08:57:04.000000000 -0800 @@ -2378,17 +2378,43 @@ static void build_zonelist_cache(pg_data #endif /* CONFIG_NUMA */ +/* + * This provides a way for other parts of the + * system to detect when the list of zones + * might have changed underneath them. + * + * Use this if you are doing a for_each_zone() + * or for_each_node() and really, really care + * if you miss some memory. + */ +static seqlock_t zonelist_seqlock = SEQLOCK_UNLOCKED; + +/* + * We could #ifdef these under MEMORY_HOTPLUG, but they + * are tiny. + */ +unsigned zonelist_seqbegin(void) +{ + return read_seqbegin(&zonelist_seqlock); +} +int zonelist_seqretry(void) +{ + return read_seqretry(&zonelist_seqlock, iv); +} + /* return values int ....just for stop_machine() */ static int __build_all_zonelists(void *dummy) { int nid; + write_seqlock(&zonelist_seqlock); for_each_online_node(nid) { pg_data_t *pgdat = NODE_DATA(nid); build_zonelists(pgdat); build_zonelist_cache(pgdat); } + write_sequnlock(&zonelist_seqlock); return 0; } _