Commit ff8f3520 authored by Hans Holmberg's avatar Hans Holmberg Committed by Jens Axboe
Browse files

lightnvm: pblk: use kvmalloc for metadata



There is no reason now not to use kvmalloc, so replace the internal
metadata allocation scheme.

Reviewed-by: default avatarJavier González <javier@javigon.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarHans Holmberg <hans@owltronix.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 48e5da72
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -1839,8 +1839,7 @@ static void pblk_save_lba_list(struct pblk *pblk, struct pblk_line *line)
	struct pblk_w_err_gc *w_err_gc = line->w_err_gc;
	struct pblk_emeta *emeta = line->emeta;

	w_err_gc->lba_list = pblk_malloc(lba_list_size,
					 l_mg->emeta_alloc_type, GFP_KERNEL);
	w_err_gc->lba_list = kvmalloc(lba_list_size, GFP_KERNEL);
	memcpy(w_err_gc->lba_list, emeta_to_lbas(pblk, emeta->buf),
				lba_list_size);
}
+8 −11
Original line number Diff line number Diff line
@@ -132,14 +132,12 @@ static __le64 *get_lba_list_from_emeta(struct pblk *pblk,
				       struct pblk_line *line)
{
	struct line_emeta *emeta_buf;
	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
	struct pblk_line_meta *lm = &pblk->lm;
	unsigned int lba_list_size = lm->emeta_len[2];
	__le64 *lba_list;
	int ret;

	emeta_buf = pblk_malloc(lm->emeta_len[0],
				l_mg->emeta_alloc_type, GFP_KERNEL);
	emeta_buf = kvmalloc(lm->emeta_len[0], GFP_KERNEL);
	if (!emeta_buf)
		return NULL;

@@ -147,7 +145,7 @@ static __le64 *get_lba_list_from_emeta(struct pblk *pblk,
	if (ret) {
		pblk_err(pblk, "line %d read emeta failed (%d)\n",
				line->id, ret);
		pblk_mfree(emeta_buf, l_mg->emeta_alloc_type);
		kvfree(emeta_buf);
		return NULL;
	}

@@ -161,16 +159,16 @@ static __le64 *get_lba_list_from_emeta(struct pblk *pblk,
	if (ret) {
		pblk_err(pblk, "inconsistent emeta (line %d)\n",
				line->id);
		pblk_mfree(emeta_buf, l_mg->emeta_alloc_type);
		kvfree(emeta_buf);
		return NULL;
	}

	lba_list = pblk_malloc(lba_list_size,
			       l_mg->emeta_alloc_type, GFP_KERNEL);
	lba_list = kvmalloc(lba_list_size, GFP_KERNEL);

	if (lba_list)
		memcpy(lba_list, emeta_to_lbas(pblk, emeta_buf), lba_list_size);

	pblk_mfree(emeta_buf, l_mg->emeta_alloc_type);
	kvfree(emeta_buf);

	return lba_list;
}
@@ -181,7 +179,6 @@ static void pblk_gc_line_prepare_ws(struct work_struct *work)
									ws);
	struct pblk *pblk = line_ws->pblk;
	struct pblk_line *line = line_ws->line;
	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
	struct pblk_line_meta *lm = &pblk->lm;
	struct nvm_tgt_dev *dev = pblk->dev;
	struct nvm_geo *geo = &dev->geo;
@@ -272,7 +269,7 @@ next_rq:
		goto next_rq;

out:
	pblk_mfree(lba_list, l_mg->emeta_alloc_type);
	kvfree(lba_list);
	kfree(line_ws);
	kfree(invalid_bitmap);

@@ -286,7 +283,7 @@ fail_free_gc_data:
fail_free_gc_rq:
	kfree(gc_rq);
fail_free_lba_list:
	pblk_mfree(lba_list, l_mg->emeta_alloc_type);
	kvfree(lba_list);
fail_free_invalid_bitmap:
	kfree(invalid_bitmap);
fail_free_ws:
+10 −28
Original line number Diff line number Diff line
@@ -543,7 +543,7 @@ static void pblk_line_mg_free(struct pblk *pblk)

