diff options
| author | OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 2006-04-18 03:44:06 -0400 |
|---|---|---|
| committer | Jens Axboe <axboe@suse.de> | 2006-04-18 03:44:06 -0400 |
| commit | fba822722e3f9d438fca8fd9541d7ddd447d7a48 (patch) | |
| tree | 05fc35428f61fb6b66726e3aae03ce9187212c21 /block | |
| parent | a9a5cd5d2a57fb76dbae2115450f777b69beccf7 (diff) | |
[PATCH 1/2] iosched: fix typo and barrier()
On rmmod path, cfq/as waits to make sure all io-contexts was
freed. However, it's using complete(), not wait_for_completion().
I think barrier() is not enough in here. To avoid the following case,
this patch replaces barrier() with smb_wmb().
cpu0 visibility cpu1
[ioc_gnone=NULL,ioc_count=1]
ioc_gnone = &all_gone NULL,ioc_count=1
atomic_read(&ioc_count) NULL,ioc_count=1
wait_for_completion() NULL,ioc_count=0 atomic_sub_and_test()
NULL,ioc_count=0 if ( && ioc_gone)
[ioc_gone==NULL,
so doesn't call complete()]
&all_gone,ioc_count=0
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: Jens Axboe <axboe@suse.de>
Diffstat (limited to 'block')
| -rw-r--r-- | block/as-iosched.c | 5 | ||||
| -rw-r--r-- | block/cfq-iosched.c | 5 |
2 files changed, 6 insertions, 4 deletions
diff --git a/block/as-iosched.c b/block/as-iosched.c index 296708ceceb2..e25a5d79ab27 100644 --- a/block/as-iosched.c +++ b/block/as-iosched.c | |||
| @@ -1844,9 +1844,10 @@ static void __exit as_exit(void) | |||
| 1844 | DECLARE_COMPLETION(all_gone); | 1844 | DECLARE_COMPLETION(all_gone); |
| 1845 | elv_unregister(&iosched_as); | 1845 | elv_unregister(&iosched_as); |
| 1846 | ioc_gone = &all_gone; | 1846 | ioc_gone = &all_gone; |
| 1847 | barrier(); | 1847 | /* ioc_gone's update must be visible before reading ioc_count */ |
| 1848 | smp_wmb(); | ||
| 1848 | if (atomic_read(&ioc_count)) | 1849 | if (atomic_read(&ioc_count)) |
| 1849 | complete(ioc_gone); | 1850 | wait_for_completion(ioc_gone); |
| 1850 | synchronize_rcu(); | 1851 | synchronize_rcu(); |
| 1851 | kmem_cache_destroy(arq_pool); | 1852 | kmem_cache_destroy(arq_pool); |
| 1852 | } | 1853 | } |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 67d446de0227..01820b1094e9 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
| @@ -2439,9 +2439,10 @@ static void __exit cfq_exit(void) | |||
| 2439 | DECLARE_COMPLETION(all_gone); | 2439 | DECLARE_COMPLETION(all_gone); |
| 2440 | elv_unregister(&iosched_cfq); | 2440 | elv_unregister(&iosched_cfq); |
| 2441 | ioc_gone = &all_gone; | 2441 | ioc_gone = &all_gone; |
| 2442 | barrier(); | 2442 | /* ioc_gone's update must be visible before reading ioc_count */ |
| 2443 | smp_wmb(); | ||
| 2443 | if (atomic_read(&ioc_count)) | 2444 | if (atomic_read(&ioc_count)) |
| 2444 | complete(ioc_gone); | 2445 | wait_for_completion(ioc_gone); |
| 2445 | synchronize_rcu(); | 2446 | synchronize_rcu(); |
| 2446 | cfq_slab_kill(); | 2447 | cfq_slab_kill(); |
| 2447 | } | 2448 | } |
