]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Kiyoshi Ueda <k-ueda@ct.jp.nec.com> |
2 | Subject: dm-mpath: interface change for service-time dynamic load balancer | |
3 | References: FATE#303862,FATE#302108 | |
4 | ||
5 | This patch changes path selector interfaces for service-time oriented | |
6 | dynamic load balancer. | |
7 | ||
8 | To calculate the service time for an incoming I/O correctly, | |
9 | the load balancer needs the size of the incoming I/O when selecting | |
10 | the next path. | |
11 | ||
12 | ||
13 | Signed-off-by: Kiyoshi Ueda <k-ueda@ct.jp.nec.com> | |
14 | Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com> | |
15 | Signed-off-by: Hannes Reinecke <hare@suse.de> | |
16 | ||
17 | --- | |
18 | drivers/md/dm-least-pending.c | 4 ++-- | |
19 | drivers/md/dm-mpath.c | 27 ++++++++++++++++----------- | |
20 | drivers/md/dm-path-selector.h | 9 ++++++--- | |
21 | drivers/md/dm-queue-length.c | 8 +++++--- | |
22 | drivers/md/dm-round-robin.c | 2 +- | |
23 | 5 files changed, 30 insertions(+), 20 deletions(-) | |
24 | ||
25 | --- a/drivers/md/dm-least-pending.c | |
26 | +++ b/drivers/md/dm-least-pending.c | |
27 | @@ -172,7 +172,7 @@ static int lpp_reinstate_path(struct pat | |
28 | } | |
29 | ||
30 | static struct dm_path *lpp_select_path(struct path_selector *ps, | |
31 | - unsigned *repeat_count) | |
32 | + unsigned *repeat_count, size_t nr_bytes) | |
33 | { | |
34 | struct selector *s = ps->context; | |
35 | struct path_info *pi, *next, *least_io_path = NULL; | |
36 | @@ -199,7 +199,7 @@ static struct dm_path *lpp_select_path(s | |
37 | return least_io_path->path; | |
38 | } | |
39 | ||
40 | -static int lpp_end_io(struct path_selector *ps, struct dm_path *path) | |
41 | +static int lpp_end_io(struct path_selector *ps, struct dm_path *path, size_t nr_bytes) | |
42 | { | |
43 | struct path_info *pi = NULL; | |
44 | ||
45 | --- a/drivers/md/dm-mpath.c | |
46 | +++ b/drivers/md/dm-mpath.c | |
47 | @@ -99,6 +99,7 @@ struct multipath { | |
48 | */ | |
49 | struct dm_mpath_io { | |
50 | struct pgpath *pgpath; | |
51 | + size_t nr_bytes; | |
52 | }; | |
53 | ||
54 | typedef int (*action_fn) (struct pgpath *pgpath); | |
55 | @@ -246,11 +247,12 @@ static void __switch_pg(struct multipath | |
56 | m->pg_init_count = 0; | |
57 | } | |
58 | ||
59 | -static int __choose_path_in_pg(struct multipath *m, struct priority_group *pg) | |
60 | +static int __choose_path_in_pg(struct multipath *m, struct priority_group *pg, | |
61 | + size_t nr_bytes) | |
62 | { | |
63 | struct dm_path *path; | |
64 | ||
65 | - path = pg->ps.type->select_path(&pg->ps, &m->repeat_count); | |
66 | + path = pg->ps.type->select_path(&pg->ps, &m->repeat_count, nr_bytes); | |
67 | if (!path) | |
68 | return -ENXIO; | |
69 | ||
70 | @@ -262,7 +264,7 @@ static int __choose_path_in_pg(struct mu | |
71 | return 0; | |
72 | } | |
73 | ||
74 | -static void __choose_pgpath(struct multipath *m) | |
75 | +static void __choose_pgpath(struct multipath *m, size_t nr_bytes) | |
76 | { | |
77 | struct priority_group *pg; | |
78 | unsigned bypassed = 1; | |
79 | @@ -274,12 +276,12 @@ static void __choose_pgpath(struct multi | |
80 | if (m->next_pg) { | |
81 | pg = m->next_pg; | |
82 | m->next_pg = NULL; | |
83 | - if (!__choose_path_in_pg(m, pg)) | |
84 | + if (!__choose_path_in_pg(m, pg, nr_bytes)) | |
85 | return; | |
86 | } | |
87 | ||
88 | /* Don't change PG until it has no remaining paths */ | |
89 | - if (m->current_pg && !__choose_path_in_pg(m, m->current_pg)) | |
90 | + if (m->current_pg && !__choose_path_in_pg(m, m->current_pg, nr_bytes)) | |
91 | return; | |
92 | ||
93 | /* | |
94 | @@ -291,7 +293,7 @@ static void __choose_pgpath(struct multi | |
95 | list_for_each_entry(pg, &m->priority_groups, list) { | |
96 | if (pg->bypassed == bypassed) | |
97 | continue; | |
98 | - if (!__choose_path_in_pg(m, pg)) | |
99 | + if (!__choose_path_in_pg(m, pg, nr_bytes)) | |
100 | return; | |
101 | } | |
102 | } while (bypassed--); | |
103 | @@ -322,6 +324,7 @@ static int map_io(struct multipath *m, s | |
104 | struct dm_mpath_io *mpio, unsigned was_queued) | |
105 | { | |
106 | int r = DM_MAPIO_REMAPPED; | |
107 | + size_t nr_bytes = blk_rq_bytes(clone); | |
108 | unsigned long flags; | |
109 | struct pgpath *pgpath; | |
110 | struct block_device *bdev; | |
111 | @@ -331,7 +334,7 @@ static int map_io(struct multipath *m, s | |
112 | /* Do we need to select a new pgpath? */ | |
113 | if (!m->current_pgpath || | |
114 | (!m->queue_io && (m->repeat_count && --m->repeat_count == 0))) | |
115 | - __choose_pgpath(m); | |
116 | + __choose_pgpath(m, nr_bytes); | |
117 | ||
118 | pgpath = m->current_pgpath; | |
119 | ||
120 | @@ -358,9 +361,11 @@ static int map_io(struct multipath *m, s | |
121 | r = -EIO; /* Failed */ | |
122 | ||
123 | mpio->pgpath = pgpath; | |
124 | + mpio->nr_bytes = nr_bytes; | |
125 | ||
126 | if (r == DM_MAPIO_REMAPPED && pgpath->pg->ps.type->start_io) | |
127 | - pgpath->pg->ps.type->start_io(&pgpath->pg->ps, &pgpath->path); | |
128 | + pgpath->pg->ps.type->start_io(&pgpath->pg->ps, &pgpath->path, | |
129 | + nr_bytes); | |
130 | ||
131 | spin_unlock_irqrestore(&m->lock, flags); | |
132 | ||
133 | @@ -440,7 +445,7 @@ static void process_queued_ios(struct wo | |
134 | goto out; | |
135 | ||
136 | if (!m->current_pgpath) | |
137 | - __choose_pgpath(m); | |
138 | + __choose_pgpath(m, 1 << 19); /* Assume 512 KB */ | |
139 | ||
140 | pgpath = m->current_pgpath; | |
141 | ||
142 | @@ -1193,7 +1198,7 @@ static int multipath_end_io(struct dm_ta | |
143 | if (pgpath) { | |
144 | ps = &pgpath->pg->ps; | |
145 | if (ps->type->end_io) | |
146 | - ps->type->end_io(ps, &pgpath->path); | |
147 | + ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes); | |
148 | } | |
149 | mempool_free(mpio, m->mpio_pool); | |
150 | ||
151 | @@ -1412,7 +1417,7 @@ static int multipath_ioctl(struct dm_tar | |
152 | spin_lock_irqsave(&m->lock, flags); | |
153 | ||
154 | if (!m->current_pgpath) | |
155 | - __choose_pgpath(m); | |
156 | + __choose_pgpath(m, 1 << 19); /* Assume 512KB */ | |
157 | ||
158 | if (m->current_pgpath) { | |
159 | bdev = m->current_pgpath->path.dev->bdev; | |
160 | --- a/drivers/md/dm-path-selector.h | |
161 | +++ b/drivers/md/dm-path-selector.h | |
162 | @@ -56,7 +56,8 @@ struct path_selector_type { | |
163 | * the path fails. | |
164 | */ | |
165 | struct dm_path *(*select_path) (struct path_selector *ps, | |
166 | - unsigned *repeat_count); | |
167 | + unsigned *repeat_count, | |
168 | + size_t nr_bytes); | |
169 | ||
170 | /* | |
171 | * Notify the selector that a path has failed. | |
172 | @@ -75,8 +76,10 @@ struct path_selector_type { | |
173 | int (*status) (struct path_selector *ps, struct dm_path *path, | |
174 | status_type_t type, char *result, unsigned int maxlen); | |
175 | ||
176 | - int (*start_io) (struct path_selector *ps, struct dm_path *path); | |
177 | - int (*end_io) (struct path_selector *ps, struct dm_path *path); | |
178 | + int (*start_io) (struct path_selector *ps, struct dm_path *path, | |
179 | + size_t nr_bytes); | |
180 | + int (*end_io) (struct path_selector *ps, struct dm_path *path, | |
181 | + size_t nr_bytes); | |
182 | }; | |
183 | ||
184 | /* Register a path selector */ | |
185 | --- a/drivers/md/dm-queue-length.c | |
186 | +++ b/drivers/md/dm-queue-length.c | |
187 | @@ -142,7 +142,7 @@ static inline int ql_compare_qlen(struct | |
188 | } | |
189 | ||
190 | static struct dm_path *ql_select_path(struct path_selector *ps, | |
191 | - unsigned *repeat_count) | |
192 | + unsigned *repeat_count, size_t nr_bytes) | |
193 | { | |
194 | struct selector *s = (struct selector *) ps->context; | |
195 | struct path_info *cpi = NULL, *spi = NULL; | |
196 | @@ -166,7 +166,8 @@ static struct dm_path *ql_select_path(st | |
197 | return spi ? spi->path : NULL; | |
198 | } | |
199 | ||
200 | -static int ql_start_io(struct path_selector *ps, struct dm_path *path) | |
201 | +static int ql_start_io(struct path_selector *ps, struct dm_path *path, | |
202 | + size_t nr_bytes) | |
203 | { | |
204 | struct path_info *pi = path->pscontext; | |
205 | ||
206 | @@ -175,7 +176,8 @@ static int ql_start_io(struct path_selec | |
207 | return 0; | |
208 | } | |
209 | ||
210 | -static int ql_end_io(struct path_selector *ps, struct dm_path *path) | |
211 | +static int ql_end_io(struct path_selector *ps, struct dm_path *path, | |
212 | + size_t nr_bytes) | |
213 | { | |
214 | struct path_info *pi = path->pscontext; | |
215 | ||
216 | --- a/drivers/md/dm-round-robin.c | |
217 | +++ b/drivers/md/dm-round-robin.c | |
218 | @@ -160,7 +160,7 @@ static int rr_reinstate_path(struct path | |
219 | } | |
220 | ||
221 | static struct dm_path *rr_select_path(struct path_selector *ps, | |
222 | - unsigned *repeat_count) | |
223 | + unsigned *repeat_count, size_t nr_bytes) | |
224 | { | |
225 | struct selector *s = (struct selector *) ps->context; | |
226 | struct path_info *pi = NULL; |