|
69 | 69 |
|
70 | 70 | /* prevent >1 _updater_ of zone percpu pageset ->high and ->batch fields */
|
71 | 71 | static DEFINE_MUTEX(pcp_batch_high_lock);
|
| 72 | +#define MIN_PERCPU_PAGELIST_FRACTION (8) |
72 | 73 |
|
73 | 74 | #ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID
|
74 | 75 | DEFINE_PER_CPU(int, numa_node);
|
@@ -4106,7 +4107,7 @@ static void __meminit zone_init_free_lists(struct zone *zone)
|
4106 | 4107 | memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY)
|
4107 | 4108 | #endif
|
4108 | 4109 |
|
4109 |
| -static int __meminit zone_batchsize(struct zone *zone) |
| 4110 | +static int zone_batchsize(struct zone *zone) |
4110 | 4111 | {
|
4111 | 4112 | #ifdef CONFIG_MMU
|
4112 | 4113 | int batch;
|
@@ -4222,8 +4223,8 @@ static void pageset_set_high(struct per_cpu_pageset *p,
|
4222 | 4223 | pageset_update(&p->pcp, high, batch);
|
4223 | 4224 | }
|
4224 | 4225 |
|
4225 |
| -static void __meminit pageset_set_high_and_batch(struct zone *zone, |
4226 |
| - struct per_cpu_pageset *pcp) |
| 4226 | +static void pageset_set_high_and_batch(struct zone *zone, |
| 4227 | + struct per_cpu_pageset *pcp) |
4227 | 4228 | {
|
4228 | 4229 | if (percpu_pagelist_fraction)
|
4229 | 4230 | pageset_set_high(pcp,
|
@@ -5848,23 +5849,38 @@ int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write,
|
5848 | 5849 | void __user *buffer, size_t *length, loff_t *ppos)
|
5849 | 5850 | {
|
5850 | 5851 | struct zone *zone;
|
5851 |
| - unsigned int cpu; |
| 5852 | + int old_percpu_pagelist_fraction; |
5852 | 5853 | int ret;
|
5853 | 5854 |
|
| 5855 | + mutex_lock(&pcp_batch_high_lock); |
| 5856 | + old_percpu_pagelist_fraction = percpu_pagelist_fraction; |
| 5857 | + |
5854 | 5858 | ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
|
5855 |
| - if (!write || (ret < 0)) |
5856 |
| - return ret; |
| 5859 | + if (!write || ret < 0) |
| 5860 | + goto out; |
| 5861 | + |
| 5862 | + /* Sanity checking to avoid pcp imbalance */ |
| 5863 | + if (percpu_pagelist_fraction && |
| 5864 | + percpu_pagelist_fraction < MIN_PERCPU_PAGELIST_FRACTION) { |
| 5865 | + percpu_pagelist_fraction = old_percpu_pagelist_fraction; |
| 5866 | + ret = -EINVAL; |
| 5867 | + goto out; |
| 5868 | + } |
| 5869 | + |
| 5870 | + /* No change? */ |
| 5871 | + if (percpu_pagelist_fraction == old_percpu_pagelist_fraction) |
| 5872 | + goto out; |
5857 | 5873 |
|
5858 |
| - mutex_lock(&pcp_batch_high_lock); |
5859 | 5874 | for_each_populated_zone(zone) {
|
5860 |
| - unsigned long high; |
5861 |
| - high = zone->managed_pages / percpu_pagelist_fraction; |
| 5875 | + unsigned int cpu; |
| 5876 | + |
5862 | 5877 | for_each_possible_cpu(cpu)
|
5863 |
| - pageset_set_high(per_cpu_ptr(zone->pageset, cpu), |
5864 |
| - high); |
| 5878 | + pageset_set_high_and_batch(zone, |
| 5879 | + per_cpu_ptr(zone->pageset, cpu)); |
5865 | 5880 | }
|
| 5881 | +out: |
5866 | 5882 | mutex_unlock(&pcp_batch_high_lock);
|
5867 |
| - return 0; |
| 5883 | + return ret; |
5868 | 5884 | }
|
5869 | 5885 |
|
5870 | 5886 | int hashdist = HASHDIST_DEFAULT;
|
|
0 commit comments