| 1 | /* |
| 2 | #include <block/sched.h> |
| 3 | #include <mem/alloc.h> |
| 4 | #include <math/sort.h> |
| 5 | |
| 6 | #define MAX_REORDER_SCAN 8 |
| 7 | #define REORDER_THRESHOLD 32 |
| 8 | #define abs(N) ((N < 0) ? (-N) : (N)) |
| 9 | |
| 10 | static uint64_t previous_reorder_request_nums[5] = {0}; |
| 11 | static uint64_t last_lba_processed[5] = {0}; |
| 12 | |
| 13 | #define abs64(N) ((N) < 0 ? -(N) : (N)) |
| 14 | |
| 15 | static void partial_reorder(struct bio_rqueue *q, uint64_t last_lba) { |
| 16 | if (!q->head || q->head == q->tail) |
| 17 | return; |
| 18 | |
| 19 | struct bio_request *best = q->head; |
| 20 | struct bio_request *best_prev = NULL; |
| 21 | uint64_t best_distance = UINT64_MAX; |
| 22 | |
| 23 | struct bio_request *prev = NULL; |
| 24 | struct bio_request *cur = q->head; |
| 25 | |
| 26 | int scanned = 0; |
| 27 | while (cur && scanned < MAX_REORDER_SCAN) { |
| 28 | uint64_t distance = abs64((int64_t) (cur->lba - last_lba)); |
| 29 | if (distance < best_distance) { |
| 30 | best_distance = distance; |
| 31 | best = cur; |
| 32 | best_prev = prev; |
| 33 | } |
| 34 | prev = cur; |
| 35 | cur = cur->next; |
| 36 | scanned++; |
| 37 | } |
| 38 | |
| 39 | if (best != q->head) { |
| 40 | if (best_prev) |
| 41 | best_prev->next = best->next; |
| 42 | if (best == q->tail) |
| 43 | q->tail = best_prev; |
| 44 | |
| 45 | best->next = q->head; |
| 46 | q->head = best; |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | void ide_reorder(struct generic_disk *disk) { |
| 51 | struct bio_scheduler *sched = disk->scheduler; |
| 52 | |
| 53 | for (int level = 0; level <= BIO_SCHED_MAX; level++) { |
| 54 | struct bio_rqueue *q = &sched->queues[level]; |
| 55 | if (!q->dirty || !q->head || q->head == q->tail) |
| 56 | continue; |
| 57 | |
| 58 | int count = q->request_count; |
| 59 | int prev_count = previous_reorder_request_nums[level]; |
| 60 | |
| 61 | if (abs(count - prev_count) < REORDER_THRESHOLD) |
| 62 | continue; |
| 63 | |
| 64 | previous_reorder_request_nums[level] = count; |
| 65 | |
| 66 | partial_reorder(q, last_lba_processed[level]); |
| 67 | |
| 68 | if (q->head) |
| 69 | last_lba_processed[level] = q->head->lba; |
| 70 | |
| 71 | q->dirty = false; |
| 72 | } |
| 73 | }*/ |
| 74 | |