|
34 | 34 | #include "super.h" |
35 | 35 | #include "raid-stripe-tree.h" |
36 | 36 |
|
| 37 | +#ifdef CONFIG_BTRFS_READ_POLICIES |
| 38 | +#include <linux/part_stat.h> |
| 39 | +#endif |
| 40 | + |
37 | 41 | #define BTRFS_BLOCK_GROUP_STRIPE_MASK (BTRFS_BLOCK_GROUP_RAID0 | \ |
38 | 42 | BTRFS_BLOCK_GROUP_RAID10 | \ |
39 | 43 | BTRFS_BLOCK_GROUP_RAID56_MASK) |
@@ -6051,6 +6055,44 @@ unsigned long btrfs_full_stripe_len(struct btrfs_fs_info *fs_info, |
6051 | 6055 | } |
6052 | 6056 |
|
6053 | 6057 | #ifdef CONFIG_BTRFS_READ_POLICIES |
| 6058 | +static unsigned int part_in_flight(struct block_device *part) |
| 6059 | +{ |
| 6060 | + unsigned int inflight = 0; |
| 6061 | + int cpu; |
| 6062 | + |
| 6063 | + for_each_possible_cpu(cpu) { |
| 6064 | + inflight += part_stat_local_read_cpu(part, in_flight[READ], cpu) + |
| 6065 | + part_stat_local_read_cpu(part, in_flight[WRITE], cpu); |
| 6066 | + } |
| 6067 | + if ((int)inflight < 0) |
| 6068 | + inflight = 0; |
| 6069 | + |
| 6070 | + return inflight; |
| 6071 | +} |
| 6072 | + |
| 6073 | +/* |
| 6074 | + * btrfs_earliest_stripe |
| 6075 | + * |
| 6076 | + * Select a stripe from the device with shortest in-flight requests. |
| 6077 | + */ |
| 6078 | +static int btrfs_read_earliest(struct btrfs_fs_info *fs_info, |
| 6079 | + struct btrfs_chunk_map *map, int first, |
| 6080 | + int num_stripes) |
| 6081 | +{ |
| 6082 | + u64 best_in_flight = U64_MAX; |
| 6083 | + int best_stripe = 0; |
| 6084 | + |
| 6085 | + for (int index = first; index < first + num_stripes; index++) { |
| 6086 | + u64 in_flight = part_in_flight(map->stripes[index].dev->bdev); |
| 6087 | + if (best_in_flight > in_flight) { |
| 6088 | + best_in_flight = in_flight; |
| 6089 | + best_stripe = index; |
| 6090 | + } |
| 6091 | + } |
| 6092 | + |
| 6093 | + return best_stripe; |
| 6094 | +} |
| 6095 | + |
6054 | 6096 | static int btrfs_read_preferred(struct btrfs_chunk_map *map, int first, int num_stripes) |
6055 | 6097 | { |
6056 | 6098 | for (int index = first; index < first + num_stripes; index++) { |
@@ -6162,6 +6204,10 @@ static int find_live_mirror(struct btrfs_fs_info *fs_info, |
6162 | 6204 | case BTRFS_READ_POLICY_RR: |
6163 | 6205 | preferred_mirror = btrfs_read_rr(map, first, num_stripes); |
6164 | 6206 | break; |
| 6207 | + case BTRFS_READ_POLICY_QUEUE: |
| 6208 | + preferred_mirror = btrfs_read_earliest(fs_info, map, first, |
| 6209 | + num_stripes); |
| 6210 | + break; |
6165 | 6211 | case BTRFS_READ_POLICY_DEVID: |
6166 | 6212 | preferred_mirror = btrfs_read_preferred(map, first, num_stripes); |
6167 | 6213 | break; |
|
0 commit comments