Skip to content

Commit

Permalink
lightnvm: pblk: take bitmap alloc. out of critical section
Browse files Browse the repository at this point in the history
pblk allocates line bitmaps within the line lock unnecessarily. In order
to take pressure out of the fast patch, allocate line bitmaps outside
of this lock and refactor accordingly.

Signed-off-by: Javier González <[email protected]>
Signed-off-by: Matias Bjørling <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
javigon authored and axboe committed Jun 1, 2018
1 parent cc9c9a0 commit 9cfd5a9
Showing 1 changed file with 56 additions and 41 deletions.
97 changes: 56 additions & 41 deletions drivers/lightnvm/pblk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,25 @@ static int pblk_line_init_metadata(struct pblk *pblk, struct pblk_line *line,
return 1;
}

static int pblk_line_alloc_bitmaps(struct pblk *pblk, struct pblk_line *line)
{
struct pblk_line_meta *lm = &pblk->lm;

line->map_bitmap = kzalloc(lm->sec_bitmap_len, GFP_KERNEL);
if (!line->map_bitmap)
return -ENOMEM;

/* will be initialized using bb info from map_bitmap */
line->invalid_bitmap = kmalloc(lm->sec_bitmap_len, GFP_KERNEL);
if (!line->invalid_bitmap) {
kfree(line->map_bitmap);
line->map_bitmap = NULL;
return -ENOMEM;
}

return 0;
}

/* For now lines are always assumed full lines. Thus, smeta former and current
* lun bitmaps are omitted.
*/
Expand Down Expand Up @@ -1171,18 +1190,7 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line)
{
struct pblk_line_meta *lm = &pblk->lm;
int blk_in_line = atomic_read(&line->blk_in_line);
int blk_to_erase, ret;

line->map_bitmap = kzalloc(lm->sec_bitmap_len, GFP_ATOMIC);
if (!line->map_bitmap)
return -ENOMEM;

/* will be initialized using bb info from map_bitmap */
line->invalid_bitmap = kmalloc(lm->sec_bitmap_len, GFP_ATOMIC);
if (!line->invalid_bitmap) {
ret = -ENOMEM;
goto fail_free_map_bitmap;
}
int blk_to_erase;

/* Bad blocks do not need to be erased */
bitmap_copy(line->erase_bitmap, line->blk_bitmap, lm->blk_per_line);
Expand All @@ -1200,15 +1208,15 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line)
}

if (blk_in_line < lm->min_blk_line) {
ret = -EAGAIN;
goto fail_free_invalid_bitmap;
spin_unlock(&line->lock);
return -EAGAIN;
}

if (line->state != PBLK_LINESTATE_FREE) {
WARN(1, "pblk: corrupted line %d, state %d\n",
line->id, line->state);
ret = -EINTR;
goto fail_free_invalid_bitmap;
spin_unlock(&line->lock);
return -EINTR;
}

line->state = PBLK_LINESTATE_OPEN;
Expand All @@ -1222,16 +1230,6 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line)
kref_init(&line->ref);

return 0;

fail_free_invalid_bitmap:
spin_unlock(&line->lock);
kfree(line->invalid_bitmap);
line->invalid_bitmap = NULL;
fail_free_map_bitmap:
kfree(line->map_bitmap);
line->map_bitmap = NULL;

return ret;
}

int pblk_line_recov_alloc(struct pblk *pblk, struct pblk_line *line)
Expand All @@ -1251,13 +1249,16 @@ int pblk_line_recov_alloc(struct pblk *pblk, struct pblk_line *line)
}
spin_unlock(&l_mg->free_lock);

pblk_rl_free_lines_dec(&pblk->rl, line, true);
ret = pblk_line_alloc_bitmaps(pblk, line);
if (ret)
return ret;

if (!pblk_line_init_bb(pblk, line, 0)) {
list_add(&line->list, &l_mg->free_list);
return -EINTR;
}

pblk_rl_free_lines_dec(&pblk->rl, line, true);
return 0;
}

Expand All @@ -1269,6 +1270,24 @@ void pblk_line_recov_close(struct pblk *pblk, struct pblk_line *line)
line->emeta = NULL;
}

static void pblk_line_reinit(struct pblk_line *line)
{
*line->vsc = cpu_to_le32(EMPTY_ENTRY);

line->map_bitmap = NULL;
line->invalid_bitmap = NULL;
line->smeta = NULL;
line->emeta = NULL;
}

void pblk_line_free(struct pblk_line *line)
{
kfree(line->map_bitmap);
kfree(line->invalid_bitmap);

pblk_line_reinit(line);
}

struct pblk_line *pblk_line_get(struct pblk *pblk)
{
struct pblk_line_mgmt *l_mg = &pblk->l_mg;
Expand Down Expand Up @@ -1335,11 +1354,14 @@ static struct pblk_line *pblk_line_retry(struct pblk *pblk,
return NULL;
}

retry_line->map_bitmap = line->map_bitmap;
retry_line->invalid_bitmap = line->invalid_bitmap;
retry_line->smeta = line->smeta;
retry_line->emeta = line->emeta;
retry_line->meta_line = line->meta_line;

pblk_line_free(line);
pblk_line_reinit(line);

l_mg->data_line = retry_line;
spin_unlock(&l_mg->free_lock);

Expand Down Expand Up @@ -1392,6 +1414,9 @@ struct pblk_line *pblk_line_get_first_data(struct pblk *pblk)
}
spin_unlock(&l_mg->free_lock);

if (pblk_line_alloc_bitmaps(pblk, line))
return NULL;

if (pblk_line_erase(pblk, line)) {
line = pblk_line_retry(pblk, line);
if (!line)
Expand Down Expand Up @@ -1536,6 +1561,9 @@ struct pblk_line *pblk_line_replace_data(struct pblk *pblk)
goto retry_erase;
}

if (pblk_line_alloc_bitmaps(pblk, new))
return NULL;

retry_setup:
if (!pblk_line_init_metadata(pblk, new, cur)) {
new = pblk_line_retry(pblk, new);
Expand Down Expand Up @@ -1575,19 +1603,6 @@ struct pblk_line *pblk_line_replace_data(struct pblk *pblk)
return new;
}

void pblk_line_free(struct pblk_line *line)
{
kfree(line->map_bitmap);
kfree(line->invalid_bitmap);

*line->vsc = cpu_to_le32(EMPTY_ENTRY);

line->map_bitmap = NULL;
line->invalid_bitmap = NULL;
line->smeta = NULL;
line->emeta = NULL;
}

static void __pblk_line_put(struct pblk *pblk, struct pblk_line *line)
{
struct pblk_line_mgmt *l_mg = &pblk->l_mg;
Expand Down

0 comments on commit 9cfd5a9

Please sign in to comment.