From: Hannes Reinecke <hare@suse.de>
To: Kiyoshi Ueda <k-ueda@ct.jp.nec.com>
Cc: Christof Schmitt <christof.schmitt@de.ibm.com>,
device-mapper development <dm-devel@redhat.com>,
Alasdair Kergon <agk@redhat.com>
Subject: Re: [PATCH 1/7] dm core: add core functions for request-based dm
Date: Fri, 24 Apr 2009 10:45:52 +0200 [thread overview]
Message-ID: <49F17C40.6020402@suse.de> (raw)
In-Reply-To: <49F17477.1010807@ct.jp.nec.com>
Kiyoshi Ueda wrote:
> This patch adds core functions for request-based dm.
>
> When struct mapped device (md) is initialized, md->queue has
> an I/O scheduler and the following functions are used for
> request-based dm as the queue functions:
> make_request_fn: dm_make_request()
> pref_fn: dm_prep_fn()
> request_fn: dm_request_fn()
> softirq_done_fn: dm_softirq_done()
> lld_busy_fn: dm_lld_busy()
> Actual initializations are done in another patch (PATCH 3).
>
> Below is a brief summary of how request-based dm behaves, including:
> - making request from bio
> - cloning, mapping and dispatching request
> - completing request and bio
> - suspending md
> - resuming md
>
>
> bio to request
> ==============
> md->queue->make_request_fn() (dm_make_request()) calls__make_request()
> for a bio submitted to the md.
> Then, the bio is kept in the queue as a new request or merged into
> another request in the queue if possible.
>
>
> Cloning and Mapping
> ===================
> Cloning and mapping are done in md->queue->request_fn() (dm_request_fn()),
> when requests are dispatched after they are sorted by the I/O scheduler.
>
> dm_request_fn() checks busy state of underlying devices using
> target's busy() function and stops dispatching requests to keep them
> on the dm device's queue if busy.
> It helps better I/O merging, since no merge is done for a request
> once it is dispatched to underlying devices.
>
> Actual cloning and mapping are done in dm_prep_fn() and map_request()
> called from dm_request_fn().
> dm_prep_fn() clones not only request but also bios of the request
> so that dm can hold bio completion in error cases and prevent
> the bio submitter from noticing the error.
> (See the "Completion" section below for details.)
>
> After the cloning, the clone is mapped by target's map_rq() function
> and inserted to underlying device's queue using
> blk_insert_cloned_request().
>
>
> Completion
> ==========
> Request completion can be hooked by rq->end_io(), but then, all bios
> in the request will have been completed even error cases, and the bio
> submitter will have noticed the error.
> To prevent the bio completion in error cases, request-based dm clones
> both bio and request and hooks both bio->bi_end_io() and rq->end_io():
> bio->bi_end_io(): end_clone_bio()
> rq->end_io(): end_clone_request()
>
> Summary of the request completion flow is below:
> blk_end_request() for a clone request
> => __end_that_request_first()
> => bio->bi_end_io() == end_clone_bio() for each clone bio
> => Free the clone bio
> => Success: Complete the original bio (blk_update_request())
> Error: Don't complete the original bio
> => end_that_request_last()
> => rq->end_io() == end_clone_request()
> => blk_complete_request()
> => dm_softirq_done()
> => Free the clone request
> => Success: Complete the original request (blk_end_request())
> Error: Requeue the original request
>
> end_clone_bio() completes the original request on the size of
> the original bio in successful cases.
> Even if all bios in the original request are completed by that
> completion, the original request must not be completed yet to keep
> the ordering of request completion for the stacking.
> So end_clone_bio() uses blk_update_request() instead of
> blk_end_request().
> In error cases, end_clone_bio() doesn't complete the original bio.
> It just frees the cloned bio and gives over the error handling to
> end_clone_request().
>
> end_clone_request(), which is called with queue lock held, completes
> the clone request and the original request in a softirq context
> (dm_softirq_done()), which has no queue lock, to avoid a deadlock
> issue on submission of another request during the completion:
> - The submitted request may be mapped to the same device
> - Request submission requires queue lock, but the queue lock
> has been held by itself and it doesn't know that
>
> The clone request has no clone bio when dm_softirq_done() is called.
> So target drivers can't resubmit it again even error cases.
> Instead, they can ask dm core for requeueing and remapping
> the original request in that cases.
>
>
> suspend
> =======
> Request-based dm uses stopping md->queue as suspend of the md.
> For noflush suspend, just stops md->queue.
>
> For flush suspend, inserts a marker request to the tail of md->queue.
> And dispatches all requests in md->queue until the marker comes to
> the front of md->queue. Then, stops dispatching request and waits
> for the all dispatched requests to complete.
> After that, completes the marker request, stops md->queue and
> wake up the waiter on the suspend queue, md->wait.
>
>
> resume
> ======
> Starts md->queue.
>
>
> Signed-off-by: Kiyoshi Ueda <k-ueda@ct.jp.nec.com>
> Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Acked-by: Hannes Reinecke <hare@suse.de>
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)
next prev parent reply other threads:[~2009-04-24 8:45 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-24 8:10 [PATCH 0/7] request-based dm-multipath (v2) Kiyoshi Ueda
2009-04-24 8:12 ` [PATCH 1/7] dm core: add core functions for request-based dm Kiyoshi Ueda
2009-04-24 8:45 ` Hannes Reinecke [this message]
2009-04-24 8:13 ` [PATCH 2/7] dm core: add integrity feature to " Kiyoshi Ueda
2009-04-24 8:46 ` Hannes Reinecke
2009-04-24 8:14 ` [PATCH 3/7] dm core: enable " Kiyoshi Ueda
2009-04-24 8:50 ` Hannes Reinecke
2009-04-24 8:14 ` [PATCH 4/7] dm core: don't set QUEUE_ORDERED_DRAIN for " Kiyoshi Ueda
2009-04-24 8:51 ` Hannes Reinecke
2009-04-24 8:15 ` [PATCH 5/7] dm core: reject I/O violating new queue limits Kiyoshi Ueda
2009-04-24 8:59 ` Hannes Reinecke
2009-04-28 7:49 ` Kiyoshi Ueda
2009-06-23 5:46 ` Kiyoshi Ueda
2009-04-24 8:15 ` [PATCH 6/7] dm core: disable interrupt when taking map_lock Kiyoshi Ueda
2009-04-24 9:00 ` Hannes Reinecke
2009-04-24 11:50 ` Christof Schmitt
2009-04-24 8:16 ` [PATCH 7/7] dm-mpath: convert to request-based Kiyoshi Ueda
2009-04-24 9:04 ` Hannes Reinecke
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49F17C40.6020402@suse.de \
--to=hare@suse.de \
--cc=agk@redhat.com \
--cc=christof.schmitt@de.ibm.com \
--cc=dm-devel@redhat.com \
--cc=k-ueda@ct.jp.nec.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.