From fba822722e3f9d438fca8fd9541d7ddd447d7a48 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Tue, 18 Apr 2006 09:44:06 +0200 Subject: [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 Signed-off-by: Jens Axboe --- block/as-iosched.c | 5 +++-- block/cfq-iosched.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'block') diff --git a/block/as-iosched.c b/block/as-iosched.c index 296708ceceb..e25a5d79ab2 100644 --- a/block/as-iosched.c +++ b/block/as-iosched.c @@ -1844,9 +1844,10 @@ static void __exit as_exit(void) DECLARE_COMPLETION(all_gone); elv_unregister(&iosched_as); ioc_gone = &all_gone; - barrier(); + /* ioc_gone's update must be visible before reading ioc_count */ + smp_wmb(); if (atomic_read(&ioc_count)) - complete(ioc_gone); + wait_for_completion(ioc_gone); synchronize_rcu(); kmem_cache_destroy(arq_pool); } diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 67d446de022..01820b1094e 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -2439,9 +2439,10 @@ static void __exit cfq_exit(void) DECLARE_COMPLETION(all_gone); elv_unregister(&iosched_cfq); ioc_gone = &all_gone; - barrier(); + /* ioc_gone's update must be visible before reading ioc_count */ + smp_wmb(); if (atomic_read(&ioc_count)) - complete(ioc_gone); + wait_for_completion(ioc_gone); synchronize_rcu(); cfq_slab_kill(); } -- cgit v1.2.2