diff options
Diffstat (limited to 'block/cfq-iosched.c')
| -rw-r--r-- | block/cfq-iosched.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 7102bafc98..3cd985bece 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
| @@ -91,6 +91,9 @@ static kmem_cache_t *crq_pool; | |||
| 91 | static kmem_cache_t *cfq_pool; | 91 | static kmem_cache_t *cfq_pool; |
| 92 | static kmem_cache_t *cfq_ioc_pool; | 92 | static kmem_cache_t *cfq_ioc_pool; |
| 93 | 93 | ||
| 94 | static atomic_t ioc_count = ATOMIC_INIT(0); | ||
| 95 | static struct completion *ioc_gone; | ||
| 96 | |||
| 94 | #define CFQ_PRIO_LISTS IOPRIO_BE_NR | 97 | #define CFQ_PRIO_LISTS IOPRIO_BE_NR |
| 95 | #define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE) | 98 | #define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE) |
| 96 | #define cfq_class_be(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_BE) | 99 | #define cfq_class_be(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_BE) |
| @@ -1202,13 +1205,17 @@ static void cfq_free_io_context(struct cfq_io_context *cic) | |||
| 1202 | { | 1205 | { |
| 1203 | struct cfq_io_context *__cic; | 1206 | struct cfq_io_context *__cic; |
| 1204 | struct list_head *entry, *next; | 1207 | struct list_head *entry, *next; |
| 1208 | int freed = 1; | ||
| 1205 | 1209 | ||
| 1206 | list_for_each_safe(entry, next, &cic->list) { | 1210 | list_for_each_safe(entry, next, &cic->list) { |
| 1207 | __cic = list_entry(entry, struct cfq_io_context, list); | 1211 | __cic = list_entry(entry, struct cfq_io_context, list); |
| 1208 | kmem_cache_free(cfq_ioc_pool, __cic); | 1212 | kmem_cache_free(cfq_ioc_pool, __cic); |
| 1213 | freed++; | ||
| 1209 | } | 1214 | } |
| 1210 | 1215 | ||
| 1211 | kmem_cache_free(cfq_ioc_pool, cic); | 1216 | kmem_cache_free(cfq_ioc_pool, cic); |
| 1217 | if (atomic_sub_and_test(freed, &ioc_count) && ioc_gone) | ||
| 1218 | complete(ioc_gone); | ||
| 1212 | } | 1219 | } |
| 1213 | 1220 | ||
| 1214 | static void cfq_trim(struct io_context *ioc) | 1221 | static void cfq_trim(struct io_context *ioc) |
| @@ -1297,6 +1304,7 @@ cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) | |||
| 1297 | cic->dtor = cfq_free_io_context; | 1304 | cic->dtor = cfq_free_io_context; |
| 1298 | cic->exit = cfq_exit_io_context; | 1305 | cic->exit = cfq_exit_io_context; |
| 1299 | INIT_LIST_HEAD(&cic->queue_list); | 1306 | INIT_LIST_HEAD(&cic->queue_list); |
| 1307 | atomic_inc(&ioc_count); | ||
| 1300 | } | 1308 | } |
| 1301 | 1309 | ||
| 1302 | return cic; | 1310 | return cic; |
| @@ -1501,6 +1509,7 @@ restart: | |||
| 1501 | list); | 1509 | list); |
| 1502 | read_unlock(&cfq_exit_lock); | 1510 | read_unlock(&cfq_exit_lock); |
| 1503 | kmem_cache_free(cfq_ioc_pool, cic); | 1511 | kmem_cache_free(cfq_ioc_pool, cic); |
| 1512 | atomic_dec(&ioc_count); | ||
| 1504 | goto restart; | 1513 | goto restart; |
| 1505 | } | 1514 | } |
| 1506 | 1515 | ||
| @@ -1523,6 +1532,7 @@ restart: | |||
| 1523 | list_del(&__cic->list); | 1532 | list_del(&__cic->list); |
| 1524 | read_unlock(&cfq_exit_lock); | 1533 | read_unlock(&cfq_exit_lock); |
| 1525 | kmem_cache_free(cfq_ioc_pool, __cic); | 1534 | kmem_cache_free(cfq_ioc_pool, __cic); |
| 1535 | atomic_dec(&ioc_count); | ||
| 1526 | goto restart; | 1536 | goto restart; |
| 1527 | } | 1537 | } |
| 1528 | } | 1538 | } |
| @@ -2510,7 +2520,13 @@ static int __init cfq_init(void) | |||
| 2510 | 2520 | ||
| 2511 | static void __exit cfq_exit(void) | 2521 | static void __exit cfq_exit(void) |
| 2512 | { | 2522 | { |
| 2523 | DECLARE_COMPLETION(all_gone); | ||
| 2513 | elv_unregister(&iosched_cfq); | 2524 | elv_unregister(&iosched_cfq); |
| 2525 | ioc_gone = &all_gone; | ||
| 2526 | barrier(); | ||
| 2527 | if (atomic_read(&ioc_count)) | ||
| 2528 | complete(ioc_gone); | ||
| 2529 | synchronize_rcu(); | ||
| 2514 | cfq_slab_kill(); | 2530 | cfq_slab_kill(); |
| 2515 | } | 2531 | } |
| 2516 | 2532 | ||
