aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sysctl/vm.txt28
-rw-r--r--include/linux/writeback.h2
-rw-r--r--kernel/sysctl.c23
-rw-r--r--mm/pdflush.c31
4 files changed, 72 insertions, 12 deletions
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
index 3197fc83bc51..97c4b3284329 100644
--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -39,6 +39,8 @@ Currently, these files are in /proc/sys/vm:
39- nr_hugepages 39- nr_hugepages
40- nr_overcommit_hugepages 40- nr_overcommit_hugepages
41- nr_pdflush_threads 41- nr_pdflush_threads
42- nr_pdflush_threads_min
43- nr_pdflush_threads_max
42- nr_trim_pages (only if CONFIG_MMU=n) 44- nr_trim_pages (only if CONFIG_MMU=n)
43- numa_zonelist_order 45- numa_zonelist_order
44- oom_dump_tasks 46- oom_dump_tasks
@@ -463,6 +465,32 @@ The default value is 0.
463 465
464============================================================== 466==============================================================
465 467
468nr_pdflush_threads_min
469
470This value controls the minimum number of pdflush threads.
471
472At boot time, the kernel will create and maintain 'nr_pdflush_threads_min'
473threads for the kernel's lifetime.
474
475The default value is 2. The minimum value you can specify is 1, and
476the maximum value is the current setting of 'nr_pdflush_threads_max'.
477
478See 'nr_pdflush_threads_max' below for more information.
479
480==============================================================
481
482nr_pdflush_threads_max
483
484This value controls the maximum number of pdflush threads that can be
485created. The pdflush algorithm will create a new pdflush thread (up to
486this maximum) if no pdflush threads have been available for >= 1 second.
487
488The default value is 8. The minimum value you can specify is the
489current value of 'nr_pdflush_threads_min' and the
490maximum is 1000.
491
492==============================================================
493
466overcommit_memory: 494overcommit_memory:
467 495
468This value contains a flag that enables memory overcommitment. 496This value contains a flag that enables memory overcommitment.
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 93445477f86a..9c1ed1fb6ddb 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -168,6 +168,8 @@ void writeback_set_ratelimit(void);
168/* pdflush.c */ 168/* pdflush.c */
169extern int nr_pdflush_threads; /* Global so it can be exported to sysctl 169extern int nr_pdflush_threads; /* Global so it can be exported to sysctl
170 read-only. */ 170 read-only. */
171extern int nr_pdflush_threads_max; /* Global so it can be exported to sysctl */
172extern int nr_pdflush_threads_min; /* Global so it can be exported to sysctl */
171 173
172 174
173#endif /* WRITEBACK_H */ 175#endif /* WRITEBACK_H */
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index b125e3387568..72eb1a41dcab 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -101,6 +101,7 @@ static int __maybe_unused one = 1;
101static int __maybe_unused two = 2; 101static int __maybe_unused two = 2;
102static unsigned long one_ul = 1; 102static unsigned long one_ul = 1;
103static int one_hundred = 100; 103static int one_hundred = 100;
104static int one_thousand = 1000;
104 105
105/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ 106/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
106static int maxolduid = 65535; 107static int maxolduid = 65535;
@@ -1027,6 +1028,28 @@ static struct ctl_table vm_table[] = {
1027 .proc_handler = &proc_dointvec, 1028 .proc_handler = &proc_dointvec,
1028 }, 1029 },
1029 { 1030 {
1031 .ctl_name = CTL_UNNUMBERED,
1032 .procname = "nr_pdflush_threads_min",
1033 .data = &nr_pdflush_threads_min,
1034 .maxlen = sizeof nr_pdflush_threads_min,
1035 .mode = 0644 /* read-write */,
1036 .proc_handler = &proc_dointvec_minmax,
1037 .strategy = &sysctl_intvec,
1038 .extra1 = &one,
1039 .extra2 = &nr_pdflush_threads_max,
1040 },
1041 {
1042 .ctl_name = CTL_UNNUMBERED,
1043 .procname = "nr_pdflush_threads_max",
1044 .data = &nr_pdflush_threads_max,
1045 .maxlen = sizeof nr_pdflush_threads_max,
1046 .mode = 0644 /* read-write */,
1047 .proc_handler = &proc_dointvec_minmax,
1048 .strategy = &sysctl_intvec,
1049 .extra1 = &nr_pdflush_threads_min,
1050 .extra2 = &one_thousand,
1051 },
1052 {
1030 .ctl_name = VM_SWAPPINESS, 1053 .ctl_name = VM_SWAPPINESS,
1031 .procname = "swappiness", 1054 .procname = "swappiness",
1032 .data = &vm_swappiness, 1055 .data = &vm_swappiness,
diff --git a/mm/pdflush.c b/mm/pdflush.c
index 235ac440c44e..f2caf96993f8 100644
--- a/mm/pdflush.c
+++ b/mm/pdflush.c
@@ -58,6 +58,14 @@ static DEFINE_SPINLOCK(pdflush_lock);
58int nr_pdflush_threads = 0; 58int nr_pdflush_threads = 0;
59 59
60/* 60/*
61 * The max/min number of pdflush threads. R/W by sysctl at
62 * /proc/sys/vm/nr_pdflush_threads_max/min
63 */
64int nr_pdflush_threads_max __read_mostly = MAX_PDFLUSH_THREADS;
65int nr_pdflush_threads_min __read_mostly = MIN_PDFLUSH_THREADS;
66
67
68/*
61 * The time at which the pdflush thread pool last went empty 69 * The time at which the pdflush thread pool last went empty
62 */ 70 */
63static unsigned long last_empty_jifs; 71static unsigned long last_empty_jifs;
@@ -68,7 +76,7 @@ static unsigned long last_empty_jifs;
68 * Thread pool management algorithm: 76 * Thread pool management algorithm:
69 * 77 *
70 * - The minimum and maximum number of pdflush instances are bound 78 * - The minimum and maximum number of pdflush instances are bound
71 * by MIN_PDFLUSH_THREADS and MAX_PDFLUSH_THREADS. 79 * by nr_pdflush_threads_min and nr_pdflush_threads_max.
72 * 80 *
73 * - If there have been no idle pdflush instances for 1 second, create 81 * - If there have been no idle pdflush instances for 1 second, create
74 * a new one. 82 * a new one.
@@ -134,14 +142,13 @@ static int __pdflush(struct pdflush_work *my_work)
134 * To throttle creation, we reset last_empty_jifs. 142 * To throttle creation, we reset last_empty_jifs.
135 */ 143 */
136 if (time_after(jiffies, last_empty_jifs + 1 * HZ)) { 144 if (time_after(jiffies, last_empty_jifs + 1 * HZ)) {
137 if (list_empty(&pdflush_list)) { 145 if (list_empty(&pdflush_list) &&
138 if (nr_pdflush_threads < MAX_PDFLUSH_THREADS) { 146 nr_pdflush_threads < nr_pdflush_threads_max) {
139 last_empty_jifs = jiffies; 147 last_empty_jifs = jiffies;
140 nr_pdflush_threads++; 148 nr_pdflush_threads++;
141 spin_unlock_irq(&pdflush_lock); 149 spin_unlock_irq(&pdflush_lock);
142 start_one_pdflush_thread(); 150 start_one_pdflush_thread();
143 spin_lock_irq(&pdflush_lock); 151 spin_lock_irq(&pdflush_lock);
144 }
145 } 152 }
146 } 153 }
147 154
@@ -153,7 +160,7 @@ static int __pdflush(struct pdflush_work *my_work)
153 */ 160 */
154 if (list_empty(&pdflush_list)) 161 if (list_empty(&pdflush_list))
155 continue; 162 continue;
156 if (nr_pdflush_threads <= MIN_PDFLUSH_THREADS) 163 if (nr_pdflush_threads <= nr_pdflush_threads_min)
157 continue; 164 continue;
158 pdf = list_entry(pdflush_list.prev, struct pdflush_work, list); 165 pdf = list_entry(pdflush_list.prev, struct pdflush_work, list);
159 if (time_after(jiffies, pdf->when_i_went_to_sleep + 1 * HZ)) { 166 if (time_after(jiffies, pdf->when_i_went_to_sleep + 1 * HZ)) {
@@ -259,9 +266,9 @@ static int __init pdflush_init(void)
259 * Pre-set nr_pdflush_threads... If we fail to create, 266 * Pre-set nr_pdflush_threads... If we fail to create,
260 * the count will be decremented. 267 * the count will be decremented.
261 */ 268 */
262 nr_pdflush_threads = MIN_PDFLUSH_THREADS; 269 nr_pdflush_threads = nr_pdflush_threads_min;
263 270
264 for (i = 0; i < MIN_PDFLUSH_THREADS; i++) 271 for (i = 0; i < nr_pdflush_threads_min; i++)
265 start_one_pdflush_thread(); 272 start_one_pdflush_thread();
266 return 0; 273 return 0;
267} 274}