diff options
Diffstat (limited to 'mm/pdflush.c')
-rw-r--r-- | mm/pdflush.c | 30 |
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 | ||
237 | static void start_one_pdflush_thread(void) | 242 | static 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 | ||
242 | static int __init pdflush_init(void) | 254 | static 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; |