pr_err("pblk: attempted to erase bb: line:%d, pos:%d\n",
                                                        line->id, pos);
 
-       pblk_line_run_ws(pblk, NULL, ppa, pblk_line_mark_bb);
+       pblk_line_run_ws(pblk, NULL, ppa, pblk_line_mark_bb, pblk->bb_wq);
 }
 
 static void __pblk_end_io_erase(struct pblk *pblk, struct nvm_rq *rqd)
 }
 
 void pblk_line_run_ws(struct pblk *pblk, struct pblk_line *line, void *priv,
-                     void (*work)(struct work_struct *))
+                     void (*work)(struct work_struct *),
+                     struct workqueue_struct *wq)
 {
        struct pblk_line_ws *line_ws;
 
        line_ws->priv = priv;
 
        INIT_WORK(&line_ws->ws, work);
-       queue_work(pblk->kw_wq, &line_ws->ws);
+       queue_work(wq, &line_ws->ws);
 }
 
 void pblk_down_rq(struct pblk *pblk, struct ppa_addr *ppa_list, int nr_ppas,
 
        if (!pblk->page_pool)
                return -ENOMEM;
 
-       pblk->line_ws_pool = mempool_create_slab_pool(geo->nr_luns,
+       pblk->line_ws_pool = mempool_create_slab_pool(PBLK_WS_POOL_SIZE,
                                                        pblk_blk_ws_cache);
        if (!pblk->line_ws_pool)
                goto free_page_pool;
        if (!pblk->rec_pool)
                goto free_blk_ws_pool;
 
-       pblk->g_rq_pool = mempool_create_slab_pool(64, pblk_g_rq_cache);
+       pblk->g_rq_pool = mempool_create_slab_pool(PBLK_READ_REQ_POOL_SIZE,
+                                                       pblk_g_rq_cache);
        if (!pblk->g_rq_pool)
                goto free_rec_pool;
 
-       pblk->w_rq_pool = mempool_create_slab_pool(64, pblk_w_rq_cache);
+       pblk->w_rq_pool = mempool_create_slab_pool(geo->nr_luns * 2,
+                                                       pblk_w_rq_cache);
        if (!pblk->w_rq_pool)
                goto free_g_rq_pool;
 
        pblk->line_meta_pool =
-                       mempool_create_slab_pool(16, pblk_line_meta_cache);
+                       mempool_create_slab_pool(PBLK_META_POOL_SIZE,
+                                                       pblk_line_meta_cache);
        if (!pblk->line_meta_pool)
                goto free_w_rq_pool;
 
-       pblk->kw_wq = alloc_workqueue("pblk-aux-wq",
-                                       WQ_MEM_RECLAIM | WQ_UNBOUND, 1);
-       if (!pblk->kw_wq)
+       pblk->close_wq = alloc_workqueue("pblk-close-wq",
+                       WQ_MEM_RECLAIM | WQ_UNBOUND, PBLK_NR_CLOSE_JOBS);
+       if (!pblk->close_wq)
                goto free_line_meta_pool;
 
+       pblk->bb_wq = alloc_workqueue("pblk-bb-wq",
+                       WQ_MEM_RECLAIM | WQ_UNBOUND, 0);
+       if (!pblk->bb_wq)
+               goto free_close_wq;
+
        if (pblk_set_ppaf(pblk))
-               goto free_kw_wq;
+               goto free_bb_wq;
 
        if (pblk_rwb_init(pblk))
-               goto free_kw_wq;
+               goto free_bb_wq;
 
        INIT_LIST_HEAD(&pblk->compl_list);
        return 0;
 
-free_kw_wq:
-       destroy_workqueue(pblk->kw_wq);
+free_bb_wq:
+       destroy_workqueue(pblk->bb_wq);
+free_close_wq:
+       destroy_workqueue(pblk->close_wq);
 free_line_meta_pool:
        mempool_destroy(pblk->line_meta_pool);
 free_w_rq_pool:
 
 static void pblk_core_free(struct pblk *pblk)
 {
-       if (pblk->kw_wq)
-               destroy_workqueue(pblk->kw_wq);
+       if (pblk->close_wq)
+               destroy_workqueue(pblk->close_wq);
+
+       if (pblk->bb_wq)
+               destroy_workqueue(pblk->bb_wq);
 
        mempool_destroy(pblk->page_pool);
        mempool_destroy(pblk->line_ws_pool);
 
        }
 
        INIT_WORK(&recovery->ws_rec, pblk_submit_rec);
-       queue_work(pblk->kw_wq, &recovery->ws_rec);
+       queue_work(pblk->close_wq, &recovery->ws_rec);
 
 out:
        pblk_complete_write(pblk, rqd, c_ctx);
 
        sync = atomic_add_return(rqd->nr_ppas, &emeta->sync);
        if (sync == emeta->nr_entries)
-               pblk_line_run_ws(pblk, line, NULL, pblk_line_close_ws);
+               pblk_line_run_ws(pblk, line, NULL, pblk_line_close_ws,
+                                                               pblk->close_wq);
 
        bio_put(rqd->bio);
        pblk_free_rqd(pblk, rqd, READ);
 
 #define PBLK_MAX_REQ_ADDRS (64)
 #define PBLK_MAX_REQ_ADDRS_PW (6)
 
+#define PBLK_WS_POOL_SIZE (128)
+#define PBLK_META_POOL_SIZE (128)
+#define PBLK_READ_REQ_POOL_SIZE (1024)
+
+#define PBLK_NR_CLOSE_JOBS (4)
+
 #define PBLK_CACHE_NAME_LEN (DISK_NAME_LEN + 16)
 
 #define PBLK_COMMAND_TIMEOUT_MS 30000
        mempool_t *w_rq_pool;
        mempool_t *line_meta_pool;
 
-       struct workqueue_struct *kw_wq;
+       struct workqueue_struct *close_wq;
+       struct workqueue_struct *bb_wq;
+
        struct timer_list wtimer;
 
        struct pblk_gc gc;
 void pblk_line_close_ws(struct work_struct *work);
 void pblk_line_mark_bb(struct work_struct *work);
 void pblk_line_run_ws(struct pblk *pblk, struct pblk_line *line, void *priv,
-                     void (*work)(struct work_struct *));
+                     void (*work)(struct work_struct *),
+                     struct workqueue_struct *wq);
 u64 pblk_line_smeta_start(struct pblk *pblk, struct pblk_line *line);
 int pblk_line_read_smeta(struct pblk *pblk, struct pblk_line *line);
 int pblk_line_read_emeta(struct pblk *pblk, struct pblk_line *line,