aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm
diff options
context:
space:
mode:
authorHans Holmberg <hans.holmberg@cnexlabs.com>2018-10-09 07:11:58 -0400
committerJens Axboe <axboe@kernel.dk>2018-10-09 10:25:07 -0400
commit1864de94ec9d6e1ae4d481212847374df9b1be41 (patch)
tree05bf1d0ff69e95206cd7b6950380ff558e24af11 /drivers/lightnvm
parent63dee3a6c39a5bfa5f299ebb314f2e3e0273092b (diff)
lightnvm: pblk: stop recreating global caches
Pblk should not create a set of global caches every time a pblk instance is created. The global caches should be made available only when there is one or more pblk instances. This patch bundles the global caches together with a kref keeping track of whether the caches should be available or not. Also, turn the global pblk lock into a mutex that explicitly protects the caches (as this was the only purpose of the lock). Signed-off-by: Hans Holmberg <hans.holmberg@cnexlabs.com> Signed-off-by: Matias Bjørling <mb@lightnvm.io> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/lightnvm')
-rw-r--r--drivers/lightnvm/pblk-init.c132
1 files changed, 86 insertions, 46 deletions
diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index 9aebdee8e4c9..fb66bc84d5ca 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -26,9 +26,24 @@ static unsigned int write_buffer_size;
26module_param(write_buffer_size, uint, 0644); 26module_param(write_buffer_size, uint, 0644);
27MODULE_PARM_DESC(write_buffer_size, "number of entries in a write buffer"); 27MODULE_PARM_DESC(write_buffer_size, "number of entries in a write buffer");
28 28
29static struct kmem_cache *pblk_ws_cache, *pblk_rec_cache, *pblk_g_rq_cache, 29struct pblk_global_caches {
30 *pblk_w_rq_cache; 30 struct kmem_cache *ws;
31static DECLARE_RWSEM(pblk_lock); 31 struct kmem_cache *rec;
32 struct kmem_cache *g_rq;
33 struct kmem_cache *w_rq;
34
35 struct kref kref;
36
37 struct mutex mutex; /* Ensures consistency between
38 * caches and kref
39 */
40};
41
42static struct pblk_global_caches pblk_caches = {
43 .mutex = __MUTEX_INITIALIZER(pblk_caches.mutex),
44 .kref = KREF_INIT(0),
45};
46
32struct bio_set pblk_bio_set; 47struct bio_set pblk_bio_set;
33 48
34static int pblk_rw_io(struct request_queue *q, struct pblk *pblk, 49static int pblk_rw_io(struct request_queue *q, struct pblk *pblk,
@@ -307,53 +322,80 @@ static int pblk_set_addrf(struct pblk *pblk)
307 return 0; 322 return 0;
308} 323}
309 324
310static int pblk_init_global_caches(struct pblk *pblk) 325static int pblk_create_global_caches(void)
311{ 326{
312 down_write(&pblk_lock); 327
313 pblk_ws_cache = kmem_cache_create("pblk_blk_ws", 328 pblk_caches.ws = kmem_cache_create("pblk_blk_ws",
314 sizeof(struct pblk_line_ws), 0, 0, NULL); 329 sizeof(struct pblk_line_ws), 0, 0, NULL);
315 if (!pblk_ws_cache) { 330 if (!pblk_caches.ws)
316 up_write(&pblk_lock);
317 return -ENOMEM; 331 return -ENOMEM;
318 }
319 332
320 pblk_rec_cache = kmem_cache_create("pblk_rec", 333 pblk_caches.rec = kmem_cache_create("pblk_rec",
321 sizeof(struct pblk_rec_ctx), 0, 0, NULL); 334 sizeof(struct pblk_rec_ctx), 0, 0, NULL);
322 if (!pblk_rec_cache) { 335 if (!pblk_caches.rec)
323 kmem_cache_destroy(pblk_ws_cache); 336 goto fail_destroy_ws;
324 up_write(&pblk_lock);
325 return -ENOMEM;
326 }
327 337
328 pblk_g_rq_cache = kmem_cache_create("pblk_g_rq", pblk_g_rq_size, 338 pblk_caches.g_rq = kmem_cache_create("pblk_g_rq", pblk_g_rq_size,
329 0, 0, NULL); 339 0, 0, NULL);
330 if (!pblk_g_rq_cache) { 340 if (!pblk_caches.g_rq)
331 kmem_cache_destroy(pblk_ws_cache); 341 goto fail_destroy_rec;
332 kmem_cache_destroy(pblk_rec_cache);
333 up_write(&pblk_lock);
334 return -ENOMEM;
335 }
336 342
337 pblk_w_rq_cache = kmem_cache_create("pblk_w_rq", pblk_w_rq_size, 343 pblk_caches.w_rq = kmem_cache_create("pblk_w_rq", pblk_w_rq_size,
338 0, 0, NULL); 344 0, 0, NULL);
339 if (!pblk_w_rq_cache) { 345 if (!pblk_caches.w_rq)
340 kmem_cache_destroy(pblk_ws_cache); 346 goto fail_destroy_g_rq;
341 kmem_cache_destroy(pblk_rec_cache);
342 kmem_cache_destroy(pblk_g_rq_cache);
343 up_write(&pblk_lock);
344 return -ENOMEM;
345 }
346 up_write(&pblk_lock);
347 347
348 return 0; 348 return 0;
349
350fail_destroy_g_rq:
351 kmem_cache_destroy(pblk_caches.g_rq);
352fail_destroy_rec:
353 kmem_cache_destroy(pblk_caches.rec);
354fail_destroy_ws:
355 kmem_cache_destroy(pblk_caches.ws);
356
357 return -ENOMEM;
358}
359
360static int pblk_get_global_caches(void)
361{
362 int ret;
363
364 mutex_lock(&pblk_caches.mutex);
365
366 if (kref_read(&pblk_caches.kref) > 0) {
367 kref_get(&pblk_caches.kref);
368 mutex_unlock(&pblk_caches.mutex);
369 return 0;
370 }
371
372 ret = pblk_create_global_caches();
373
374 if (!ret)
375 kref_get(&pblk_caches.kref);
376
377 mutex_unlock(&pblk_caches.mutex);
378
379 return ret;
380}
381
382static void pblk_destroy_global_caches(struct kref *ref)
383{
384 struct pblk_global_caches *c;
385
386 c = container_of(ref, struct pblk_global_caches, kref);
387
388 kmem_cache_destroy(c->ws);
389 kmem_cache_destroy(c->rec);
390 kmem_cache_destroy(c->g_rq);
391 kmem_cache_destroy(c->w_rq);
349} 392}
350 393
351static void pblk_free_global_caches(struct pblk *pblk) 394static void pblk_put_global_caches(void)
352{ 395{
353 kmem_cache_destroy(pblk_ws_cache); 396 mutex_lock(&pblk_caches.mutex);
354 kmem_cache_destroy(pblk_rec_cache); 397 kref_put(&pblk_caches.kref, pblk_destroy_global_caches);
355 kmem_cache_destroy(pblk_g_rq_cache); 398 mutex_unlock(&pblk_caches.mutex);
356 kmem_cache_destroy(pblk_w_rq_cache);
357} 399}
358 400
359static int pblk_core_init(struct pblk *pblk) 401static int pblk_core_init(struct pblk *pblk)
@@ -382,7 +424,7 @@ static int pblk_core_init(struct pblk *pblk)
382 if (!pblk->pad_dist) 424 if (!pblk->pad_dist)
383 return -ENOMEM; 425 return -ENOMEM;
384 426
385 if (pblk_init_global_caches(pblk)) 427 if (pblk_get_global_caches())
386 goto fail_free_pad_dist; 428 goto fail_free_pad_dist;
387 429
388 /* Internal bios can be at most the sectors signaled by the device. */ 430 /* Internal bios can be at most the sectors signaled by the device. */
@@ -391,27 +433,27 @@ static int pblk_core_init(struct pblk *pblk)
391 goto free_global_caches; 433 goto free_global_caches;
392 434
393 ret = mempool_init_slab_pool(&pblk->gen_ws_pool, PBLK_GEN_WS_POOL_SIZE, 435 ret = mempool_init_slab_pool(&pblk->gen_ws_pool, PBLK_GEN_WS_POOL_SIZE,
394 pblk_ws_cache); 436 pblk_caches.ws);
395 if (ret) 437 if (ret)
396 goto free_page_bio_pool; 438 goto free_page_bio_pool;
397 439
398 ret = mempool_init_slab_pool(&pblk->rec_pool, geo->all_luns, 440 ret = mempool_init_slab_pool(&pblk->rec_pool, geo->all_luns,
399 pblk_rec_cache); 441 pblk_caches.rec);
400 if (ret) 442 if (ret)
401 goto free_gen_ws_pool; 443 goto free_gen_ws_pool;
402 444
403 ret = mempool_init_slab_pool(&pblk->r_rq_pool, geo->all_luns, 445 ret = mempool_init_slab_pool(&pblk->r_rq_pool, geo->all_luns,
404 pblk_g_rq_cache); 446 pblk_caches.g_rq);
405 if (ret) 447 if (ret)
406 goto free_rec_pool; 448 goto free_rec_pool;
407 449
408 ret = mempool_init_slab_pool(&pblk->e_rq_pool, geo->all_luns, 450 ret = mempool_init_slab_pool(&pblk->e_rq_pool, geo->all_luns,
409 pblk_g_rq_cache); 451 pblk_caches.g_rq);
410 if (ret) 452 if (ret)
411 goto free_r_rq_pool; 453 goto free_r_rq_pool;
412 454
413 ret = mempool_init_slab_pool(&pblk->w_rq_pool, geo->all_luns, 455 ret = mempool_init_slab_pool(&pblk->w_rq_pool, geo->all_luns,
414 pblk_w_rq_cache); 456 pblk_caches.w_rq);
415 if (ret) 457 if (ret)
416 goto free_e_rq_pool; 458 goto free_e_rq_pool;
417 459
@@ -457,7 +499,7 @@ free_gen_ws_pool:
457free_page_bio_pool: 499free_page_bio_pool:
458 mempool_exit(&pblk->page_bio_pool); 500 mempool_exit(&pblk->page_bio_pool);
459free_global_caches: 501free_global_caches:
460 pblk_free_global_caches(pblk); 502 pblk_put_global_caches();
461fail_free_pad_dist: 503fail_free_pad_dist:
462 kfree(pblk->pad_dist); 504 kfree(pblk->pad_dist);
463 return -ENOMEM; 505 return -ENOMEM;
@@ -481,7 +523,7 @@ static void pblk_core_free(struct pblk *pblk)
481 mempool_exit(&pblk->e_rq_pool); 523 mempool_exit(&pblk->e_rq_pool);
482 mempool_exit(&pblk->w_rq_pool); 524 mempool_exit(&pblk->w_rq_pool);
483 525
484 pblk_free_global_caches(pblk); 526 pblk_put_global_caches();
485 kfree(pblk->pad_dist); 527 kfree(pblk->pad_dist);
486} 528}
487 529
@@ -1074,7 +1116,6 @@ static void pblk_exit(void *private, bool graceful)
1074{ 1116{
1075 struct pblk *pblk = private; 1117 struct pblk *pblk = private;
1076 1118
1077 down_write(&pblk_lock);
1078 pblk_gc_exit(pblk, graceful); 1119 pblk_gc_exit(pblk, graceful);
1079 pblk_tear_down(pblk, graceful); 1120 pblk_tear_down(pblk, graceful);
1080 1121
@@ -1083,7 +1124,6 @@ static void pblk_exit(void *private, bool graceful)
1083#endif 1124#endif
1084 1125
1085 pblk_free(pblk); 1126 pblk_free(pblk);
1086 up_write(&pblk_lock);
1087} 1127}
1088 1128
1089static sector_t pblk_capacity(void *private) 1129static sector_t pblk_capacity(void *private)