cfq-iosched: split seeky coop queues after one slice

Currently we split seeky coop queues after 1s, which is too big. Below patch
marks seeky coop queue split_coop flag after one slice. After that, if new
requests come in, the queues will be splitted. Patch is suggested by Corrado.

Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Reviewed-by: Corrado Zoccolo <czoccolo@gmail.com>
Acked-by: Jeff Moyer <jmoyer@redhat.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>

authored by Shaohua Li and committed by Jens Axboe ae54abed fc76be43

+16 -33
+16 -33
block/cfq-iosched.c
··· 42 42 */ 43 43 #define CFQ_MIN_TT (2) 44 44 45 - /* 46 - * Allow merged cfqqs to perform this amount of seeky I/O before 47 - * deciding to break the queues up again. 48 - */ 49 - #define CFQQ_COOP_TOUT (HZ) 50 - 51 45 #define CFQ_SLICE_SCALE (5) 52 46 #define CFQ_HW_QUEUE_MIN (5) 53 47 #define CFQ_SERVICE_SHIFT 12 48 + 49 + #define CFQQ_SEEK_THR 8 * 1024 50 + #define CFQQ_SEEKY(cfqq) ((cfqq)->seek_mean > CFQQ_SEEK_THR) 54 51 55 52 #define RQ_CIC(rq) \ 56 53 ((struct cfq_io_context *) (rq)->elevator_private) ··· 134 137 u64 seek_total; 135 138 sector_t seek_mean; 136 139 sector_t last_request_pos; 137 - unsigned long seeky_start; 138 140 139 141 pid_t pid; 140 142 ··· 310 314 CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */ 311 315 CFQ_CFQQ_FLAG_sync, /* synchronous queue */ 312 316 CFQ_CFQQ_FLAG_coop, /* cfqq is shared */ 317 + CFQ_CFQQ_FLAG_split_coop, /* shared cfqq will be splitted */ 313 318 CFQ_CFQQ_FLAG_deep, /* sync cfqq experienced large depth */ 314 319 CFQ_CFQQ_FLAG_wait_busy, /* Waiting for next request */ 315 320 }; ··· 339 342 CFQ_CFQQ_FNS(slice_new); 340 343 CFQ_CFQQ_FNS(sync); 341 344 CFQ_CFQQ_FNS(coop); 345 + CFQ_CFQQ_FNS(split_coop); 342 346 CFQ_CFQQ_FNS(deep); 343 347 CFQ_CFQQ_FNS(wait_busy); 344 348 #undef CFQ_CFQQ_FNS ··· 1564 1566 cfq_clear_cfqq_wait_busy(cfqq); 1565 1567 1566 1568 /* 1569 + * If this cfqq is shared between multiple processes, check to 1570 + * make sure that those processes are still issuing I/Os within 1571 + * the mean seek distance. If not, it may be time to break the 1572 + * queues apart again. 1573 + */ 1574 + if (cfq_cfqq_coop(cfqq) && CFQQ_SEEKY(cfqq)) 1575 + cfq_mark_cfqq_split_coop(cfqq); 1576 + 1577 + /* 1567 1578 * store what was left of this slice, if the queue idled/timed out 1568 1579 */ 1569 1580 if (timed_out && !cfq_cfqq_slice_new(cfqq)) { ··· 1669 1662 else 1670 1663 return cfqd->last_position - blk_rq_pos(rq); 1671 1664 } 1672 - 1673 - #define CFQQ_SEEK_THR 8 * 1024 1674 - #define CFQQ_SEEKY(cfqq) ((cfqq)->seek_mean > CFQQ_SEEK_THR) 1675 1665 1676 1666 static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq, 1677 1667 struct request *rq, bool for_preempt) ··· 3004 3000 total = cfqq->seek_total + (cfqq->seek_samples/2); 3005 3001 do_div(total, cfqq->seek_samples); 3006 3002 cfqq->seek_mean = (sector_t)total; 3007 - 3008 - /* 3009 - * If this cfqq is shared between multiple processes, check to 3010 - * make sure that those processes are still issuing I/Os within 3011 - * the mean seek distance. If not, it may be time to break the 3012 - * queues apart again. 3013 - */ 3014 - if (cfq_cfqq_coop(cfqq)) { 3015 - if (CFQQ_SEEKY(cfqq) && !cfqq->seeky_start) 3016 - cfqq->seeky_start = jiffies; 3017 - else if (!CFQQ_SEEKY(cfqq)) 3018 - cfqq->seeky_start = 0; 3019 - } 3020 3003 } 3021 3004 3022 3005 /* ··· 3444 3453 return cic_to_cfqq(cic, 1); 3445 3454 } 3446 3455 3447 - static int should_split_cfqq(struct cfq_queue *cfqq) 3448 - { 3449 - if (cfqq->seeky_start && 3450 - time_after(jiffies, cfqq->seeky_start + CFQQ_COOP_TOUT)) 3451 - return 1; 3452 - return 0; 3453 - } 3454 - 3455 3456 /* 3456 3457 * Returns NULL if a new cfqq should be allocated, or the old cfqq if this 3457 3458 * was the last process referring to said cfqq. ··· 3452 3469 split_cfqq(struct cfq_io_context *cic, struct cfq_queue *cfqq) 3453 3470 { 3454 3471 if (cfqq_process_refs(cfqq) == 1) { 3455 - cfqq->seeky_start = 0; 3456 3472 cfqq->pid = current->pid; 3457 3473 cfq_clear_cfqq_coop(cfqq); 3474 + cfq_clear_cfqq_split_coop(cfqq); 3458 3475 return cfqq; 3459 3476 } 3460 3477 ··· 3493 3510 /* 3494 3511 * If the queue was seeky for too long, break it apart. 3495 3512 */ 3496 - if (cfq_cfqq_coop(cfqq) && should_split_cfqq(cfqq)) { 3513 + if (cfq_cfqq_coop(cfqq) && cfq_cfqq_split_coop(cfqq)) { 3497 3514 cfq_log_cfqq(cfqd, cfqq, "breaking apart cfqq"); 3498 3515 cfqq = split_cfqq(cic, cfqq); 3499 3516 if (!cfqq)