History

Merge tag 'dm-3.12-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device-mapper fixes from Mike Snitzer: "A few fixes for dm-snapshot, a 32 bit fix for dm-stats, a couple error handling fixes for dm-multipath. A fix for the thin provisioning target to not expose non-zero discard limits if discards are disabled. Lastly, add two DM module parameters which allow users to tune the emergency memory reserves that DM mainatins per device -- this helps fix a long-standing issue for dm-multipath. The conservative default reserve for request-based dm-multipath devices (256) has proven problematic for users with many multipathed SCSI devices but relatively little memory. To responsibly select a smaller value users should use the new nr_bios tracepoint info (via commit 75afb352 "block: Add nr_bios to block_rq_remap tracepoint") to determine the peak number of bios their workloads create" * tag 'dm-3.12-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm: add reserved_bio_based_ios module parameter dm: add reserved_rq_based_ios module parameter dm: lower bio-based mempool reservation dm thin: do not expose non-zero discard limits if discards disabled dm mpath: disable WRITE SAME if it fails dm-snapshot: fix performance degradation due to small hash size dm snapshot: workaround for a false positive lockdep warning dm stats: fix possible counter corruption on 32-bit systems dm mpath: do not fail path on -ENOSPC

Linus Torvalds committed 13 years ago

Commit e93dd912 parents b482041 e8603139 files · +120 −26Browse files

Unified · Split

9 files
  1. drivers/md/dm-io.c +3 −4
  2. drivers/md/dm-mpath.c +14 −4
  3. drivers/md/dm-snap-persistent.c +1 −1
  4. drivers/md/dm-snap.c +2 −3
  5. drivers/md/dm-stats.c +17 −6
  6. drivers/md/dm-thin.c +11 −3
  7. drivers/md/dm.c +67 −4
  8. drivers/md/dm.h +3 −0
  9. include/linux/device-mapper.h +2 −1
