| @@ -31,11 +31,6 @@ · 30 unmodified lines |
| 31 | */ | 31 | */ |
| 32 | static const int read_expire = HZ / 2; /* max time before a read is submitted. */ | 32 | static const int read_expire = HZ / 2; /* max time before a read is submitted. */ |
| 33 | static const int write_expire = 5 * HZ; /* ditto for writes, these limits are SOFT! */ | 33 | static const int write_expire = 5 * HZ; /* ditto for writes, these limits are SOFT! */ |
| 34 | /* | | |
| 35 | * Time after which to dispatch lower priority requests even if higher | | |
| 36 | * priority requests are pending. | | |
| 37 | */ | | |
| 38 | static const int aging_expire = 10 * HZ; | | |
| 39 | static const int writes_starved = 2; /* max times reads can starve a write */ | 34 | static const int writes_starved = 2; /* max times reads can starve a write */ |
| 40 | static const int fifo_batch = 16; /* # of sequential requests treated as one | 35 | static const int fifo_batch = 16; /* # of sequential requests treated as one |
| 41 | by the above parameters. For throughput. */ | 36 | by the above parameters. For throughput. */ |
| @@ -103,7 +98,6 @@ struct deadline_data { · 61 unmodified lines |
| 103 | int writes_starved; | 98 | int writes_starved; |
| 104 | int front_merges; | 99 | int front_merges; |
| 105 | u32 async_depth; | 100 | u32 async_depth; |
| 106 | int aging_expire; | | |
| 107 | | 101 | |
| 108 | spinlock_t lock; | 102 | spinlock_t lock; |
| 109 | spinlock_t zone_lock; | 103 | spinlock_t zone_lock; |
| @@ -369,11 +363,10 @@ deadline_next_request(struct deadline_data *dd, struct dd_per_prio *per_prio, · 259 unmodified lines |
| 369 | | 363 | |
| 370 | /* | 364 | /* |
| 371 | * deadline_dispatch_requests selects the best request according to | 365 | * deadline_dispatch_requests selects the best request according to |
| 372 | * read/write expire, fifo_batch, etc and with a start time <= @latest. | 366 | * read/write expire, fifo_batch, etc |
| 373 | */ | 367 | */ |
| 374 | static struct request *__dd_dispatch_request(struct deadline_data *dd, | 368 | static struct request *__dd_dispatch_request(struct deadline_data *dd, |
| 375 | struct dd_per_prio *per_prio, | 369 | struct dd_per_prio *per_prio) |
| 376 | u64 latest_start_ns) | | |
| 377 | { | 370 | { |
| 378 | struct request *rq, *next_rq; | 371 | struct request *rq, *next_rq; |
| 379 | enum dd_data_dir data_dir; | 372 | enum dd_data_dir data_dir; |
| @@ -385,8 +378,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, · 5 unmodified lines |
| 385 | if (!list_empty(&per_prio->dispatch)) { | 378 | if (!list_empty(&per_prio->dispatch)) { |
| 386 | rq = list_first_entry(&per_prio->dispatch, struct request, | 379 | rq = list_first_entry(&per_prio->dispatch, struct request, |
| 387 | queuelist); | 380 | queuelist); |
| 388 | if (rq->start_time_ns > latest_start_ns) | | |
| 389 | return NULL; | | |
| 390 | list_del_init(&rq->queuelist); | 381 | list_del_init(&rq->queuelist); |
| 391 | goto done; | 382 | goto done; |
| 392 | } | 383 | } |
| @@ -464,8 +455,6 @@ dispatch_find_request: · 71 unmodified lines |
| 464 | dd->batching = 0; | 455 | dd->batching = 0; |
| 465 | | 456 | |
| 466 | dispatch_request: | 457 | dispatch_request: |
| 467 | if (rq->start_time_ns > latest_start_ns) | | |
| 468 | return NULL; | | |
| 469 | /* | 458 | /* |
| 470 | * rq is the selected appropriate request. | 459 | * rq is the selected appropriate request. |
| 471 | */ | 460 | */ |
| @@ -494,32 +483,15 @@ done: · 22 unmodified lines |
| 494 | static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx) | 483 | static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx) |
| 495 | { | 484 | { |
| 496 | struct deadline_data *dd = hctx->queue->elevator->elevator_data; | 485 | struct deadline_data *dd = hctx->queue->elevator->elevator_data; |
| 497 | const u64 now_ns = ktime_get_ns(); | 486 | struct request *rq; |
| 498 | struct request *rq = NULL; | | |
| 499 | enum dd_prio prio; | 487 | enum dd_prio prio; |
| 500 | | 488 | |
| 501 | spin_lock(&dd->lock); | 489 | spin_lock(&dd->lock); |
| 502 | /* | | |
| 503 | * Start with dispatching requests whose deadline expired more than | | |
| 504 | * aging_expire jiffies ago. | | |
| 505 | */ | | |
| 506 | for (prio = DD_BE_PRIO; prio <= DD_PRIO_MAX; prio++) { | | |
| 507 | rq = __dd_dispatch_request(dd, &dd->per_prio[prio], now_ns - | | |
| 508 | jiffies_to_nsecs(dd->aging_expire)); | | |
| 509 | if (rq) | | |
| 510 | goto unlock; | | |
| 511 | } | | |
| 512 | /* | | |
| 513 | * Next, dispatch requests in priority order. Ignore lower priority | | |
| 514 | * requests if any higher priority requests are pending. | | |
| 515 | */ | | |
| 516 | for (prio = 0; prio <= DD_PRIO_MAX; prio++) { | 490 | for (prio = 0; prio <= DD_PRIO_MAX; prio++) { |
| 517 | rq = __dd_dispatch_request(dd, &dd->per_prio[prio], now_ns); | 491 | rq = __dd_dispatch_request(dd, &dd->per_prio[prio]); |
| 518 | if (rq || dd_queued(dd, prio)) | 492 | if (rq) |
| 519 | break; | 493 | break; |
| 520 | } | 494 | } |
| 521 | | | |
| 522 | unlock: | | |
| 523 | spin_unlock(&dd->lock); | 495 | spin_unlock(&dd->lock); |
| 524 | | 496 | |
| 525 | return rq; | 497 | return rq; |
| @@ -620,7 +592,6 @@ static int dd_init_sched(struct request_queue *q, struct elevator_type *e) · 94 unmodified lines |
| 620 | dd->front_merges = 1; | 592 | dd->front_merges = 1; |
| 621 | dd->last_dir = DD_WRITE; | 593 | dd->last_dir = DD_WRITE; |
| 622 | dd->fifo_batch = fifo_batch; | 594 | dd->fifo_batch = fifo_batch; |
| 623 | dd->aging_expire = aging_expire; | | |
| 624 | spin_lock_init(&dd->lock); | 595 | spin_lock_init(&dd->lock); |
| 625 | spin_lock_init(&dd->zone_lock); | 596 | spin_lock_init(&dd->zone_lock); |
| 626 | | 597 | |
| @@ -711,6 +682,7 @@ static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, · 84 unmodified lines |
| 711 | | 682 | |
| 712 | prio = ioprio_class_to_prio[ioprio_class]; | 683 | prio = ioprio_class_to_prio[ioprio_class]; |
| 713 | dd_count(dd, inserted, prio); | 684 | dd_count(dd, inserted, prio); |
| | 685 | rq->elv.priv[0] = (void *)(uintptr_t)1; |
| 714 | | 686 | |
| 715 | if (blk_mq_sched_try_insert_merge(q, rq, &free)) { | 687 | if (blk_mq_sched_try_insert_merge(q, rq, &free)) { |
| 716 | blk_mq_free_requests(&free); | 688 | blk_mq_free_requests(&free); |
| @@ -759,12 +731,10 @@ static void dd_insert_requests(struct blk_mq_hw_ctx *hctx, · 42 unmodified lines |
| 759 | spin_unlock(&dd->lock); | 731 | spin_unlock(&dd->lock); |
| 760 | } | 732 | } |
| 761 | | 733 | |
| 762 | /* | 734 | /* Callback from inside blk_mq_rq_ctx_init(). */ |
| 763 | * Nothing to do here. This is defined only to ensure that .finish_request | | |
| 764 | * method is called upon request completion. | | |
| 765 | */ | | |
| 766 | static void dd_prepare_request(struct request *rq) | 735 | static void dd_prepare_request(struct request *rq) |
| 767 | { | 736 | { |
| | 737 | rq->elv.priv[0] = NULL; |
| 768 | } | 738 | } |
| 769 | | 739 | |
| 770 | /* | 740 | /* |
| @@ -791,7 +761,14 @@ static void dd_finish_request(struct request *rq) · 20 unmodified lines |
| 791 | const enum dd_prio prio = ioprio_class_to_prio[ioprio_class]; | 761 | const enum dd_prio prio = ioprio_class_to_prio[ioprio_class]; |
| 792 | struct dd_per_prio *per_prio = &dd->per_prio[prio]; | 762 | struct dd_per_prio *per_prio = &dd->per_prio[prio]; |
| 793 | | 763 | |
| 794 | dd_count(dd, completed, prio); | 764 | /* |
| | 765 | * The block layer core may call dd_finish_request() without having |
| | 766 | * called dd_insert_requests(). Hence only update statistics for |
| | 767 | * requests for which dd_insert_requests() has been called. See also |
| | 768 | * blk_mq_request_bypass_insert(). |
| | 769 | */ |
| | 770 | if (rq->elv.priv[0]) |
| | 771 | dd_count(dd, completed, prio); |
| 795 | | 772 | |
| 796 | if (blk_queue_is_zoned(q)) { | 773 | if (blk_queue_is_zoned(q)) { |
| 797 | unsigned long flags; | 774 | unsigned long flags; |
| @@ -836,7 +813,6 @@ static ssize_t __FUNC(struct elevator_queue *e, char *page) \ · 38 unmodified lines |
| 836 | #define SHOW_JIFFIES(__FUNC, __VAR) SHOW_INT(__FUNC, jiffies_to_msecs(__VAR)) | 813 | #define SHOW_JIFFIES(__FUNC, __VAR) SHOW_INT(__FUNC, jiffies_to_msecs(__VAR)) |
| 837 | SHOW_JIFFIES(deadline_read_expire_show, dd->fifo_expire[DD_READ]); | 814 | SHOW_JIFFIES(deadline_read_expire_show, dd->fifo_expire[DD_READ]); |
| 838 | SHOW_JIFFIES(deadline_write_expire_show, dd->fifo_expire[DD_WRITE]); | 815 | SHOW_JIFFIES(deadline_write_expire_show, dd->fifo_expire[DD_WRITE]); |
| 839 | SHOW_JIFFIES(deadline_aging_expire_show, dd->aging_expire); | | |
| 840 | SHOW_INT(deadline_writes_starved_show, dd->writes_starved); | 816 | SHOW_INT(deadline_writes_starved_show, dd->writes_starved); |
| 841 | SHOW_INT(deadline_front_merges_show, dd->front_merges); | 817 | SHOW_INT(deadline_front_merges_show, dd->front_merges); |
| 842 | SHOW_INT(deadline_async_depth_show, dd->front_merges); | 818 | SHOW_INT(deadline_async_depth_show, dd->front_merges); |
| @@ -866,7 +842,6 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count) · 23 unmodified lines |
| 866 | STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, msecs_to_jiffies) | 842 | STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, msecs_to_jiffies) |
| 867 | STORE_JIFFIES(deadline_read_expire_store, &dd->fifo_expire[DD_READ], 0, INT_MAX); | 843 | STORE_JIFFIES(deadline_read_expire_store, &dd->fifo_expire[DD_READ], 0, INT_MAX); |
| 868 | STORE_JIFFIES(deadline_write_expire_store, &dd->fifo_expire[DD_WRITE], 0, INT_MAX); | 844 | STORE_JIFFIES(deadline_write_expire_store, &dd->fifo_expire[DD_WRITE], 0, INT_MAX); |
| 869 | STORE_JIFFIES(deadline_aging_expire_store, &dd->aging_expire, 0, INT_MAX); | | |
| 870 | STORE_INT(deadline_writes_starved_store, &dd->writes_starved, INT_MIN, INT_MAX); | 845 | STORE_INT(deadline_writes_starved_store, &dd->writes_starved, INT_MIN, INT_MAX); |
| 871 | STORE_INT(deadline_front_merges_store, &dd->front_merges, 0, 1); | 846 | STORE_INT(deadline_front_merges_store, &dd->front_merges, 0, 1); |
| 872 | STORE_INT(deadline_async_depth_store, &dd->front_merges, 1, INT_MAX); | 847 | STORE_INT(deadline_async_depth_store, &dd->front_merges, 1, INT_MAX); |
| @@ -885,7 +860,6 @@ static struct elv_fs_entry deadline_attrs[] = { · 12 unmodified lines |
| 885 | DD_ATTR(front_merges), | 860 | DD_ATTR(front_merges), |
| 886 | DD_ATTR(async_depth), | 861 | DD_ATTR(async_depth), |
| 887 | DD_ATTR(fifo_batch), | 862 | DD_ATTR(fifo_batch), |
| 888 | DD_ATTR(aging_expire), | | |
| 889 | __ATTR_NULL | 863 | __ATTR_NULL |
| 890 | }; | 864 | }; |
| 891 | | 865 | |