Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dm snapshot: use per device mempools

Change snapshot per-module mempool to per-device mempool.

Per-module mempools could cause a deadlock if multiple
snapshot devices are stacked above each other.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>

authored by

Mikulas Patocka and committed by
Alasdair G Kergon
92e86812 a8d41b59

+24 -18
+22 -18
drivers/md/dm-snap.c
··· 96 96 */ 97 97 static struct kmem_cache *exception_cache; 98 98 static struct kmem_cache *pending_cache; 99 - static mempool_t *pending_pool; 100 99 101 100 struct dm_snap_tracked_chunk { 102 101 struct hlist_node node; ··· 363 364 kmem_cache_free(exception_cache, e); 364 365 } 365 366 366 - static struct dm_snap_pending_exception *alloc_pending_exception(void) 367 + static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snapshot *s) 367 368 { 368 - return mempool_alloc(pending_pool, GFP_NOIO); 369 + struct dm_snap_pending_exception *pe = mempool_alloc(s->pending_pool, 370 + GFP_NOIO); 371 + 372 + pe->snap = s; 373 + 374 + return pe; 369 375 } 370 376 371 377 static void free_pending_exception(struct dm_snap_pending_exception *pe) 372 378 { 373 - mempool_free(pe, pending_pool); 379 + mempool_free(pe, pe->snap->pending_pool); 374 380 } 375 381 376 382 static void insert_completed_exception(struct dm_snapshot *s, ··· 631 627 goto bad5; 632 628 } 633 629 630 + s->pending_pool = mempool_create_slab_pool(MIN_IOS, pending_cache); 631 + if (!s->pending_pool) { 632 + ti->error = "Could not allocate mempool for pending exceptions"; 633 + goto bad6; 634 + } 635 + 634 636 s->tracked_chunk_pool = mempool_create_slab_pool(MIN_IOS, 635 637 tracked_chunk_cache); 636 638 if (!s->tracked_chunk_pool) { 637 639 ti->error = "Could not allocate tracked_chunk mempool for " 638 640 "tracking reads"; 639 - goto bad6; 641 + goto bad_tracked_chunk_pool; 640 642 } 641 643 642 644 for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++) ··· 678 668 679 669 bad_load_and_register: 680 670 mempool_destroy(s->tracked_chunk_pool); 671 + 672 + bad_tracked_chunk_pool: 673 + mempool_destroy(s->pending_pool); 681 674 682 675 bad6: 683 676 dm_kcopyd_client_destroy(s->kcopyd_client); ··· 735 722 mempool_destroy(s->tracked_chunk_pool); 736 723 737 724 __free_exceptions(s); 725 + 726 + mempool_destroy(s->pending_pool); 738 727 739 728 dm_put_device(ti, s->origin); 740 729 dm_put_device(ti, s->cow); ··· 984 969 * to hold the lock while we do this. 985 970 */ 986 971 up_write(&s->lock); 987 - pe = alloc_pending_exception(); 972 + pe = alloc_pending_exception(s); 988 973 down_write(&s->lock); 989 974 990 975 if (!s->valid) { ··· 1004 989 bio_list_init(&pe->snapshot_bios); 1005 990 pe->primary_pe = NULL; 1006 991 atomic_set(&pe->ref_count, 0); 1007 - pe->snap = s; 1008 992 pe->started = 0; 1009 993 1010 994 if (s->store.prepare_exception(&s->store, &pe->e)) { ··· 1432 1418 goto bad5; 1433 1419 } 1434 1420 1435 - pending_pool = mempool_create_slab_pool(128, pending_cache); 1436 - if (!pending_pool) { 1437 - DMERR("Couldn't create pending pool."); 1438 - r = -ENOMEM; 1439 - goto bad_pending_pool; 1440 - } 1441 - 1442 1421 ksnapd = create_singlethread_workqueue("ksnapd"); 1443 1422 if (!ksnapd) { 1444 1423 DMERR("Failed to create ksnapd workqueue."); 1445 1424 r = -ENOMEM; 1446 - goto bad6; 1425 + goto bad_pending_pool; 1447 1426 } 1448 1427 1449 1428 return 0; 1450 1429 1451 - bad6: 1452 - mempool_destroy(pending_pool); 1453 1430 bad_pending_pool: 1454 1431 kmem_cache_destroy(tracked_chunk_cache); 1455 1432 bad5: ··· 1471 1466 DMERR("origin unregister failed %d", r); 1472 1467 1473 1468 exit_origin_hash(); 1474 - mempool_destroy(pending_pool); 1475 1469 kmem_cache_destroy(pending_cache); 1476 1470 kmem_cache_destroy(exception_cache); 1477 1471 kmem_cache_destroy(tracked_chunk_cache);
+2
drivers/md/dm-snap.h
··· 161 161 /* The last percentage we notified */ 162 162 int last_percent; 163 163 164 + mempool_t *pending_pool; 165 + 164 166 struct exception_table pending; 165 167 struct exception_table complete; 166 168