diff options
Diffstat (limited to 'block/as-iosched.c')
| -rw-r--r-- | block/as-iosched.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/block/as-iosched.c b/block/as-iosched.c index d2ee2af44b..55a997fc4b 100644 --- a/block/as-iosched.c +++ b/block/as-iosched.c | |||
| @@ -182,6 +182,9 @@ struct as_rq { | |||
| 182 | 182 | ||
| 183 | static kmem_cache_t *arq_pool; | 183 | static kmem_cache_t *arq_pool; |
| 184 | 184 | ||
| 185 | static atomic_t ioc_count = ATOMIC_INIT(0); | ||
| 186 | static struct completion *ioc_gone; | ||
| 187 | |||
| 185 | static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq); | 188 | static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq); |
| 186 | static void as_antic_stop(struct as_data *ad); | 189 | static void as_antic_stop(struct as_data *ad); |
| 187 | 190 | ||
| @@ -193,11 +196,14 @@ static void as_antic_stop(struct as_data *ad); | |||
| 193 | static void free_as_io_context(struct as_io_context *aic) | 196 | static void free_as_io_context(struct as_io_context *aic) |
| 194 | { | 197 | { |
| 195 | kfree(aic); | 198 | kfree(aic); |
| 199 | if (atomic_dec_and_test(&ioc_count) && ioc_gone) | ||
| 200 | complete(ioc_gone); | ||
| 196 | } | 201 | } |
| 197 | 202 | ||
| 198 | static void as_trim(struct io_context *ioc) | 203 | static void as_trim(struct io_context *ioc) |
| 199 | { | 204 | { |
| 200 | kfree(ioc->aic); | 205 | if (ioc->aic) |
| 206 | free_as_io_context(ioc->aic); | ||
| 201 | ioc->aic = NULL; | 207 | ioc->aic = NULL; |
| 202 | } | 208 | } |
| 203 | 209 | ||
| @@ -226,6 +232,7 @@ static struct as_io_context *alloc_as_io_context(void) | |||
| 226 | ret->seek_total = 0; | 232 | ret->seek_total = 0; |
| 227 | ret->seek_samples = 0; | 233 | ret->seek_samples = 0; |
| 228 | ret->seek_mean = 0; | 234 | ret->seek_mean = 0; |
| 235 | atomic_inc(&ioc_count); | ||
| 229 | } | 236 | } |
| 230 | 237 | ||
| 231 | return ret; | 238 | return ret; |
| @@ -1900,7 +1907,13 @@ static int __init as_init(void) | |||
| 1900 | 1907 | ||
| 1901 | static void __exit as_exit(void) | 1908 | static void __exit as_exit(void) |
| 1902 | { | 1909 | { |
| 1910 | DECLARE_COMPLETION(all_gone); | ||
| 1903 | elv_unregister(&iosched_as); | 1911 | elv_unregister(&iosched_as); |
| 1912 | ioc_gone = &all_gone; | ||
| 1913 | barrier(); | ||
| 1914 | if (atomic_read(&ioc_count)) | ||
| 1915 | complete(ioc_gone); | ||
| 1916 | synchronize_rcu(); | ||
| 1904 | kmem_cache_destroy(arq_pool); | 1917 | kmem_cache_destroy(arq_pool); |
| 1905 | } | 1918 | } |
| 1906 | 1919 | ||
