|
|
|
#ifndef _RAID1_H
|
|
|
|
#define _RAID1_H
|
|
|
|
|
|
|
|
struct raid1_info {
|
|
|
|
struct md_rdev *rdev;
|
|
|
|
sector_t head_position;
|
|
|
|
|
|
|
|
/* When choose the best device for a read (read_balance())
|
|
|
|
* we try to keep sequential reads one the same device
|
|
|
|
*/
|
|
|
|
sector_t next_seq_sect;
|
md/raid1: prevent merging too large request
For SSD, if request size exceeds specific value (optimal io size), request size
isn't important for bandwidth. In such condition, if making request size bigger
will cause some disks idle, the total throughput will actually drop. A good
example is doing a readahead in a two-disk raid1 setup.
So when should we split big requests? We absolutly don't want to split big
request to very small requests. Even in SSD, big request transfer is more
efficient. This patch only considers request with size above optimal io size.
If all disks are busy, is it worth doing a split? Say optimal io size is 16k,
two requests 32k and two disks. We can let each disk run one 32k request, or
split the requests to 4 16k requests and each disk runs two. It's hard to say
which case is better, depending on hardware.
So only consider case where there are idle disks. For readahead, split is
always better in this case. And in my test, below patch can improve > 30%
thoughput. Hmm, not 100%, because disk isn't 100% busy.
Such case can happen not just in readahead, for example, in directio. But I
suppose directio usually will have bigger IO depth and make all disks busy, so
I ignored it.
Note: if the raid uses any hard disk, we don't prevent merging. That will make
performace worse.
Signed-off-by: Shaohua Li <shli@fusionio.com>
Signed-off-by: NeilBrown <neilb@suse.de>
13 years ago
|
|
|
sector_t seq_start;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* memory pools need a pointer to the mddev, so they can force an unplug
|
|
|
|
* when memory is tight, and a count of the number of drives that the
|
|
|
|
* pool was allocated for, so they know how much to allocate and free.
|
|
|
|
* mddev->raid_disks cannot be used, as it can change while a pool is active
|
|
|
|
* These two datums are stored in a kmalloced struct.
|
|
|
|
* The 'raid_disks' here is twice the raid_disks in r1conf.
|
|
|
|
* This allows space for each 'real' device can have a replacement in the
|
|
|
|
* second half of the array.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct pool_info {
|
|
|
|
struct mddev *mddev;
|
|
|
|
int raid_disks;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct r1conf {
|
|
|
|
struct mddev *mddev;
|
|
|
|
struct raid1_info *mirrors; /* twice 'raid_disks' to
|
|
|
|
* allow for replacements.
|
|
|
|
*/
|
|
|
|
int raid_disks;
|
|
|
|
|
|
|
|
/* During resync, read_balancing is only allowed on the part
|
|
|
|
* of the array that has been resynced. 'next_resync' tells us
|
|
|
|
* where that is.
|
|
|
|
*/
|
|
|
|
sector_t next_resync;
|
|
|
|
|
raid1: Rewrite the implementation of iobarrier.
There is an iobarrier in raid1 because of contention between normal IO and
resync IO. It suspends all normal IO when resync/recovery happens.
However if normal IO is out side the resync window, there is no contention.
So this patch changes the barrier mechanism to only block IO that
could contend with the resync that is currently happening.
We partition the whole space into five parts.
|---------|-----------|------------|----------------|-------|
start next_resync start_next_window end_window
start + RESYNC_WINDOW = next_resync
next_resync + NEXT_NORMALIO_DISTANCE = start_next_window
start_next_window + NEXT_NORMALIO_DISTANCE = end_window
Firstly we introduce some concepts:
1 - RESYNC_WINDOW: For resync, there are 32 resync requests at most at the
same time. A sync request is RESYNC_BLOCK_SIZE(64*1024).
So the RESYNC_WINDOW is 32 * RESYNC_BLOCK_SIZE, that is 2MB.
2 - NEXT_NORMALIO_DISTANCE: the distance between next_resync
and start_next_window. It also indicates the distance between
start_next_window and end_window.
It is currently 3 * RESYNC_WINDOW_SIZE but could be tuned if
this turned out not to be optimal.
3 - next_resync: the next sector at which we will do sync IO.
4 - start: a position which is at most RESYNC_WINDOW before
next_resync.
5 - start_next_window: a position which is NEXT_NORMALIO_DISTANCE
beyond next_resync. Normal-io after this position doesn't need to
wait for resync-io to complete.
6 - end_window: a position which is 2 * NEXT_NORMALIO_DISTANCE beyond
next_resync. This also doesn't need to wait, but is counted
differently.
7 - current_window_requests: the count of normalIO between
start_next_window and end_window.
8 - next_window_requests: the count of normalIO after end_window.
NormalIO will be partitioned into four types:
NormIO1: the end sector of bio is smaller or equal the start
NormIO2: the start sector of bio larger or equal to end_window
NormIO3: the start sector of bio larger or equal to
start_next_window.
NormIO4: the location between start_next_window and end_window
|--------|-----------|--------------------|----------------|-------------|
| start | next_resync | start_next_window | end_window |
NormIO1 NormIO4 NormIO4 NormIO3 NormIO2
For NormIO1, we don't need any io barrier.
For NormIO4, we used a similar approach to the original iobarrier
mechanism. The normalIO and resyncIO must be kept separate.
For NormIO2/3, we add two fields to struct r1conf: "current_window_requests"
and "next_window_requests". They indicate the count of active
requests in the two window.
For these, we don't wait for resync io to complete.
For resync action, if there are NormIO4s, we must wait for it.
If not, we can proceed.
But if resync action reaches start_next_window and
current_window_requests > 0 (that is there are NormIO3s), we must
wait until the current_window_requests becomes zero.
When current_window_requests becomes zero, start_next_window also
moves forward. Then current_window_requests will replaced by
next_window_requests.
There is a problem which when and how to change from NormIO2 to
NormIO3. Only then can sync action progress.
We add a field in struct r1conf "start_next_window".
A: if start_next_window == MaxSector, it means there are no NormIO2/3.
So start_next_window = next_resync + NEXT_NORMALIO_DISTANCE
B: if current_window_requests == 0 && next_window_requests != 0, it
means start_next_window move to end_window
There is another problem which how to differentiate between
old NormIO2(now it is NormIO3) and NormIO2.
For example, there are many bios which are NormIO2 and a bio which is
NormIO3. NormIO3 firstly completed, so the bios of NormIO2 became NormIO3.
We add a field in struct r1bio "start_next_window".
This is used to record the position conf->start_next_window when the call
to wait_barrier() is made in make_request().
In allow_barrier(), we check the conf->start_next_window.
If r1bio->stat_next_window == conf->start_next_window, it means
there is no transition between NormIO2 and NormIO3.
If r1bio->start_next_window != conf->start_next_window, it mean
there was a transition between NormIO2 and NormIO3. There can only
have been one transition. So it only means the bio is old NormIO2.
For one bio, there may be many r1bio's. So we make sure
all the r1bio->start_next_window are the same value.
If we met blocked_dev in make_request(), it must call allow_barrier
and wait_barrier. So the former and the later value of
conf->start_next_window will be change.
If there are many r1bio's with differnet start_next_window,
for the relevant bio, it depend on the last value of r1bio.
It will cause error. To avoid this, we must wait for previous r1bios
to complete.
Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
11 years ago
|
|
|
/* When raid1 starts resync, we divide array into four partitions
|
|
|
|
* |---------|--------------|---------------------|-------------|
|
|
|
|
* next_resync start_next_window end_window
|
|
|
|
* start_next_window = next_resync + NEXT_NORMALIO_DISTANCE
|
|
|
|
* end_window = start_next_window + NEXT_NORMALIO_DISTANCE
|
|
|
|
* current_window_requests means the count of normalIO between
|
|
|
|
* start_next_window and end_window.
|
|
|
|
* next_window_requests means the count of normalIO after end_window.
|
|
|
|
* */
|
|
|
|
sector_t start_next_window;
|
|
|
|
int current_window_requests;
|
|
|
|
int next_window_requests;
|
|
|
|
|
|
|
|
spinlock_t device_lock;
|
|
|
|
|
|
|
|
/* list of 'struct r1bio' that need to be processed by raid1d,
|
|
|
|
* whether to retry a read, writeout a resync or recovery
|
|
|
|
* block, or anything else.
|
|
|
|
*/
|
|
|
|
struct list_head retry_list;
|
|
|
|
|
|
|
|
/* queue pending writes to be submitted on unplug */
|
|
|
|
struct bio_list pending_bio_list;
|
|
|
|
int pending_count;
|
|
|
|
|
|
|
|
/* for use when syncing mirrors:
|
|
|
|
* We don't allow both normal IO and resync/recovery IO at
|
|
|
|
* the same time - resync/recovery can only happen when there
|
|
|
|
* is no other IO. So when either is active, the other has to wait.
|
|
|
|
* See more details description in raid1.c near raise_barrier().
|
|
|
|
*/
|
|
|
|
wait_queue_head_t wait_barrier;
|
|
|
|
spinlock_t resync_lock;
|
|
|
|
int nr_pending;
|
|
|
|
int nr_waiting;
|
|
|
|
int nr_queued;
|
|
|
|
int barrier;
|
|
|
|
int array_frozen;
|
|
|
|
|
|
|
|
/* Set to 1 if a full sync is needed, (fresh device added).
|
|
|
|
* Cleared when a sync completes.
|
|
|
|
*/
|
|
|
|
int fullsync;
|
|
|
|
|
|
|
|
/* When the same as mddev->recovery_disabled we don't allow
|
|
|
|
* recovery to be attempted as we expect a read error.
|
|
|
|
*/
|
|
|
|
int recovery_disabled;
|
|
|
|
|
|
|
|
/* poolinfo contains information about the content of the
|
|
|
|
* mempools - it changes when the array grows or shrinks
|
|
|
|
*/
|
|
|
|
struct pool_info *poolinfo;
|
|
|
|
mempool_t *r1bio_pool;
|
|
|
|
mempool_t *r1buf_pool;
|
|
|
|
|
|
|
|
/* temporary buffer to synchronous IO when attempting to repair
|
|
|
|
* a read error.
|
|
|
|
*/
|
|
|
|
struct page *tmppage;
|
|
|
|
|
|
|
|
/* When taking over an array from a different personality, we store
|
|
|
|
* the new thread here until we fully activate the array.
|
|
|
|
*/
|
|
|
|
struct md_thread *thread;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* this is our 'private' RAID1 bio.
|
|
|
|
*
|
|
|
|
* it contains information about what kind of IO operations were started
|
|
|
|
* for this RAID1 operation, and about their status:
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct r1bio {
|
|
|
|
atomic_t remaining; /* 'have we finished' count,
|
|
|
|
* used from IRQ handlers
|
|
|
|
*/
|
|
|
|
atomic_t behind_remaining; /* number of write-behind ios remaining
|
|
|
|
* in this BehindIO request
|
|
|
|
*/
|
|
|
|
sector_t sector;
|
raid1: Rewrite the implementation of iobarrier.
There is an iobarrier in raid1 because of contention between normal IO and
resync IO. It suspends all normal IO when resync/recovery happens.
However if normal IO is out side the resync window, there is no contention.
So this patch changes the barrier mechanism to only block IO that
could contend with the resync that is currently happening.
We partition the whole space into five parts.
|---------|-----------|------------|----------------|-------|
start next_resync start_next_window end_window
start + RESYNC_WINDOW = next_resync
next_resync + NEXT_NORMALIO_DISTANCE = start_next_window
start_next_window + NEXT_NORMALIO_DISTANCE = end_window
Firstly we introduce some concepts:
1 - RESYNC_WINDOW: For resync, there are 32 resync requests at most at the
same time. A sync request is RESYNC_BLOCK_SIZE(64*1024).
So the RESYNC_WINDOW is 32 * RESYNC_BLOCK_SIZE, that is 2MB.
2 - NEXT_NORMALIO_DISTANCE: the distance between next_resync
and start_next_window. It also indicates the distance between
start_next_window and end_window.
It is currently 3 * RESYNC_WINDOW_SIZE but could be tuned if
this turned out not to be optimal.
3 - next_resync: the next sector at which we will do sync IO.
4 - start: a position which is at most RESYNC_WINDOW before
next_resync.
5 - start_next_window: a position which is NEXT_NORMALIO_DISTANCE
beyond next_resync. Normal-io after this position doesn't need to
wait for resync-io to complete.
6 - end_window: a position which is 2 * NEXT_NORMALIO_DISTANCE beyond
next_resync. This also doesn't need to wait, but is counted
differently.
7 - current_window_requests: the count of normalIO between
start_next_window and end_window.
8 - next_window_requests: the count of normalIO after end_window.
NormalIO will be partitioned into four types:
NormIO1: the end sector of bio is smaller or equal the start
NormIO2: the start sector of bio larger or equal to end_window
NormIO3: the start sector of bio larger or equal to
start_next_window.
NormIO4: the location between start_next_window and end_window
|--------|-----------|--------------------|----------------|-------------|
| start | next_resync | start_next_window | end_window |
NormIO1 NormIO4 NormIO4 NormIO3 NormIO2
For NormIO1, we don't need any io barrier.
For NormIO4, we used a similar approach to the original iobarrier
mechanism. The normalIO and resyncIO must be kept separate.
For NormIO2/3, we add two fields to struct r1conf: "current_window_requests"
and "next_window_requests". They indicate the count of active
requests in the two window.
For these, we don't wait for resync io to complete.
For resync action, if there are NormIO4s, we must wait for it.
If not, we can proceed.
But if resync action reaches start_next_window and
current_window_requests > 0 (that is there are NormIO3s), we must
wait until the current_window_requests becomes zero.
When current_window_requests becomes zero, start_next_window also
moves forward. Then current_window_requests will replaced by
next_window_requests.
There is a problem which when and how to change from NormIO2 to
NormIO3. Only then can sync action progress.
We add a field in struct r1conf "start_next_window".
A: if start_next_window == MaxSector, it means there are no NormIO2/3.
So start_next_window = next_resync + NEXT_NORMALIO_DISTANCE
B: if current_window_requests == 0 && next_window_requests != 0, it
means start_next_window move to end_window
There is another problem which how to differentiate between
old NormIO2(now it is NormIO3) and NormIO2.
For example, there are many bios which are NormIO2 and a bio which is
NormIO3. NormIO3 firstly completed, so the bios of NormIO2 became NormIO3.
We add a field in struct r1bio "start_next_window".
This is used to record the position conf->start_next_window when the call
to wait_barrier() is made in make_request().
In allow_barrier(), we check the conf->start_next_window.
If r1bio->stat_next_window == conf->start_next_window, it means
there is no transition between NormIO2 and NormIO3.
If r1bio->start_next_window != conf->start_next_window, it mean
there was a transition between NormIO2 and NormIO3. There can only
have been one transition. So it only means the bio is old NormIO2.
For one bio, there may be many r1bio's. So we make sure
all the r1bio->start_next_window are the same value.
If we met blocked_dev in make_request(), it must call allow_barrier
and wait_barrier. So the former and the later value of
conf->start_next_window will be change.
If there are many r1bio's with differnet start_next_window,
for the relevant bio, it depend on the last value of r1bio.
It will cause error. To avoid this, we must wait for previous r1bios
to complete.
Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
11 years ago
|
|
|
sector_t start_next_window;
|
|
|
|
int sectors;
|
|
|
|
unsigned long state;
|
|
|
|
struct mddev *mddev;
|
|
|
|
/*
|
|
|
|
* original bio going to /dev/mdx
|
|
|
|
*/
|
|
|
|
struct bio *master_bio;
|
|
|
|
/*
|
|
|
|
* if the IO is in READ direction, then this is where we read
|
|
|
|
*/
|
|
|
|
int read_disk;
|
|
|
|
|
|
|
|
struct list_head retry_list;
|
|
|
|
/* Next two are only valid when R1BIO_BehindIO is set */
|
|
|
|
struct bio_vec *behind_bvecs;
|
|
|
|
int behind_page_count;
|
|
|
|
/*
|
|
|
|
* if the IO is in WRITE direction, then multiple bios are used.
|
|
|
|
* We choose the number when they are allocated.
|
|
|
|
*/
|
|
|
|
struct bio *bios[0];
|
|
|
|
/* DO NOT PUT ANY NEW FIELDS HERE - bios array is contiguously alloced*/
|
|
|
|
};
|
|
|
|
|
|
|
|
/* bits for r1bio.state */
|
|
|
|
#define R1BIO_Uptodate 0
|
|
|
|
#define R1BIO_IsSync 1
|
|
|
|
#define R1BIO_Degraded 2
|
[PATCH] md: support BIO_RW_BARRIER for md/raid1
We can only accept BARRIER requests if all slaves handle
barriers, and that can, of course, change with time....
So we keep track of whether the whole array seems safe for barriers,
and also whether each individual rdev handles barriers.
We initially assumes barriers are OK.
When writing the superblock we try a barrier, and if that fails, we flag
things for no-barriers. This will usually clear the flags fairly quickly.
If writing the superblock finds that BIO_RW_BARRIER is -ENOTSUPP, we need to
resubmit, so introduce function "md_super_wait" which waits for requests to
finish, and retries ENOTSUPP requests without the barrier flag.
When writing the real raid1, write requests which were BIO_RW_BARRIER but
which aresn't supported need to be retried. So raid1d is enhanced to do this,
and when any bio write completes (i.e. no retry needed) we remove it from the
r1bio, so that devices needing retry are easy to find.
We should hardly ever get -ENOTSUPP errors when writing data to the raid.
It should only happen if:
1/ the device used to support BARRIER, but now doesn't. Few devices
change like this, though raid1 can!
or
2/ the array has no persistent superblock, so there was no opportunity to
pre-test for barriers when writing the superblock.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
19 years ago
|
|
|
#define R1BIO_BehindIO 3
|
|
|
|
/* Set ReadError on bios that experience a readerror so that
|
|
|
|
* raid1d knows what to do with them.
|
|
|
|
*/
|
|
|
|
#define R1BIO_ReadError 4
|
|
|
|
/* For write-behind requests, we call bi_end_io when
|
|
|
|
* the last non-write-behind device completes, providing
|
|
|
|
* any write was successful. Otherwise we call when
|
|
|
|
* any write-behind write succeeds, otherwise we call
|
|
|
|
* with failure when last write completes (and all failed).
|
|
|
|
* Record that bi_end_io was called with this flag...
|
|
|
|
*/
|
|
|
|
#define R1BIO_Returned 6
|
|
|
|
/* If a write for this request means we can clear some
|
|
|
|
* known-bad-block records, we set this flag
|
|
|
|
*/
|
|
|
|
#define R1BIO_MadeGood 7
|
|
|
|
#define R1BIO_WriteError 8
|
|
|
|
|
|
|
|
extern int md_raid1_congested(struct mddev *mddev, int bits);
|
|
|
|
|
|
|
|
#endif
|