	for (i = 0; i < PBLK_DATA_LINES; i++) {
		kfree(l_mg->sline_meta[i]);
		pblk_mfree(l_mg->eline_meta[i]->buf, l_mg->emeta_alloc_type);
		kvfree(l_mg->eline_meta[i]->buf);
		kfree(l_mg->eline_meta[i]);
	}

@@ -560,7 +560,7 @@ static void pblk_line_meta_free(struct pblk_line_mgmt *l_mg,
	kfree(line->erase_bitmap);
	kfree(line->chks);

	pblk_mfree(w_err_gc->lba_list, l_mg->emeta_alloc_type);
	kvfree(w_err_gc->lba_list);
	kfree(w_err_gc);
}

@@ -890,21 +890,7 @@ static int pblk_line_mg_init(struct pblk *pblk)
		if (!emeta)
			goto fail_free_emeta;

		if (lm->emeta_len[0] > KMALLOC_MAX_CACHE_SIZE) {
			l_mg->emeta_alloc_type = PBLK_VMALLOC_META;

			emeta->buf = vmalloc(lm->emeta_len[0]);
			if (!emeta->buf) {
				kfree(emeta);
				goto fail_free_emeta;
			}

			emeta->nr_entries = lm->emeta_sec[0];
			l_mg->eline_meta[i] = emeta;
		} else {
			l_mg->emeta_alloc_type = PBLK_KMALLOC_META;

			emeta->buf = kmalloc(lm->emeta_len[0], GFP_KERNEL);
		emeta->buf = kvmalloc(lm->emeta_len[0], GFP_KERNEL);
		if (!emeta->buf) {
			kfree(emeta);
			goto fail_free_emeta;
@@ -913,7 +899,6 @@ static int pblk_line_mg_init(struct pblk *pblk)
		emeta->nr_entries = lm->emeta_sec[0];
		l_mg->eline_meta[i] = emeta;
	}
	}

	for (i = 0; i < l_mg->nr_lines; i++)
		l_mg->vsc_list[i] = cpu_to_le32(EMPTY_ENTRY);
@@ -926,10 +911,7 @@ static int pblk_line_mg_init(struct pblk *pblk)

fail_free_emeta:
	while (--i >= 0) {
		if (l_mg->emeta_alloc_type == PBLK_VMALLOC_META)
			vfree(l_mg->eline_meta[i]->buf);
		else
			kfree(l_mg->eline_meta[i]->buf);
		kvfree(l_mg->eline_meta[i]->buf);
		kfree(l_mg->eline_meta[i]);
	}

+0 −23
Original line number Diff line number Diff line
@@ -481,11 +481,6 @@ struct pblk_line {

#define PBLK_DATA_LINES 4

enum {
	PBLK_KMALLOC_META = 1,
	PBLK_VMALLOC_META = 2,
};

enum {
	PBLK_EMETA_TYPE_HEADER = 1,	/* struct line_emeta first sector */
	PBLK_EMETA_TYPE_LLBA = 2,	/* lba list - type: __le64 */
@@ -521,9 +516,6 @@ struct pblk_line_mgmt {

	__le32 *vsc_list;		/* Valid sector counts for all lines */

	/* Metadata allocation type: VMALLOC | KMALLOC */
	int emeta_alloc_type;

	/* Pre-allocated metadata for data lines */
	struct pblk_smeta *sline_meta[PBLK_DATA_LINES];
	struct pblk_emeta *eline_meta[PBLK_DATA_LINES];
@@ -934,21 +926,6 @@ void pblk_rl_werr_line_out(struct pblk_rl *rl);
int pblk_sysfs_init(struct gendisk *tdisk);
void pblk_sysfs_exit(struct gendisk *tdisk);

static inline void *pblk_malloc(size_t size, int type, gfp_t flags)
{
	if (type == PBLK_KMALLOC_META)
		return kmalloc(size, flags);
	return vmalloc(size);
}

static inline void pblk_mfree(void *ptr, int type)
{
	if (type == PBLK_KMALLOC_META)
		kfree(ptr);
	else
		vfree(ptr);
}

static inline struct nvm_rq *nvm_rq_from_c_ctx(void *c_ctx)
{
	return c_ctx - sizeof(struct nvm_rq);