Linux Device Mapper development
 help / color / mirror / Atom feed
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)

  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox