• Logan Gunthorpe's avatar
    md/raid5: Pivot raid5_make_request() · 7e55c60a
    Logan Gunthorpe authored
    raid5_make_request() loops through every page in the request,
    finds the appropriate stripe and adds the bio for that page in the
    disk.
    
    This causes a great deal of contention on the hash_lock and extra
    work seeing each stripe must be found once for every data disk.
    
    The number of times a stripe must be found can be reduced by pivoting
    raid5_make_request() so that it loops through every stripe and then
    loops through every disk in that stripe to see if the bio must be
    added. This reduces the number of times the hash lock must be taken
    by a factor equal to the number of data disks.
    
    To accomplish this, the logical sectors that have already been added
    must be tracked. Tracking them is done with a bitmap: the bits
    for all pages are set at the start of the request and each bit
    is cleared once the bio is added to a stripe.
    
    Finding the next sector to be done is then just a call to
    find_first_bit() so that sectors that have been done can simply be
    skipped.
    
    One minor downside is that the maximum sectors for a request must be
    limited so that the bitmap can be appropriately sized on the stack.
    This limit is arbitrarily chosen to be 256 stripe pages which works out
    to 1MB if PAGE_SIZE == DEFAULT_STRIPE_SIZE. This doesn't actually
    restrict the maximum request further seeing the default block queue
    settings are used which restricts the number of segments to 128 (which
    results in request sizes that are approximately 512KB).
    Signed-off-by: default avatarLogan Gunthorpe <logang@deltatee.com>
    Signed-off-by: default avatarSong Liu <song@kernel.org>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    7e55c60a
raid5.c 254 KB