aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/pdflush.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/mm/pdflush.c b/mm/pdflush.c
index 118905e3d788..235ac440c44e 100644
--- a/mm/pdflush.c
+++ b/mm/pdflush.c
@@ -98,7 +98,6 @@ static int __pdflush(struct pdflush_work *my_work)
98 INIT_LIST_HEAD(&my_work->list); 98 INIT_LIST_HEAD(&my_work->list);
99 99
100 spin_lock_irq(&pdflush_lock); 100 spin_lock_irq(&pdflush_lock);
101 nr_pdflush_threads++;
102 for ( ; ; ) { 101 for ( ; ; ) {
103 struct pdflush_work *pdf; 102 struct pdflush_work *pdf;
104 103
@@ -126,20 +125,26 @@ static int __pdflush(struct pdflush_work *my_work)
126 125
127 (*my_work->fn)(my_work->arg0); 126 (*my_work->fn)(my_work->arg0);
128 127
128 spin_lock_irq(&pdflush_lock);
129
129 /* 130 /*
130 * Thread creation: For how long have there been zero 131 * Thread creation: For how long have there been zero
131 * available threads? 132 * available threads?
133 *
134 * To throttle creation, we reset last_empty_jifs.
132 */ 135 */
133 if (time_after(jiffies, last_empty_jifs + 1 * HZ)) { 136 if (time_after(jiffies, last_empty_jifs + 1 * HZ)) {
134 /* unlocked list_empty() test is OK here */
135 if (list_empty(&pdflush_list)) { 137 if (list_empty(&pdflush_list)) {
136 /* unlocked test is OK here */ 138 if (nr_pdflush_threads < MAX_PDFLUSH_THREADS) {
137 if (nr_pdflush_threads < MAX_PDFLUSH_THREADS) 139 last_empty_jifs = jiffies;
140 nr_pdflush_threads++;
141 spin_unlock_irq(&pdflush_lock);
138 start_one_pdflush_thread(); 142 start_one_pdflush_thread();
143 spin_lock_irq(&pdflush_lock);
144 }
139 } 145 }
140 } 146 }
141 147
142 spin_lock_irq(&pdflush_lock);
143 my_work->fn = NULL; 148 my_work->fn = NULL;
144 149
145 /* 150 /*
@@ -236,13 +241,26 @@ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0)
236 241
237static void start_one_pdflush_thread(void) 242static void start_one_pdflush_thread(void)
238{ 243{
239 kthread_run(pdflush, NULL, "pdflush"); 244 struct task_struct *k;
245
246 k = kthread_run(pdflush, NULL, "pdflush");
247 if (unlikely(IS_ERR(k))) {
248 spin_lock_irq(&pdflush_lock);
249 nr_pdflush_threads--;
250 spin_unlock_irq(&pdflush_lock);
251 }
240} 252}
241 253
242static int __init pdflush_init(void) 254static int __init pdflush_init(void)
243{ 255{
244 int i; 256 int i;
245 257
258 /*
259 * Pre-set nr_pdflush_threads... If we fail to create,
260 * the count will be decremented.
261 */
262 nr_pdflush_threads = MIN_PDFLUSH_THREADS;
263
246 for (i = 0; i < MIN_PDFLUSH_THREADS; i++) 264 for (i = 0; i < MIN_PDFLUSH_THREADS; i++)
247 start_one_pdflush_thread(); 265 start_one_pdflush_thread();
248 return 0; 266 return 0;