Re: [PATCH V3 1/2] RAID1: a new I/O barrier implementation to remove resync window

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2017/2/17 上午1:05, Coly Li wrote:
> On 2017/2/16 上午10:22, Shaohua Li wrote:
>> On Thu, Feb 16, 2017 at 12:35:22AM +0800, colyli@xxxxxxx wrote:

[snip]
>>
>>>  
>>> -static void raid1_read_request(struct mddev *mddev, struct bio *bio,
>>> -				 struct r1bio *r1_bio)
>>> +static void raid1_read_request(struct mddev *mddev, struct bio *bio)
>>>  {
>>>  	struct r1conf *conf = mddev->private;
>>>  	struct raid1_info *mirror;
>>> +	struct r1bio *r1_bio;
>>>  	struct bio *read_bio;
>>>  	struct bitmap *bitmap = mddev->bitmap;
>>>  	const int op = bio_op(bio);
>>> @@ -1083,7 +1101,34 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
>>>  	int max_sectors;
>>>  	int rdisk;
>>>  
>>> -	wait_barrier(conf, bio);
>>> +	/*
>>> +	 * Still need barrier for READ in case that whole
>>> +	 * array is frozen.
>>> +	 */
>>> +	wait_read_barrier(conf, bio->bi_iter.bi_sector);
>>> +	bitmap = mddev->bitmap;
>>> +
>>> +	/*
>>> +	 * make_request() can abort the operation when read-ahead is being
>>> +	 * used and no empty request is available.
>>> +	 *
>>> +	 */
>>> +	r1_bio = mempool_alloc(conf->r1bio_pool, GFP_NOIO);
>>> +	r1_bio->master_bio = bio;
>>> +	r1_bio->sectors = bio_sectors(bio);
>>> +	r1_bio->state = 0;
>>> +	r1_bio->mddev = mddev;
>>> +	r1_bio->sector = bio->bi_iter.bi_sector;
>>
>> This part looks unnecessary complicated. If you change raid1_make_request to
>> something like __raid1_make_reques, add a new raid1_make_request and do bio
>> split there, then call __raid1_make_request for each splitted bio, then you
>> don't need to duplicate the r1_bio allocation parts for read/write.
>>
> 
> Aha, good point! I will do that.

I find adding one more wrap function increases stack depth in raid1 I/O
path. Finally I choose to use a static inline function to allocate
r1bio, other than wrap one more function.


+static inline struct r1bio *
+alloc_r1bio(struct mddev *mddev, struct bio *bio, sector_t sectors_handled)
+{
+       struct r1conf *conf = mddev->private;
+       struct r1bio *r1_bio = NULL;
+
+
+       r1_bio = mempool_alloc(conf->r1bio_pool, GFP_NOIO);
+       if (!r1_bio) {
+               WARN(1, "%s: fail to allocate r1_bio.\n", __func__);
+               return NULL;
+       }
+
+       r1_bio->master_bio = bio;
+       r1_bio->sectors = bio_sectors(bio) - sectors_handled;
+       r1_bio->state = 0;
+       r1_bio->mddev = mddev;
+       r1_bio->sector = bio->bi_iter.bi_sector + sectors_handled;
+
+       return r1_bio;
+}

A good point is, before jumping to read_again in raid1_read_request() or
jumping to retry_write in raid1_write_request(), this function can help
to remove more redundant code like this,
	r1_bio = alloc_r1bio(mddev, bio, sectors_handled);

I don't check whether alloc_r1bio() returns NULL in neither
raid1_read_request() nor raid1_write_request(). If the allocation
failed, it may cause a NULL pointer deference fault, but I don't plan to
fix it in this patch set, just keep the existing code logic.

Coly


--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux