diff options
author | Shaohua Li <shli@kernel.org> | 2012-07-19 02:01:31 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2012-07-19 02:01:31 -0400 |
commit | b17459c05000fdbe8d10946570a26510f86ec0f6 (patch) | |
tree | 251a9e640d91a9b9ffc804519ea07ed365035636 /drivers/md/raid5.h | |
parent | 7eaf7e8eb31747e4259d60288b44b194fb3d56c7 (diff) |
raid5: add a per-stripe lock
Add a per-stripe lock to protect stripe specific data. The purpose is to reduce
lock contention of conf->device_lock.
stripe ->toread, ->towrite are protected by per-stripe lock. Accessing bio
list of the stripe is always serialized by this lock, so adding bio to the
lists (add_stripe_bio()) and removing bio from the lists (like
ops_run_biofill()) not race.
If bio in ->read, ->written ... list are not shared by multiple stripes, we
don't need any lock to protect ->read, ->written, because STRIPE_ACTIVE will
protect them. If the bio are shared, there are two protections:
1. bi_phys_segments acts as a reference count
2. traverse the list uses r5_next_bio, which makes traverse never access bio
not belonging to the stripe
Let's have an example:
| stripe1 | stripe2 | stripe3 |
...bio1......|bio2|bio3|....bio4.....
stripe2 has 4 bios, when it's finished, it will decrement bi_phys_segments for
all bios, but only end_bio for bio2 and bio3. bio1->bi_next still points to
bio2, but this doesn't matter. When stripe1 is finished, it will not touch bio2
because of r5_next_bio check. Next time stripe1 will end_bio for bio1 and
stripe3 will end_bio bio4.
before add_stripe_bio() addes a bio to a stripe, we already increament the bio
bi_phys_segments, so don't worry other stripes release the bio.
Signed-off-by: Shaohua Li <shli@fusionio.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid5.h')
-rw-r--r-- | drivers/md/raid5.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h index 2164021f3b5f..f03fb3395183 100644 --- a/drivers/md/raid5.h +++ b/drivers/md/raid5.h | |||
@@ -210,6 +210,7 @@ struct stripe_head { | |||
210 | int disks; /* disks in stripe */ | 210 | int disks; /* disks in stripe */ |
211 | enum check_states check_state; | 211 | enum check_states check_state; |
212 | enum reconstruct_states reconstruct_state; | 212 | enum reconstruct_states reconstruct_state; |
213 | spinlock_t stripe_lock; | ||
213 | /** | 214 | /** |
214 | * struct stripe_operations | 215 | * struct stripe_operations |
215 | * @target - STRIPE_OP_COMPUTE_BLK target | 216 | * @target - STRIPE_OP_COMPUTE_BLK target |