drivers/md/dm-io.c+3−4
@@ -19,8 +19,6 @@ · 18 unmodified lines
1919 #define DM_MSG_PREFIX "io"
2020
2121 #define DM_IO_MAX_REGIONS BITS_PER_LONG
22−#define MIN_IOS 16
23−#define MIN_BIOS 16
2422
2523 struct dm_io_client {
2624 mempool_t *pool;
@@ -50,16 +48,17 @@ static struct kmem_cache *_dm_io_cache; · 23 unmodified lines
5048 struct dm_io_client *dm_io_client_create(void)
5149 {
5250 struct dm_io_client *client;
51+ unsigned min_ios = dm_get_reserved_bio_based_ios();
5352
5453 client = kmalloc(sizeof(*client), GFP_KERNEL);
5554 if (!client)
5655 return ERR_PTR(-ENOMEM);
5756
58− client->pool = mempool_create_slab_pool(MIN_IOS, _dm_io_cache);
57+ client->pool = mempool_create_slab_pool(min_ios, _dm_io_cache);
5958 if (!client->pool)
6059 goto bad;
6160
62− client->bios = bioset_create(MIN_BIOS, 0);
61+ client->bios = bioset_create(min_ios, 0);
6362 if (!client->bios)
6463 goto bad;
6564
drivers/md/dm-mpath.c+14−4
@@ -7,6 +7,7 @@ · 6 unmodified lines
77
88 #include <linux/device-mapper.h>
99
10+#include "dm.h"
1011 #include "dm-path-selector.h"
1112 #include "dm-uevent.h"
1213
@@ -116,8 +117,6 @@ struct dm_mpath_io { · 103 unmodified lines
116117
117118 typedef int (*action_fn) (struct pgpath *pgpath);
118119
119−#define MIN_IOS 256 /* Mempool size */
120−
121120 static struct kmem_cache *_mpio_cache;
122121
123122 static struct workqueue_struct *kmultipathd, *kmpath_handlerd;
@@ -190,6 +189,7 @@ static void free_priority_group(struct priority_group *pg, · 66 unmodified lines
190189 static struct multipath *alloc_multipath(struct dm_target *ti)
191190 {
192191 struct multipath *m;
192+ unsigned min_ios = dm_get_reserved_rq_based_ios();
193193
194194 m = kzalloc(sizeof(*m), GFP_KERNEL);
195195 if (m) {
@@ -202,7 +202,7 @@ static struct multipath *alloc_multipath(struct dm_target *ti) · 6 unmodified lines
202202 INIT_WORK(&m->trigger_event, trigger_event);
203203 init_waitqueue_head(&m->pg_init_wait);
204204 mutex_init(&m->work_mutex);
205− m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache);
205+ m->mpio_pool = mempool_create_slab_pool(min_ios, _mpio_cache);
206206 if (!m->mpio_pool) {
207207 kfree(m);
208208 return NULL;
@@ -1268,6 +1268,7 @@ static int noretry_error(int error) · 1059 unmodified lines
12681268 case -EREMOTEIO:
12691269 case -EILSEQ:
12701270 case -ENODATA:
1271+ case -ENOSPC:
12711272 return 1;
12721273 }
12731274
@@ -1298,8 +1299,17 @@ static int do_end_io(struct multipath *m, struct request *clone, · 24 unmodified lines
12981299 if (!error && !clone->errors)
12991300 return 0; /* I/O complete */
13001301
1301− if (noretry_error(error))
1302+ if (noretry_error(error)) {
1303+ if ((clone->cmd_flags & REQ_WRITE_SAME) &&
1304+ !clone->q->limits.max_write_same_sectors) {
1305+ struct queue_limits *limits;
1306+
1307+ /* device doesn't really support WRITE SAME, disable it */
1308+ limits = dm_get_queue_limits(dm_table_get_md(m->ti->table));
1309+ limits->max_write_same_sectors = 0;
1310+ }
13021311 return error;
1312+ }
13031313
13041314 if (mpio->pgpath)
13051315 fail_path(mpio->pgpath);
drivers/md/dm-snap-persistent.c+1−1
@@ -256,7 +256,7 @@ static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw, · 255 unmodified lines
256256 */
257257 INIT_WORK_ONSTACK(&req.work, do_metadata);
258258 queue_work(ps->metadata_wq, &req.work);
259− flush_work(&req.work);
259+ flush_workqueue(ps->metadata_wq);
260260
261261 return req.result;
262262 }
drivers/md/dm-snap.c+2−3
@@ -725,17 +725,16 @@ static int calc_max_buckets(void) · 724 unmodified lines
725725 */
726726 static int init_hash_tables(struct dm_snapshot *s)
727727 {
728− sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets;
728+ sector_t hash_size, cow_dev_size, max_buckets;
729729
730730 /*
731731 * Calculate based on the size of the original volume or
732732 * the COW volume...
733733 */
734734 cow_dev_size = get_dev_size(s->cow->bdev);
735− origin_dev_size = get_dev_size(s->origin->bdev);
736735 max_buckets = calc_max_buckets();
737736
738− hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift;
737+ hash_size = cow_dev_size >> s->store->chunk_shift;
739738 hash_size = min(hash_size, max_buckets);
740739
741740 if (hash_size < 64)
drivers/md/dm-stats.c+17−6
@@ -451,19 +451,26 @@ static void dm_stat_for_entry(struct dm_stat *s, size_t entry, · 450 unmodified lines
451451 struct dm_stat_percpu *p;
452452
453453 /*
454− * For strict correctness we should use local_irq_disable/enable
454+ * For strict correctness we should use local_irq_save/restore
455455 * instead of preempt_disable/enable.
456456 *
457− * This is racy if the driver finishes bios from non-interrupt
458− * context as well as from interrupt context or from more different
459− * interrupts.
457+ * preempt_disable/enable is racy if the driver finishes bios
458+ * from non-interrupt context as well as from interrupt context
459+ * or from more different interrupts.
460460 *
461− * However, the race only results in not counting some events,
462− * so it is acceptable.
461+ * On 64-bit architectures the race only results in not counting some
462+ * events, so it is acceptable. On 32-bit architectures the race could
463+ * cause the counter going off by 2^32, so we need to do proper locking
464+ * there.
463465 *
464466 * part_stat_lock()/part_stat_unlock() have this race too.
465467 */
468+#if BITS_PER_LONG == 32
469+ unsigned long flags;
470+ local_irq_save(flags);
471+#else
466472 preempt_disable();
473+#endif
467474 p = &s->stat_percpu[smp_processor_id()][entry];
468475
469476 if (!end) {
@@ -478,7 +485,11 @@ static void dm_stat_for_entry(struct dm_stat *s, size_t entry, · 8 unmodified lines
478485 p->ticks[idx] += duration;
479486 }
480487
488+#if BITS_PER_LONG == 32
489+ local_irq_restore(flags);
490+#else
481491 preempt_enable();
492+#endif
482493 }
483494
484495 static void __dm_stat_bio(struct dm_stat *s, unsigned long bi_rw,
drivers/md/dm-thin.c+11−3
@@ -2095,6 +2095,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) · 2094 unmodified lines
20952095 * them down to the data device. The thin device's discard
20962096 * processing will cause mappings to be removed from the btree.
20972097 */
2098+ ti->discard_zeroes_data_unsupported = true;
20982099 if (pf.discard_enabled && pf.discard_passdown) {
20992100 ti->num_discard_bios = 1;
21002101
@@ -2104,7 +2105,6 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) · 3 unmodified lines
21042105 * thin devices' discard limits consistent).
21052106 */
21062107 ti->discards_supported = true;
2107− ti->discard_zeroes_data_unsupported = true;
21082108 }
21092109 ti->private = pt;
21102110
@@ -2689,8 +2689,16 @@ static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits) · 578 unmodified lines
26892689 * They get transferred to the live pool in bind_control_target()
26902690 * called from pool_preresume().
26912691 */
2692− if (!pt->adjusted_pf.discard_enabled)
2692+ if (!pt->adjusted_pf.discard_enabled) {
2693+ /*
2694+ * Must explicitly disallow stacking discard limits otherwise the
2695+ * block layer will stack them if pool's data device has support.
2696+ * QUEUE_FLAG_DISCARD wouldn't be set but there is no way for the
2697+ * user to see that, so make sure to set all discard limits to 0.
2698+ */
2699+ limits->discard_granularity = 0;
26932700 return;
2701+ }
26942702
26952703 disable_passdown_if_not_supported(pt);
26962704
@@ -2826,10 +2834,10 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) · 129 unmodified lines
28262834 ti->per_bio_data_size = sizeof(struct dm_thin_endio_hook);
28272835
28282836 /* In case the pool supports discards, pass them on. */
2837+ ti->discard_zeroes_data_unsupported = true;
28292838 if (tc->pool->pf.discard_enabled) {
28302839 ti->discards_supported = true;
28312840 ti->num_discard_bios = 1;
2832− ti->discard_zeroes_data_unsupported = true;
28332841 /* Discard bios must be split on a block boundary */
28342842 ti->split_discard_bios = true;
28352843 }
drivers/md/dm.c+67−4
@@ -211,10 +211,55 @@ struct dm_md_mempools { · 210 unmodified lines
211211 struct bio_set *bs;
212212 };
213213
214−#define MIN_IOS 256
214+#define RESERVED_BIO_BASED_IOS 16
215+#define RESERVED_REQUEST_BASED_IOS 256
216+#define RESERVED_MAX_IOS 1024
215217 static struct kmem_cache *_io_cache;
216218 static struct kmem_cache *_rq_tio_cache;
217219
220+/*
221+ * Bio-based DM's mempools' reserved IOs set by the user.
222+ */
223+static unsigned reserved_bio_based_ios = RESERVED_BIO_BASED_IOS;
224+
225+/*
226+ * Request-based DM's mempools' reserved IOs set by the user.
227+ */
228+static unsigned reserved_rq_based_ios = RESERVED_REQUEST_BASED_IOS;
229+
230+static unsigned __dm_get_reserved_ios(unsigned *reserved_ios,
231+ unsigned def, unsigned max)
232+{
233+ unsigned ios = ACCESS_ONCE(*reserved_ios);
234+ unsigned modified_ios = 0;
235+
236+ if (!ios)
237+ modified_ios = def;
238+ else if (ios > max)
239+ modified_ios = max;
240+
241+ if (modified_ios) {
242+ (void)cmpxchg(reserved_ios, ios, modified_ios);
243+ ios = modified_ios;
244+ }
245+
246+ return ios;
247+}
248+
249+unsigned dm_get_reserved_bio_based_ios(void)
250+{
251+ return __dm_get_reserved_ios(&reserved_bio_based_ios,
252+ RESERVED_BIO_BASED_IOS, RESERVED_MAX_IOS);
253+}
254+EXPORT_SYMBOL_GPL(dm_get_reserved_bio_based_ios);
255+
256+unsigned dm_get_reserved_rq_based_ios(void)
257+{
258+ return __dm_get_reserved_ios(&reserved_rq_based_ios,
259+ RESERVED_REQUEST_BASED_IOS, RESERVED_MAX_IOS);
260+}
261+EXPORT_SYMBOL_GPL(dm_get_reserved_rq_based_ios);
262+
218263 static int __init local_init(void)
219264 {
220265 int r = -ENOMEM;
@@ -2277,6 +2322,17 @@ struct target_type *dm_get_immutable_target_type(struct mapped_device *md) · 2056 unmodified lines
22772322 return md->immutable_target_type;
22782323 }
22792324
2325+/*
2326+ * The queue_limits are only valid as long as you have a reference
2327+ * count on 'md'.
2328+ */
2329+struct queue_limits *dm_get_queue_limits(struct mapped_device *md)
2330+{
2331+ BUG_ON(!atomic_read(&md->holders));
2332+ return &md->queue->limits;
2333+}
2334+EXPORT_SYMBOL_GPL(dm_get_queue_limits);
2335+
22802336 /*
22812337 * Fully initialize a request-based queue (->elevator, ->request_fn, etc).
22822338 */
@@ -2862,18 +2918,18 @@ struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity, u · 579 unmodified lines
28622918
28632919 if (type == DM_TYPE_BIO_BASED) {
28642920 cachep = _io_cache;
2865− pool_size = 16;
2921+ pool_size = dm_get_reserved_bio_based_ios();
28662922 front_pad = roundup(per_bio_data_size, __alignof__(struct dm_target_io)) + offsetof(struct dm_target_io, clone);
28672923 } else if (type == DM_TYPE_REQUEST_BASED) {
28682924 cachep = _rq_tio_cache;
2869− pool_size = MIN_IOS;
2925+ pool_size = dm_get_reserved_rq_based_ios();
28702926 front_pad = offsetof(struct dm_rq_clone_bio_info, clone);
28712927 /* per_bio_data_size is not used. See __bind_mempools(). */
28722928 WARN_ON(per_bio_data_size != 0);
28732929 } else
28742930 goto out;
28752931
2876− pools->io_pool = mempool_create_slab_pool(MIN_IOS, cachep);
2932+ pools->io_pool = mempool_create_slab_pool(pool_size, cachep);
28772933 if (!pools->io_pool)
28782934 goto out;
28792935
@@ -2924,6 +2980,13 @@ module_exit(dm_exit); · 44 unmodified lines
29242980
29252981 module_param(major, uint, 0);
29262982 MODULE_PARM_DESC(major, "The major number of the device mapper");
2983+
2984+module_param(reserved_bio_based_ios, uint, S_IRUGO | S_IWUSR);
2985+MODULE_PARM_DESC(reserved_bio_based_ios, "Reserved IOs in bio-based mempools");
2986+
2987+module_param(reserved_rq_based_ios, uint, S_IRUGO | S_IWUSR);
2988+MODULE_PARM_DESC(reserved_rq_based_ios, "Reserved IOs in request-based mempools");
2989+
29272990 MODULE_DESCRIPTION(DM_NAME " driver");
29282991 MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>");
29292992 MODULE_LICENSE("GPL");
drivers/md/dm.h+3−0
@@ -184,6 +184,9 @@ void dm_free_md_mempools(struct dm_md_mempools *pools); · 183 unmodified lines
184184 /*
185185 * Helpers that are used by DM core
186186 */
187+unsigned dm_get_reserved_bio_based_ios(void);
188+unsigned dm_get_reserved_rq_based_ios(void);
189+
187190 static inline bool dm_message_test_buffer_overflow(char *result, unsigned maxlen)
188191 {
189192 return !maxlen || strlen(result) + 1 >= maxlen;
include/linux/device-mapper.h+2−1
@@ -406,13 +406,14 @@ int dm_noflush_suspending(struct dm_target *ti); · 405 unmodified lines
406406 union map_info *dm_get_mapinfo(struct bio *bio);
407407 union map_info *dm_get_rq_mapinfo(struct request *rq);
408408
409+struct queue_limits *dm_get_queue_limits(struct mapped_device *md);
410+
409411 /*
410412 * Geometry functions.
411413 */
412414 int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo);
413415 int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo);
414416
415−
416417 /*-----------------------------------------------------------------
417418 * Functions for manipulating device-mapper tables.
418419 *---------------------------------------------------------------*/