Commit 9d357b0787bb3c91835d5e658c3bda178f9ca419
Committed by
Alasdair G Kergon
1 parent
4e2d19e46b
Exists in
master
and in
7 other branches
dm: introduce target callbacks and congestion callback
DM currently implements congestion checking by checking on congestion in each component device. For raid456 we need to also check if the stripe cache is congested. Add per-target congestion checker callback support. Extending the target_callbacks structure with additional callback functions allows for establishing multiple callbacks per-target (a callback is also needed for unplug). Cc: linux-raid@vger.kernel.org Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Jonathan Brassow <jbrassow@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Showing 2 changed files with 25 additions and 0 deletions Side-by-side Diff
drivers/md/dm-table.c
... | ... | @@ -71,6 +71,8 @@ |
71 | 71 | void *event_context; |
72 | 72 | |
73 | 73 | struct dm_md_mempools *mempools; |
74 | + | |
75 | + struct list_head target_callbacks; | |
74 | 76 | }; |
75 | 77 | |
76 | 78 | /* |
... | ... | @@ -204,6 +206,7 @@ |
204 | 206 | return -ENOMEM; |
205 | 207 | |
206 | 208 | INIT_LIST_HEAD(&t->devices); |
209 | + INIT_LIST_HEAD(&t->target_callbacks); | |
207 | 210 | atomic_set(&t->holders, 0); |
208 | 211 | t->discards_supported = 1; |
209 | 212 | |
210 | 213 | |
... | ... | @@ -1225,10 +1228,17 @@ |
1225 | 1228 | return 0; |
1226 | 1229 | } |
1227 | 1230 | |
1231 | +void dm_table_add_target_callbacks(struct dm_table *t, struct dm_target_callbacks *cb) | |
1232 | +{ | |
1233 | + list_add(&cb->list, &t->target_callbacks); | |
1234 | +} | |
1235 | +EXPORT_SYMBOL_GPL(dm_table_add_target_callbacks); | |
1236 | + | |
1228 | 1237 | int dm_table_any_congested(struct dm_table *t, int bdi_bits) |
1229 | 1238 | { |
1230 | 1239 | struct dm_dev_internal *dd; |
1231 | 1240 | struct list_head *devices = dm_table_get_devices(t); |
1241 | + struct dm_target_callbacks *cb; | |
1232 | 1242 | int r = 0; |
1233 | 1243 | |
1234 | 1244 | list_for_each_entry(dd, devices, list) { |
... | ... | @@ -1242,6 +1252,10 @@ |
1242 | 1252 | dm_device_name(t->md), |
1243 | 1253 | bdevname(dd->dm_dev.bdev, b)); |
1244 | 1254 | } |
1255 | + | |
1256 | + list_for_each_entry(cb, &t->target_callbacks, list) | |
1257 | + if (cb->congested_fn) | |
1258 | + r |= cb->congested_fn(cb, bdi_bits); | |
1245 | 1259 | |
1246 | 1260 | return r; |
1247 | 1261 | } |
include/linux/device-mapper.h
... | ... | @@ -193,6 +193,12 @@ |
193 | 193 | char *error; |
194 | 194 | }; |
195 | 195 | |
196 | +/* Each target can link one of these into the table */ | |
197 | +struct dm_target_callbacks { | |
198 | + struct list_head list; | |
199 | + int (*congested_fn) (struct dm_target_callbacks *, int); | |
200 | +}; | |
201 | + | |
196 | 202 | int dm_register_target(struct target_type *t); |
197 | 203 | void dm_unregister_target(struct target_type *t); |
198 | 204 | |
... | ... | @@ -267,6 +273,11 @@ |
267 | 273 | */ |
268 | 274 | int dm_table_add_target(struct dm_table *t, const char *type, |
269 | 275 | sector_t start, sector_t len, char *params); |
276 | + | |
277 | +/* | |
278 | + * Target_ctr should call this if it needs to add any callbacks. | |
279 | + */ | |
280 | +void dm_table_add_target_callbacks(struct dm_table *t, struct dm_target_callbacks *cb); | |
270 | 281 | |
271 | 282 | /* |
272 | 283 | * Finally call this to make the table ready for use. |