Commit 9d357b0787bb3c91835d5e658c3bda178f9ca419

Authored by NeilBrown
Committed by Alasdair G Kergon
1 parent 4e2d19e46b

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.