• S
    raid5: add a per-stripe lock · b17459c0
    Shaohua Li 提交于
    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: NShaohua Li <shli@fusionio.com>
    Signed-off-by: NNeilBrown <neilb@suse.de>
    b17459c0
raid5.c 171.9 KB