Thread (3 messages) 3 messages, 2 authors, 2014-09-03

Re: [RFC]RAID5: batch adjacent full stripe write

From: Shaohua Li <shli@kernel.org>
Date: 2014-09-03 01:04:59

On Tue, Sep 02, 2014 at 04:52:40PM +1000, NeilBrown wrote:
On Mon, 18 Aug 2014 16:25:31 +0800 Shaohua Li [off-list ref] wrote:
quoted
stripe cache is 4k size. Even adjacent full stripe writes are handled in 4k
unit. Idealy we should use big size for adjacent full stripe writes. Bigger
stripe cache size means less stripes runing in the state machine so can reduce
cpu overhead. And also bigger size can cause bigger IO size dispatched to under
layer disks.

With below patch, we will automatically batch adjacent full stripe write
together. Such stripes will form to a container and be added to the container
list. Only the first stripe of a container will be put to handle_list and so
run handle_stripe(). Some steps of handle_stripe() are extended to cover whole
container stripes, including ops_run_io, ops_run_biodrain and so on. With this
patch, we have less stripes running in handle_stripe() and we send IO of whole
container stripes together to increase IO size.

Stripes added to a container have some limitations. A container can only
include full stripe write and can't cross chunk boundary to make sure stripes
have the same parity disk. Stripes in a container must in the same state (no
written, toread and so on). If a stripe is in a container, all new read/write
to add_stripe_bio will be blocked to overlap conflict till the container are
handled. The limitations will make sure stripes in a container in exactly the
same state in the life circly of the container.

I did test running 160k randwrite in a RAID5 array with 32k chunk size and 6
PCIe SSD. This patch improves around 30% performance and IO size to under layer
disk is exactly 32k. I also run a 4k randwrite test in the same array to make
sure the performance isn't changed with the patch.

Signed-off-by: Shaohua Li <redacted>

Thanks for posting this ... and sorry for taking so long to look at it - I'm
still fighting of the flu so I'm not thinking a clearly as I would like so
I'll have to look over this again once I'm fully recovered.

I think I like it.  It seems more complex than I would like, which makes it
harder to review, but it probably needs to be that complex to actually work.

I'm a bit worried about the ->scribble  usage.  The default chunk size of
512K with means 128 stripe_heads in a batch.  On a 64 bit machine that is
1kilobyte of pointers per device.  8 devices in a RAID6 means more than 8K
needs to be allocated for ->scribble.  That has a risk of failing.

Maybe it would make sense to use a flex_array
(Documentation/flexible-arrays.txt).

Splitting out the changes for ->scribble into a separate patch might help.
Ok, I'll check this.
 
The testing for "can this stripe_head be batched" seems a bit clumsy - lots
of loops hunting for problems.
Could we just set a "don't batch" flag whenever something happens that makes
a stripe un-batchable?  Have another flag that gets set when a stripe becomes
a full-write stripe?
good point!
Can we call the collections of stripe_heads "batch"es rather than
"container"s?   mdadm already used the name "containers" for something else,
and I think "batch" fits better.
Ok.
I think it might be useful if we could start batching together stripe_heads
that are in the same stripe, even before they are full-write.  That might
help the scheduling and avoid some of the unnecessary pre-reading that we
currently do.  I haven't really thought properly about it and don't expect
you to do that, but I thought I'd mention it anyway.
Yep, batching doesn't need to be a full-write. We can do it later. At current
stage, I'd like to make the simplest case work.

Thanks,
Shaohua
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help