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

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-2.6-dm

* git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-2.6-dm:
dm kcopyd: return client directly and not through a pointer
dm kcopyd: reserve fewer pages
dm io: use fixed initial mempool size
dm kcopyd: alloc pages from the main page allocator
dm kcopyd: add gfp parm to alloc_pl
dm kcopyd: remove superfluous page allocation spinlock
dm kcopyd: preallocate sub jobs to avoid deadlock
dm kcopyd: avoid pointless job splitting
dm mpath: do not fail paths after integrity errors
dm table: reject devices without request fns
dm table: allow targets to support discards internally

+144 -124
+5 -22
drivers/md/dm-io.c
··· 19 19 #define DM_MSG_PREFIX "io" 20 20 21 21 #define DM_IO_MAX_REGIONS BITS_PER_LONG 22 + #define MIN_IOS 16 23 + #define MIN_BIOS 16 22 24 23 25 struct dm_io_client { 24 26 mempool_t *pool; ··· 43 41 static struct kmem_cache *_dm_io_cache; 44 42 45 43 /* 46 - * io contexts are only dynamically allocated for asynchronous 47 - * io. Since async io is likely to be the majority of io we'll 48 - * have the same number of io contexts as bios! (FIXME: must reduce this). 49 - */ 50 - 51 - static unsigned int pages_to_ios(unsigned int pages) 52 - { 53 - return 4 * pages; /* too many ? */ 54 - } 55 - 56 - /* 57 44 * Create a client with mempool and bioset. 58 45 */ 59 - struct dm_io_client *dm_io_client_create(unsigned num_pages) 46 + struct dm_io_client *dm_io_client_create(void) 60 47 { 61 - unsigned ios = pages_to_ios(num_pages); 62 48 struct dm_io_client *client; 63 49 64 50 client = kmalloc(sizeof(*client), GFP_KERNEL); 65 51 if (!client) 66 52 return ERR_PTR(-ENOMEM); 67 53 68 - client->pool = mempool_create_slab_pool(ios, _dm_io_cache); 54 + client->pool = mempool_create_slab_pool(MIN_IOS, _dm_io_cache); 69 55 if (!client->pool) 70 56 goto bad; 71 57 72 - client->bios = bioset_create(16, 0); 58 + client->bios = bioset_create(MIN_BIOS, 0); 73 59 if (!client->bios) 74 60 goto bad; 75 61 ··· 70 80 return ERR_PTR(-ENOMEM); 71 81 } 72 82 EXPORT_SYMBOL(dm_io_client_create); 73 - 74 - int dm_io_client_resize(unsigned num_pages, struct dm_io_client *client) 75 - { 76 - return mempool_resize(client->pool, pages_to_ios(num_pages), 77 - GFP_KERNEL); 78 - } 79 - EXPORT_SYMBOL(dm_io_client_resize); 80 83 81 84 void dm_io_client_destroy(struct dm_io_client *client) 82 85 {
+98 -70
drivers/md/dm-kcopyd.c
··· 27 27 28 28 #include "dm.h" 29 29 30 + #define SUB_JOB_SIZE 128 31 + #define SPLIT_COUNT 8 32 + #define MIN_JOBS 8 33 + #define RESERVE_PAGES (DIV_ROUND_UP(SUB_JOB_SIZE << SECTOR_SHIFT, PAGE_SIZE)) 34 + 30 35 /*----------------------------------------------------------------- 31 36 * Each kcopyd client has its own little pool of preallocated 32 37 * pages for kcopyd io. 33 38 *---------------------------------------------------------------*/ 34 39 struct dm_kcopyd_client { 35 - spinlock_t lock; 36 40 struct page_list *pages; 37 - unsigned int nr_pages; 38 - unsigned int nr_free_pages; 41 + unsigned nr_reserved_pages; 42 + unsigned nr_free_pages; 39 43 40 44 struct dm_io_client *io_client; 41 45 ··· 71 67 queue_work(kc->kcopyd_wq, &kc->kcopyd_work); 72 68 } 73 69 74 - static struct page_list *alloc_pl(void) 70 + /* 71 + * Obtain one page for the use of kcopyd. 72 + */ 73 + static struct page_list *alloc_pl(gfp_t gfp) 75 74 { 76 75 struct page_list *pl; 77 76 78 - pl = kmalloc(sizeof(*pl), GFP_KERNEL); 77 + pl = kmalloc(sizeof(*pl), gfp); 79 78 if (!pl) 80 79 return NULL; 81 80 82 - pl->page = alloc_page(GFP_KERNEL); 81 + pl->page = alloc_page(gfp); 83 82 if (!pl->page) { 84 83 kfree(pl); 85 84 return NULL; ··· 97 90 kfree(pl); 98 91 } 99 92 93 + /* 94 + * Add the provided pages to a client's free page list, releasing 95 + * back to the system any beyond the reserved_pages limit. 96 + */ 97 + static void kcopyd_put_pages(struct dm_kcopyd_client *kc, struct page_list *pl) 98 + { 99 + struct page_list *next; 100 + 101 + do { 102 + next = pl->next; 103 + 104 + if (kc->nr_free_pages >= kc->nr_reserved_pages) 105 + free_pl(pl); 106 + else { 107 + pl->next = kc->pages; 108 + kc->pages = pl; 109 + kc->nr_free_pages++; 110 + } 111 + 112 + pl = next; 113 + } while (pl); 114 + } 115 + 100 116 static int kcopyd_get_pages(struct dm_kcopyd_client *kc, 101 117 unsigned int nr, struct page_list **pages) 102 118 { 103 119 struct page_list *pl; 104 120 105 - spin_lock(&kc->lock); 106 - if (kc->nr_free_pages < nr) { 107 - spin_unlock(&kc->lock); 108 - return -ENOMEM; 109 - } 121 + *pages = NULL; 110 122 111 - kc->nr_free_pages -= nr; 112 - for (*pages = pl = kc->pages; --nr; pl = pl->next) 113 - ; 114 - 115 - kc->pages = pl->next; 116 - pl->next = NULL; 117 - 118 - spin_unlock(&kc->lock); 123 + do { 124 + pl = alloc_pl(__GFP_NOWARN | __GFP_NORETRY); 125 + if (unlikely(!pl)) { 126 + /* Use reserved pages */ 127 + pl = kc->pages; 128 + if (unlikely(!pl)) 129 + goto out_of_memory; 130 + kc->pages = pl->next; 131 + kc->nr_free_pages--; 132 + } 133 + pl->next = *pages; 134 + *pages = pl; 135 + } while (--nr); 119 136 120 137 return 0; 121 - } 122 138 123 - static void kcopyd_put_pages(struct dm_kcopyd_client *kc, struct page_list *pl) 124 - { 125 - struct page_list *cursor; 126 - 127 - spin_lock(&kc->lock); 128 - for (cursor = pl; cursor->next; cursor = cursor->next) 129 - kc->nr_free_pages++; 130 - 131 - kc->nr_free_pages++; 132 - cursor->next = kc->pages; 133 - kc->pages = pl; 134 - spin_unlock(&kc->lock); 139 + out_of_memory: 140 + if (*pages) 141 + kcopyd_put_pages(kc, *pages); 142 + return -ENOMEM; 135 143 } 136 144 137 145 /* ··· 163 141 } 164 142 } 165 143 166 - static int client_alloc_pages(struct dm_kcopyd_client *kc, unsigned int nr) 144 + /* 145 + * Allocate and reserve nr_pages for the use of a specific client. 146 + */ 147 + static int client_reserve_pages(struct dm_kcopyd_client *kc, unsigned nr_pages) 167 148 { 168 - unsigned int i; 149 + unsigned i; 169 150 struct page_list *pl = NULL, *next; 170 151 171 - for (i = 0; i < nr; i++) { 172 - next = alloc_pl(); 152 + for (i = 0; i < nr_pages; i++) { 153 + next = alloc_pl(GFP_KERNEL); 173 154 if (!next) { 174 155 if (pl) 175 156 drop_pages(pl); ··· 182 157 pl = next; 183 158 } 184 159 160 + kc->nr_reserved_pages += nr_pages; 185 161 kcopyd_put_pages(kc, pl); 186 - kc->nr_pages += nr; 162 + 187 163 return 0; 188 164 } 189 165 190 166 static void client_free_pages(struct dm_kcopyd_client *kc) 191 167 { 192 - BUG_ON(kc->nr_free_pages != kc->nr_pages); 168 + BUG_ON(kc->nr_free_pages != kc->nr_reserved_pages); 193 169 drop_pages(kc->pages); 194 170 kc->pages = NULL; 195 - kc->nr_free_pages = kc->nr_pages = 0; 171 + kc->nr_free_pages = kc->nr_reserved_pages = 0; 196 172 } 197 173 198 174 /*----------------------------------------------------------------- ··· 242 216 struct mutex lock; 243 217 atomic_t sub_jobs; 244 218 sector_t progress; 245 - }; 246 219 247 - /* FIXME: this should scale with the number of pages */ 248 - #define MIN_JOBS 512 220 + struct kcopyd_job *master_job; 221 + }; 249 222 250 223 static struct kmem_cache *_job_cache; 251 224 252 225 int __init dm_kcopyd_init(void) 253 226 { 254 - _job_cache = KMEM_CACHE(kcopyd_job, 0); 227 + _job_cache = kmem_cache_create("kcopyd_job", 228 + sizeof(struct kcopyd_job) * (SPLIT_COUNT + 1), 229 + __alignof__(struct kcopyd_job), 0, NULL); 255 230 if (!_job_cache) 256 231 return -ENOMEM; 257 232 ··· 326 299 327 300 if (job->pages) 328 301 kcopyd_put_pages(kc, job->pages); 329 - mempool_free(job, kc->job_pool); 302 + /* 303 + * If this is the master job, the sub jobs have already 304 + * completed so we can free everything. 305 + */ 306 + if (job->master_job == job) 307 + mempool_free(job, kc->job_pool); 330 308 fn(read_err, write_err, context); 331 309 332 310 if (atomic_dec_and_test(&kc->nr_jobs)) ··· 492 460 wake(kc); 493 461 } 494 462 495 - #define SUB_JOB_SIZE 128 496 463 static void segment_complete(int read_err, unsigned long write_err, 497 464 void *context) 498 465 { 499 466 /* FIXME: tidy this function */ 500 467 sector_t progress = 0; 501 468 sector_t count = 0; 502 - struct kcopyd_job *job = (struct kcopyd_job *) context; 469 + struct kcopyd_job *sub_job = (struct kcopyd_job *) context; 470 + struct kcopyd_job *job = sub_job->master_job; 503 471 struct dm_kcopyd_client *kc = job->kc; 504 472 505 473 mutex_lock(&job->lock); ··· 530 498 531 499 if (count) { 532 500 int i; 533 - struct kcopyd_job *sub_job = mempool_alloc(kc->job_pool, 534 - GFP_NOIO); 535 501 536 502 *sub_job = *job; 537 503 sub_job->source.sector += progress; ··· 541 511 } 542 512 543 513 sub_job->fn = segment_complete; 544 - sub_job->context = job; 514 + sub_job->context = sub_job; 545 515 dispatch_job(sub_job); 546 516 547 517 } else if (atomic_dec_and_test(&job->sub_jobs)) { ··· 561 531 } 562 532 563 533 /* 564 - * Create some little jobs that will do the move between 565 - * them. 534 + * Create some sub jobs to share the work between them. 566 535 */ 567 - #define SPLIT_COUNT 8 568 - static void split_job(struct kcopyd_job *job) 536 + static void split_job(struct kcopyd_job *master_job) 569 537 { 570 538 int i; 571 539 572 - atomic_inc(&job->kc->nr_jobs); 540 + atomic_inc(&master_job->kc->nr_jobs); 573 541 574 - atomic_set(&job->sub_jobs, SPLIT_COUNT); 575 - for (i = 0; i < SPLIT_COUNT; i++) 576 - segment_complete(0, 0u, job); 542 + atomic_set(&master_job->sub_jobs, SPLIT_COUNT); 543 + for (i = 0; i < SPLIT_COUNT; i++) { 544 + master_job[i + 1].master_job = master_job; 545 + segment_complete(0, 0u, &master_job[i + 1]); 546 + } 577 547 } 578 548 579 549 int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, ··· 583 553 struct kcopyd_job *job; 584 554 585 555 /* 586 - * Allocate a new job. 556 + * Allocate an array of jobs consisting of one master job 557 + * followed by SPLIT_COUNT sub jobs. 587 558 */ 588 559 job = mempool_alloc(kc->job_pool, GFP_NOIO); 589 560 ··· 608 577 609 578 job->fn = fn; 610 579 job->context = context; 580 + job->master_job = job; 611 581 612 - if (job->source.count < SUB_JOB_SIZE) 582 + if (job->source.count <= SUB_JOB_SIZE) 613 583 dispatch_job(job); 614 - 615 584 else { 616 585 mutex_init(&job->lock); 617 586 job->progress = 0; ··· 637 606 /*----------------------------------------------------------------- 638 607 * Client setup 639 608 *---------------------------------------------------------------*/ 640 - int dm_kcopyd_client_create(unsigned int nr_pages, 641 - struct dm_kcopyd_client **result) 609 + struct dm_kcopyd_client *dm_kcopyd_client_create(void) 642 610 { 643 611 int r = -ENOMEM; 644 612 struct dm_kcopyd_client *kc; 645 613 646 614 kc = kmalloc(sizeof(*kc), GFP_KERNEL); 647 615 if (!kc) 648 - return -ENOMEM; 616 + return ERR_PTR(-ENOMEM); 649 617 650 - spin_lock_init(&kc->lock); 651 618 spin_lock_init(&kc->job_lock); 652 619 INIT_LIST_HEAD(&kc->complete_jobs); 653 620 INIT_LIST_HEAD(&kc->io_jobs); ··· 662 633 goto bad_workqueue; 663 634 664 635 kc->pages = NULL; 665 - kc->nr_pages = kc->nr_free_pages = 0; 666 - r = client_alloc_pages(kc, nr_pages); 636 + kc->nr_reserved_pages = kc->nr_free_pages = 0; 637 + r = client_reserve_pages(kc, RESERVE_PAGES); 667 638 if (r) 668 639 goto bad_client_pages; 669 640 670 - kc->io_client = dm_io_client_create(nr_pages); 641 + kc->io_client = dm_io_client_create(); 671 642 if (IS_ERR(kc->io_client)) { 672 643 r = PTR_ERR(kc->io_client); 673 644 goto bad_io_client; ··· 676 647 init_waitqueue_head(&kc->destroyq); 677 648 atomic_set(&kc->nr_jobs, 0); 678 649 679 - *result = kc; 680 - return 0; 650 + return kc; 681 651 682 652 bad_io_client: 683 653 client_free_pages(kc); ··· 687 659 bad_slab: 688 660 kfree(kc); 689 661 690 - return r; 662 + return ERR_PTR(r); 691 663 } 692 664 EXPORT_SYMBOL(dm_kcopyd_client_create); 693 665
+1 -2
drivers/md/dm-log.c
··· 449 449 450 450 lc->io_req.mem.type = DM_IO_VMA; 451 451 lc->io_req.notify.fn = NULL; 452 - lc->io_req.client = dm_io_client_create(dm_div_up(buf_size, 453 - PAGE_SIZE)); 452 + lc->io_req.client = dm_io_client_create(); 454 453 if (IS_ERR(lc->io_req.client)) { 455 454 r = PTR_ERR(lc->io_req.client); 456 455 DMWARN("couldn't allocate disk io client");
+1 -1
drivers/md/dm-mpath.c
··· 1290 1290 if (!error && !clone->errors) 1291 1291 return 0; /* I/O complete */ 1292 1292 1293 - if (error == -EOPNOTSUPP || error == -EREMOTEIO) 1293 + if (error == -EOPNOTSUPP || error == -EREMOTEIO || error == -EILSEQ) 1294 1294 return error; 1295 1295 1296 1296 if (mpio->pgpath)
+5 -5
drivers/md/dm-raid1.c
··· 22 22 #define DM_MSG_PREFIX "raid1" 23 23 24 24 #define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */ 25 - #define DM_IO_PAGES 64 26 - #define DM_KCOPYD_PAGES 64 27 25 28 26 #define DM_RAID1_HANDLE_ERRORS 0x01 29 27 #define errors_handled(p) ((p)->features & DM_RAID1_HANDLE_ERRORS) ··· 885 887 return NULL; 886 888 } 887 889 888 - ms->io_client = dm_io_client_create(DM_IO_PAGES); 890 + ms->io_client = dm_io_client_create(); 889 891 if (IS_ERR(ms->io_client)) { 890 892 ti->error = "Error creating dm_io client"; 891 893 mempool_destroy(ms->read_record_pool); ··· 1115 1117 goto err_destroy_wq; 1116 1118 } 1117 1119 1118 - r = dm_kcopyd_client_create(DM_KCOPYD_PAGES, &ms->kcopyd_client); 1119 - if (r) 1120 + ms->kcopyd_client = dm_kcopyd_client_create(); 1121 + if (IS_ERR(ms->kcopyd_client)) { 1122 + r = PTR_ERR(ms->kcopyd_client); 1120 1123 goto err_destroy_wq; 1124 + } 1121 1125 1122 1126 wakeup_mirrord(ms); 1123 1127 return 0;
+1 -12
drivers/md/dm-snap-persistent.c
··· 154 154 struct workqueue_struct *metadata_wq; 155 155 }; 156 156 157 - static unsigned sectors_to_pages(unsigned sectors) 158 - { 159 - return DIV_ROUND_UP(sectors, PAGE_SIZE >> 9); 160 - } 161 - 162 157 static int alloc_area(struct pstore *ps) 163 158 { 164 159 int r = -ENOMEM; ··· 313 318 chunk_size_supplied = 0; 314 319 } 315 320 316 - ps->io_client = dm_io_client_create(sectors_to_pages(ps->store-> 317 - chunk_size)); 321 + ps->io_client = dm_io_client_create(); 318 322 if (IS_ERR(ps->io_client)) 319 323 return PTR_ERR(ps->io_client); 320 324 ··· 361 367 chunk_size, chunk_err); 362 368 return r; 363 369 } 364 - 365 - r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size), 366 - ps->io_client); 367 - if (r) 368 - return r; 369 370 370 371 r = alloc_area(ps); 371 372 return r;
+3 -7
drivers/md/dm-snap.c
··· 40 40 #define SNAPSHOT_COPY_PRIORITY 2 41 41 42 42 /* 43 - * Reserve 1MB for each snapshot initially (with minimum of 1 page). 44 - */ 45 - #define SNAPSHOT_PAGES (((1UL << 20) >> PAGE_SHIFT) ? : 1) 46 - 47 - /* 48 43 * The size of the mempool used to track chunks in use. 49 44 */ 50 45 #define MIN_IOS 256 ··· 1111 1116 goto bad_hash_tables; 1112 1117 } 1113 1118 1114 - r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client); 1115 - if (r) { 1119 + s->kcopyd_client = dm_kcopyd_client_create(); 1120 + if (IS_ERR(s->kcopyd_client)) { 1121 + r = PTR_ERR(s->kcopyd_client); 1116 1122 ti->error = "Could not create kcopyd client"; 1117 1123 goto bad_kcopyd; 1118 1124 }
+22 -1
drivers/md/dm-table.c
··· 362 362 static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, 363 363 sector_t start, sector_t len, void *data) 364 364 { 365 + struct request_queue *q; 365 366 struct queue_limits *limits = data; 366 367 struct block_device *bdev = dev->bdev; 367 368 sector_t dev_size = ··· 370 369 unsigned short logical_block_size_sectors = 371 370 limits->logical_block_size >> SECTOR_SHIFT; 372 371 char b[BDEVNAME_SIZE]; 372 + 373 + /* 374 + * Some devices exist without request functions, 375 + * such as loop devices not yet bound to backing files. 376 + * Forbid the use of such devices. 377 + */ 378 + q = bdev_get_queue(bdev); 379 + if (!q || !q->make_request_fn) { 380 + DMWARN("%s: %s is not yet initialised: " 381 + "start=%llu, len=%llu, dev_size=%llu", 382 + dm_device_name(ti->table->md), bdevname(bdev, b), 383 + (unsigned long long)start, 384 + (unsigned long long)len, 385 + (unsigned long long)dev_size); 386 + return 1; 387 + } 373 388 374 389 if (!dev_size) 375 390 return 0; ··· 1363 1346 return 0; 1364 1347 1365 1348 /* 1366 - * Ensure that at least one underlying device supports discards. 1349 + * Unless any target used by the table set discards_supported, 1350 + * require at least one underlying device to support discards. 1367 1351 * t->devices includes internal dm devices such as mirror logs 1368 1352 * so we need to use iterate_devices here, which targets 1369 1353 * supporting discard must provide. 1370 1354 */ 1371 1355 while (i < dm_table_get_num_targets(t)) { 1372 1356 ti = dm_table_get_target(t, i++); 1357 + 1358 + if (ti->discards_supported) 1359 + return 1; 1373 1360 1374 1361 if (ti->type->iterate_devices && 1375 1362 ti->type->iterate_devices(ti, device_discard_capable, NULL))
+6
include/linux/device-mapper.h
··· 191 191 192 192 /* Used to provide an error string from the ctr */ 193 193 char *error; 194 + 195 + /* 196 + * Set if this target needs to receive discards regardless of 197 + * whether or not its underlying devices have support. 198 + */ 199 + unsigned discards_supported:1; 194 200 }; 195 201 196 202 /* Each target can link one of these into the table */
+1 -2
include/linux/dm-io.h
··· 69 69 * 70 70 * Create/destroy may block. 71 71 */ 72 - struct dm_io_client *dm_io_client_create(unsigned num_pages); 73 - int dm_io_client_resize(unsigned num_pages, struct dm_io_client *client); 72 + struct dm_io_client *dm_io_client_create(void); 74 73 void dm_io_client_destroy(struct dm_io_client *client); 75 74 76 75 /*
+1 -2
include/linux/dm-kcopyd.h
··· 25 25 * To use kcopyd you must first create a dm_kcopyd_client object. 26 26 */ 27 27 struct dm_kcopyd_client; 28 - int dm_kcopyd_client_create(unsigned num_pages, 29 - struct dm_kcopyd_client **result); 28 + struct dm_kcopyd_client *dm_kcopyd_client_create(void); 30 29 void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc); 31 30 32 31 /*