|
@@ -2571,8 +2571,11 @@ int numa_zonelist_order_handler(ctl_table *table, int write,
|
|
|
strncpy((char*)table->data, saved_string,
|
|
|
NUMA_ZONELIST_ORDER_LEN);
|
|
|
user_zonelist_order = oldval;
|
|
|
- } else if (oldval != user_zonelist_order)
|
|
|
+ } else if (oldval != user_zonelist_order) {
|
|
|
+ mutex_lock(&zonelists_mutex);
|
|
|
build_all_zonelists(NULL);
|
|
|
+ mutex_unlock(&zonelists_mutex);
|
|
|
+ }
|
|
|
}
|
|
|
out:
|
|
|
mutex_unlock(&zl_order_mutex);
|
|
@@ -2924,6 +2927,12 @@ static void setup_pageset(struct per_cpu_pageset *p, unsigned long batch);
|
|
|
static DEFINE_PER_CPU(struct per_cpu_pageset, boot_pageset);
|
|
|
static void setup_zone_pageset(struct zone *zone);
|
|
|
|
|
|
+/*
|
|
|
+ * Global mutex to protect against size modification of zonelists
|
|
|
+ * as well as to serialize pageset setup for the new populated zone.
|
|
|
+ */
|
|
|
+DEFINE_MUTEX(zonelists_mutex);
|
|
|
+
|
|
|
/* return values int ....just for stop_machine() */
|
|
|
static __init_refok int __build_all_zonelists(void *data)
|
|
|
{
|
|
@@ -2967,6 +2976,10 @@ static __init_refok int __build_all_zonelists(void *data)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Called with zonelists_mutex held always
|
|
|
+ * unless system_state == SYSTEM_BOOTING.
|
|
|
+ */
|
|
|
void build_all_zonelists(void *data)
|
|
|
{
|
|
|
set_zonelist_order();
|