On 2013-01-11 10:11, majianpeng wrote:
> In func tg_may_dispatch,
>> if (throtl_slice_used(td, tg, rw))
>>              throtl_start_new_slice(td, tg, rw);
> ...
>> if (tg_with_in_bps_limit(td, tg, bio, &bps_wait)
>>          && tg_with_in_iops_limit(td, tg, bio, &iops_wait)) {
> 
> In funcs tg_with_in_(bps/iops)_limit, it used the slice_start to count.
> So if privious slice expired, it start a new slice.This can cause hung
> task.
> 
> The next steps can repeat this bug.
> 1:echo "8:48 10240" > blkio.throttle.write_bps_devic
> 2:dd if=/dev/zero of=/dev/sdd bs=1M count=1 oflag=direct
> 
> Using the blktrace, the messages about throttle:
> root@kernel:/mnt/programs# blktrace -d /dev/sdd -a notify -o -|blkparse -i -
>   8,48   1        0     0.000000000     0  m   N throtl / [W] new slice 
> start=4294854679 end=4294854779 jiffies=4294854679
>   8,48   1        0     0.000000966     0  m   N throtl / [W] extend slice 
> start=4294854679 end=4294905900 jiffies=4294854679
>   8,48   1        0     0.000002553     0  m   N throtl / [W] bio. bdisp=0 
> sz=524288 bps=10240 iodisp=0 iops=4294967295 queued=0/0
>   8,48   1        0     0.000004788     0  m   N throtl schedule work. 
> delay=51200 jiffies=4294854679
>   8,48   1        0    51.304698681     0  m   N throtl dispatch nr_queued=1 
> read=0 write=1
>   8,48   1        0    51.304701979     0  m   N throtl / [W] new slice 
> start=4294905984 end=4294906084 jiffies=4294905984
>   8,48   1        0    51.304703329     0  m   N throtl / [W] extend slice 
> start=4294905984 end=4294957200 jiffies=4294905984
>   8,48   1        0    51.304705783     0  m   N throtl schedule work. 
> delay=51200 jiffies=4294905984
>   8,48   1        0   102.632697082     0  m   N throtl dispatch nr_queued=1 
> read=0 write=1
>   8,48   1        0   102.632700544     0  m   N throtl / [W] new slice 
> start=4294957312 end=4294957412 jiffies=4294957312
>   8,48   1        0   102.632701922     0  m   N throtl / [W] extend slice 
> start=4294957312 end=4295008600 jiffies=4294957312
>   8,48   1        0   102.632704016     0  m   N throtl schedule work. 
> delay=51200 jiffies=4294957312
>   8,48   1        0   153.960696503     0  m   N throtl dispatch nr_queued=1 
> read=0 write=1
>   8,48   1        0   153.960699797     0  m   N throtl / [W] new slice 
> start=4295008640 end=4295008740 jiffies=4295008640
>   8,48   1        0   153.960701153     0  m   N throtl / [W] extend slice 
> start=4295008640 end=4295059900 jiffies=4295008640
>   8,48   1        0   153.960703218     0  m   N throtl schedule work. 
> delay=51200 jiffies=4295008640
>   8,48   1        0   205.288697067     0  m   N throtl dispatch nr_queued=1 
> read=0 write=1
>   8,48   1        0   205.288700268     0  m   N throtl / [W] new slice 
> start=4295059968 end=4295060068 jiffies=4295059968
>   8,48   1        0   205.288701630     0  m   N throtl / [W] extend slice 
> start=4295059968 end=4295111200 jiffies=4295059968
>   8,48   1        0   205.288703784     0  m   N throtl schedule work. 
> delay=51200 jiffies=4295059968
>   8,48   1        0   256.616696184     0  m   N throtl dispatch nr_queued=1 
> read=0 write=1
>   8,48   1        0   256.616699266     0  m   N throtl / [W] new slice 
> start=4295111296 end=4295111396 jiffies=4295111296
>   8,48   1        0   256.616700574     0  m   N throtl / [W] extend slice 
> start=4295111296 end=4295162500 jiffies=4295111296
>   8,48   1        0   256.616702701     0  m   N throtl schedule work. 
> delay=51200 jiffies=4295111296
> 
> Signed-off-by: Jianpeng Ma <[email protected]>
> ---
>  block/blk-throttle.c |   15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/block/blk-throttle.c b/block/blk-throttle.c
> index 3114622..9258789 100644
> --- a/block/blk-throttle.c
> +++ b/block/blk-throttle.c
> @@ -645,6 +645,15 @@ static bool tg_may_dispatch(struct throtl_data *td, 
> struct throtl_grp *tg,
>       }
>  
>       /*
> +      * If privious slice expired,then start new slice.
> +      * But counting bps and iops limit need privious slice info
> +      * which ->slice_start.
> +      */
> +     if (tg_with_in_bps_limit(td, tg, bio, &bps_wait)
> +         && tg_with_in_iops_limit(td, tg, bio, &iops_wait))
> +             if (wait)
> +                     *wait = 0;
> +     /*
>        * If previous slice expired, start a new one otherwise renew/extend
>        * existing slice to make sure it is at least throtl_slice interval
>        * long since now.
> @@ -656,12 +665,8 @@ static bool tg_may_dispatch(struct throtl_data *td, 
> struct throtl_grp *tg,
>                       throtl_extend_slice(td, tg, rw, jiffies + throtl_slice);
>       }
>  
> -     if (tg_with_in_bps_limit(td, tg, bio, &bps_wait)
> -         && tg_with_in_iops_limit(td, tg, bio, &iops_wait)) {
> -             if (wait)
> -                     *wait = 0;
> +     if (!(bps_wait || iops_wait))
>               return 1;
> -     }
>  
>       max_wait = max(bps_wait, iops_wait);

Looks pretty sane to me. Vivek?

-- 
Jens Axboe

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to