aboutsummaryrefslogtreecommitdiffstats
path: root/block/as-iosched.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2006-03-18 15:05:53 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2006-03-18 18:34:15 -0500
commit334e94de9bea353156abd6f2242d3cc4a24562b0 (patch)
treeff4a253e9e3bf487be03bf58727a7ea40a34ba87 /block/as-iosched.c
parente17a9489b4a686bb5e9615e1d375c67619cb99c5 (diff)
[PATCH] deal with rmmod/put_io_context() races
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'block/as-iosched.c')
-rw-r--r--block/as-iosched.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/block/as-iosched.c b/block/as-iosched.c
index d2ee2af44b58..55a997fc4bb4 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -182,6 +182,9 @@ struct as_rq {
182 182
183static kmem_cache_t *arq_pool; 183static kmem_cache_t *arq_pool;
184 184
185static atomic_t ioc_count = ATOMIC_INIT(0);
186static struct completion *ioc_gone;
187
185static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq); 188static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq);
186static void as_antic_stop(struct as_data *ad); 189static void as_antic_stop(struct as_data *ad);
187 190
@@ -193,11 +196,14 @@ static void as_antic_stop(struct as_data *ad);
193static void free_as_io_context(struct as_io_context *aic) 196static 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
198static void as_trim(struct io_context *ioc) 203static 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
1901static void __exit as_exit(void) 1908static 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