discard request usually is very big and easily use all bandwidth budget of a cgroup. discard request size doesn't really mean the size of data written, so it doesn't make sense to account it into bandwidth budget. Jens pointed out treating the size 0 doesn't make sense too, because discard request does have cost. But it's not easy to find the actual cost. This patch simply makes the size one sector.
Unified · Split
| @@ -382,6 +382,14 @@ static unsigned int tg_iops_limit(struct throtl_grp *tg, int rw) · 381 unmodified lines | ||
| 382 | 382 | } \ |
| 383 | 383 | } while (0) |
| 384 | 384 | |
| 385 | +static inline unsigned int throtl_bio_data_size(struct bio *bio) | |
| 386 | +{ | |
| 387 | + /* assume it's one sector */ | |
| 388 | + if (unlikely(bio_op(bio) == REQ_OP_DISCARD)) | |
| 389 | + return 512; | |
| 390 | + return bio->bi_iter.bi_size; | |
| 391 | +} | |
| 392 | + | |
| 385 | 393 | static void throtl_qnode_init(struct throtl_qnode *qn, struct throtl_grp *tg) |
| 386 | 394 | { |
| 387 | 395 | INIT_LIST_HEAD(&qn->node); |
| @@ -934,6 +942,7 @@ static bool tg_with_in_bps_limit(struct throtl_grp *tg, struct bio *bio, · 546 unmodified lines | ||
| 934 | 942 | bool rw = bio_data_dir(bio); |
| 935 | 943 | u64 bytes_allowed, extra_bytes, tmp; |
| 936 | 944 | unsigned long jiffy_elapsed, jiffy_wait, jiffy_elapsed_rnd; |
| 945 | + unsigned int bio_size = throtl_bio_data_size(bio); | |
| 937 | 946 | |
| 938 | 947 | jiffy_elapsed = jiffy_elapsed_rnd = jiffies - tg->slice_start[rw]; |
| 939 | 948 | |
| @@ -947,14 +956,14 @@ static bool tg_with_in_bps_limit(struct throtl_grp *tg, struct bio *bio, · 7 unmodified lines | ||
| 947 | 956 | do_div(tmp, HZ); |
| 948 | 957 | bytes_allowed = tmp; |
| 949 | 958 | |
| 950 | − if (tg->bytes_disp[rw] + bio->bi_iter.bi_size <= bytes_allowed) { | |
| 959 | + if (tg->bytes_disp[rw] + bio_size <= bytes_allowed) { | |
| 951 | 960 | if (wait) |
| 952 | 961 | *wait = 0; |
| 953 | 962 | return true; |
| 954 | 963 | } |
| 955 | 964 | |
| 956 | 965 | /* Calc approx time to dispatch */ |
| 957 | − extra_bytes = tg->bytes_disp[rw] + bio->bi_iter.bi_size - bytes_allowed; | |
| 966 | + extra_bytes = tg->bytes_disp[rw] + bio_size - bytes_allowed; | |
| 958 | 967 | jiffy_wait = div64_u64(extra_bytes * HZ, tg_bps_limit(tg, rw)); |
| 959 | 968 | |
| 960 | 969 | if (!jiffy_wait) |
| @@ -1034,11 +1043,12 @@ static bool tg_may_dispatch(struct throtl_grp *tg, struct bio *bio, · 73 unmodified lines | ||
| 1034 | 1043 | static void throtl_charge_bio(struct throtl_grp *tg, struct bio *bio) |
| 1035 | 1044 | { |
| 1036 | 1045 | bool rw = bio_data_dir(bio); |
| 1046 | + unsigned int bio_size = throtl_bio_data_size(bio); | |
| 1037 | 1047 | |
| 1038 | 1048 | /* Charge the bio to the group */ |
| 1039 | − tg->bytes_disp[rw] += bio->bi_iter.bi_size; | |
| 1049 | + tg->bytes_disp[rw] += bio_size; | |
| 1040 | 1050 | tg->io_disp[rw]++; |
| 1041 | − tg->last_bytes_disp[rw] += bio->bi_iter.bi_size; | |
| 1051 | + tg->last_bytes_disp[rw] += bio_size; | |
| 1042 | 1052 | tg->last_io_disp[rw]++; |
| 1043 | 1053 | |
| 1044 | 1054 | /* |