From patchwork Fri Aug 27 01:43:46 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Junichi Nomura X-Patchwork-Id: 136251 Received: from mx02.colomx.prod.int.phx2.redhat.com (mx4-phx2.redhat.com [209.132.183.25]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o7R1wIwQ029847 for ; Fri, 27 Aug 2010 02:02:33 GMT Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx02.colomx.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o7R1rX92000498; Thu, 26 Aug 2010 21:53:34 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o7R1rWYt013104 for ; Thu, 26 Aug 2010 21:53:32 -0400 Received: from mx1.redhat.com (ext-mx05.extmail.prod.ext.phx2.redhat.com [10.5.110.9]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o7R1rRpw032242; Thu, 26 Aug 2010 21:53:27 -0400 Received: from tyo202.gate.nec.co.jp (TYO202.gate.nec.co.jp [202.32.8.206]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o7R1rEfh018311; Thu, 26 Aug 2010 21:53:15 -0400 Received: from mailgate3.nec.co.jp ([10.7.69.197]) by tyo202.gate.nec.co.jp (8.13.8/8.13.4) with ESMTP id o7R1r6Dn029866; Fri, 27 Aug 2010 10:53:06 +0900 (JST) Received: (from root@localhost) by mailgate3.nec.co.jp (8.11.7/3.7W-MAILGATE-NEC) id o7R1r5F17918; Fri, 27 Aug 2010 10:53:05 +0900 (JST) Received: from mail03.kamome.nec.co.jp (mail03.kamome.nec.co.jp [10.25.43.7]) by mailsv.nec.co.jp (8.13.8/8.13.4) with ESMTP id o7R1r4wj012849; Fri, 27 Aug 2010 10:53:04 +0900 (JST) Received: from yonosuke.jp.nec.com ([10.26.220.15] [10.26.220.15]) by mail03.kamome.nec.co.jp with ESMTP id BT-MMP-198115; Fri, 27 Aug 2010 10:43:47 +0900 Received: from xzibit.linux.bs1.fc.nec.co.jp ([10.34.125.170] [10.34.125.170]) by mail.jp.nec.com with ESMTP; Fri, 27 Aug 2010 10:43:46 +0900 Message-ID: <4C771852.3050500@ce.jp.nec.com> Date: Fri, 27 Aug 2010 10:43:46 +0900 From: "Jun'ichi Nomura" User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.10) Gecko/20100621 Fedora/3.0.5-1.fc13 Thunderbird/3.0.5 MIME-Version: 1.0 To: Mike Snitzer References: <20100727165627.GA474@lst.de> <20100727175418.GF6820@quack.suse.cz> <20100803184939.GA12198@lst.de> <20100803185148.GA12258@lst.de> <4C58F341.9060605@ct.jp.nec.com> <20100804085423.GA15687@lst.de> <4C5A1F05.40308@ce.jp.nec.com> <20100826225024.GB17832@redhat.com> In-Reply-To: <20100826225024.GB17832@redhat.com> X-RedHat-Spam-Score: -0.002 (SPF_HELO_PASS,SPF_PASS) X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-Scanned-By: MIMEDefang 2.67 on 10.5.110.9 X-loop: dm-devel@redhat.com Cc: Kiyoshi Ueda , Jan Kara , linux-scsi@vger.kernel.org, jaxboe@fusionio.com, swhiteho@redhat.com, linux-raid@vger.kernel.org, tj@kernel.org, dm-devel@redhat.com, James.Bottomley@suse.de, konishi.ryusuke@lab.ntt.co.jp, linux-fsdevel@vger.kernel.org, tytso@mit.edu, Christoph Hellwig , chris.mason@oracle.com Subject: Re: [dm-devel] [PATCH, RFC 2/2] dm: support REQ_FLUSH directly X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk Reply-To: device-mapper development List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Fri, 27 Aug 2010 02:06:05 +0000 (UTC) Index: linux-2.6.36-rc2/drivers/md/dm.c =================================================================== --- linux-2.6.36-rc2.orig/drivers/md/dm.c +++ linux-2.6.36-rc2/drivers/md/dm.c @@ -162,6 +162,7 @@ struct mapped_device { /* A pointer to the currently processing pre/post flush request */ struct request *flush_request; + atomic_t flush_pending; /* * The current mapping. @@ -777,10 +778,16 @@ static void store_barrier_error(struct m * the md may be freed in dm_put() at the end of this function. * Or do dm_get() before calling this function and dm_put() later. */ -static void rq_completed(struct mapped_device *md, int rw, int run_queue) +static void rq_completed(struct mapped_device *md, int rw, int run_queue, bool is_flush) { atomic_dec(&md->pending[rw]); + if (is_flush) { + atomic_dec(&md->flush_pending); + if (!atomic_read(&md->flush_pending)) + wake_up(&md->wait); + } + /* nudge anyone waiting on suspend queue */ if (!md_in_flight(md)) wake_up(&md->wait); @@ -837,7 +844,7 @@ static void dm_end_request(struct reques } else blk_end_request_all(rq, error); - rq_completed(md, rw, run_queue); + rq_completed(md, rw, run_queue, is_barrier); } static void dm_unprep_request(struct request *rq) @@ -880,7 +887,7 @@ void dm_requeue_unmapped_request(struct blk_requeue_request(q, rq); spin_unlock_irqrestore(q->queue_lock, flags); - rq_completed(md, rw, 0); + rq_completed(md, rw, 0, false); } EXPORT_SYMBOL_GPL(dm_requeue_unmapped_request); @@ -1993,6 +2000,7 @@ static struct mapped_device *alloc_dev(i atomic_set(&md->pending[0], 0); atomic_set(&md->pending[1], 0); + atomic_set(&md->flush_pending, 0); init_waitqueue_head(&md->wait); INIT_WORK(&md->work, dm_wq_work); INIT_WORK(&md->barrier_work, dm_rq_barrier_work); @@ -2375,7 +2383,7 @@ void dm_put(struct mapped_device *md) } EXPORT_SYMBOL_GPL(dm_put); -static int dm_wait_for_completion(struct mapped_device *md, int interruptible) +static int dm_wait_for_completion(struct mapped_device *md, int interruptible, bool for_flush) { int r = 0; DECLARE_WAITQUEUE(wait, current); @@ -2388,6 +2396,8 @@ static int dm_wait_for_completion(struct set_current_state(interruptible); smp_mb(); + if (for_flush && !atomic_read(&md->flush_pending)) + break; if (!md_in_flight(md)) break; @@ -2408,14 +2418,14 @@ static int dm_wait_for_completion(struct static void dm_flush(struct mapped_device *md) { - dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE); + dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE, false); bio_init(&md->barrier_bio); md->barrier_bio.bi_bdev = md->bdev; md->barrier_bio.bi_rw = WRITE_BARRIER; __split_and_process_bio(md, &md->barrier_bio); - dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE); + dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE, false); } static void process_barrier(struct mapped_device *md, struct bio *bio) @@ -2512,11 +2522,12 @@ static int dm_rq_barrier(struct mapped_d clone = clone_rq(md->flush_request, md, GFP_NOIO); dm_rq_set_target_request_nr(clone, j); atomic_inc(&md->pending[rq_data_dir(clone)]); + atomic_inc(&md->flush_pending); map_request(ti, clone, md); } } - dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE); + dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE, true); dm_table_put(map); return md->barrier_error; @@ -2705,7 +2716,7 @@ int dm_suspend(struct mapped_device *md, * We call dm_wait_for_completion to wait for all existing requests * to finish. */ - r = dm_wait_for_completion(md, TASK_INTERRUPTIBLE); + r = dm_wait_for_completion(md, TASK_INTERRUPTIBLE, false); down_write(&md->io_lock); if (noflush)