diff options
Diffstat (limited to 'drivers/md/dm-delay.c')
| -rw-r--r-- | drivers/md/dm-delay.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c index 496d5f3646a5..2f91d6d4a2cc 100644 --- a/drivers/md/dm-delay.c +++ b/drivers/md/dm-delay.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | struct delay_c { | 20 | struct delay_c { |
| 21 | struct timer_list delay_timer; | 21 | struct timer_list delay_timer; |
| 22 | struct mutex timer_lock; | 22 | struct mutex timer_lock; |
| 23 | struct workqueue_struct *kdelayd_wq; | ||
| 23 | struct work_struct flush_expired_bios; | 24 | struct work_struct flush_expired_bios; |
| 24 | struct list_head delayed_bios; | 25 | struct list_head delayed_bios; |
| 25 | atomic_t may_delay; | 26 | atomic_t may_delay; |
| @@ -45,14 +46,13 @@ struct dm_delay_info { | |||
| 45 | 46 | ||
| 46 | static DEFINE_MUTEX(delayed_bios_lock); | 47 | static DEFINE_MUTEX(delayed_bios_lock); |
| 47 | 48 | ||
| 48 | static struct workqueue_struct *kdelayd_wq; | ||
| 49 | static struct kmem_cache *delayed_cache; | 49 | static struct kmem_cache *delayed_cache; |
| 50 | 50 | ||
| 51 | static void handle_delayed_timer(unsigned long data) | 51 | static void handle_delayed_timer(unsigned long data) |
| 52 | { | 52 | { |
| 53 | struct delay_c *dc = (struct delay_c *)data; | 53 | struct delay_c *dc = (struct delay_c *)data; |
| 54 | 54 | ||
| 55 | queue_work(kdelayd_wq, &dc->flush_expired_bios); | 55 | queue_work(dc->kdelayd_wq, &dc->flush_expired_bios); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | static void queue_timeout(struct delay_c *dc, unsigned long expires) | 58 | static void queue_timeout(struct delay_c *dc, unsigned long expires) |
| @@ -191,6 +191,12 @@ out: | |||
| 191 | goto bad_dev_write; | 191 | goto bad_dev_write; |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0); | ||
| 195 | if (!dc->kdelayd_wq) { | ||
| 196 | DMERR("Couldn't start kdelayd"); | ||
| 197 | goto bad_queue; | ||
| 198 | } | ||
| 199 | |||
| 194 | setup_timer(&dc->delay_timer, handle_delayed_timer, (unsigned long)dc); | 200 | setup_timer(&dc->delay_timer, handle_delayed_timer, (unsigned long)dc); |
| 195 | 201 | ||
| 196 | INIT_WORK(&dc->flush_expired_bios, flush_expired_bios); | 202 | INIT_WORK(&dc->flush_expired_bios, flush_expired_bios); |
| @@ -203,6 +209,8 @@ out: | |||
| 203 | ti->private = dc; | 209 | ti->private = dc; |
| 204 | return 0; | 210 | return 0; |
| 205 | 211 | ||
| 212 | bad_queue: | ||
| 213 | mempool_destroy(dc->delayed_pool); | ||
| 206 | bad_dev_write: | 214 | bad_dev_write: |
| 207 | if (dc->dev_write) | 215 | if (dc->dev_write) |
| 208 | dm_put_device(ti, dc->dev_write); | 216 | dm_put_device(ti, dc->dev_write); |
| @@ -217,7 +225,7 @@ static void delay_dtr(struct dm_target *ti) | |||
| 217 | { | 225 | { |
| 218 | struct delay_c *dc = ti->private; | 226 | struct delay_c *dc = ti->private; |
| 219 | 227 | ||
| 220 | flush_workqueue(kdelayd_wq); | 228 | destroy_workqueue(dc->kdelayd_wq); |
| 221 | 229 | ||
| 222 | dm_put_device(ti, dc->dev_read); | 230 | dm_put_device(ti, dc->dev_read); |
| 223 | 231 | ||
| @@ -350,12 +358,6 @@ static int __init dm_delay_init(void) | |||
| 350 | { | 358 | { |
| 351 | int r = -ENOMEM; | 359 | int r = -ENOMEM; |
| 352 | 360 | ||
| 353 | kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0); | ||
| 354 | if (!kdelayd_wq) { | ||
| 355 | DMERR("Couldn't start kdelayd"); | ||
| 356 | goto bad_queue; | ||
| 357 | } | ||
| 358 | |||
| 359 | delayed_cache = KMEM_CACHE(dm_delay_info, 0); | 361 | delayed_cache = KMEM_CACHE(dm_delay_info, 0); |
| 360 | if (!delayed_cache) { | 362 | if (!delayed_cache) { |
| 361 | DMERR("Couldn't create delayed bio cache."); | 363 | DMERR("Couldn't create delayed bio cache."); |
| @@ -373,8 +375,6 @@ static int __init dm_delay_init(void) | |||
| 373 | bad_register: | 375 | bad_register: |
| 374 | kmem_cache_destroy(delayed_cache); | 376 | kmem_cache_destroy(delayed_cache); |
| 375 | bad_memcache: | 377 | bad_memcache: |
| 376 | destroy_workqueue(kdelayd_wq); | ||
| 377 | bad_queue: | ||
| 378 | return r; | 378 | return r; |
| 379 | } | 379 | } |
| 380 | 380 | ||
| @@ -382,7 +382,6 @@ static void __exit dm_delay_exit(void) | |||
| 382 | { | 382 | { |
| 383 | dm_unregister_target(&delay_target); | 383 | dm_unregister_target(&delay_target); |
| 384 | kmem_cache_destroy(delayed_cache); | 384 | kmem_cache_destroy(delayed_cache); |
| 385 | destroy_workqueue(kdelayd_wq); | ||
| 386 | } | 385 | } |
| 387 | 386 | ||
| 388 | /* Module hooks */ | 387 | /* Module hooks */ |
