Commit ade69e24 authored by Matias Bjørling's avatar Matias Bjørling Committed by Jens Axboe

lightnvm: merge gennvm with core

For the first iteration of Open-Channel SSDs, it was anticipated that
there could be various media managers on top of an open-channel SSD,
such to allow vendors to plug in their own host-side FTLs, without the
media manager in between.

Now that an Open-Channel SSD is exposed as a traditional block device,
there is no longer a need for this. Therefore lets merge the gennvm code
with core and simplify the stack.
Signed-off-by: default avatarMatias Bjørling <matias@cnexlabs.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 400f73b2
......@@ -26,15 +26,6 @@ config NVM_DEBUG
It is required to create/remove targets without IOCTLs.
config NVM_GENNVM
tristate "General Non-Volatile Memory Manager for Open-Channel SSDs"
---help---
Non-volatile memory media manager for Open-Channel SSDs that implements
physical media metadata management and block provisioning API.
This is the standard media manager for using Open-Channel SSDs, and
required for targets to be instantiated.
config NVM_RRPC
tristate "Round-robin Hybrid Open-Channel SSD target"
---help---
......
......@@ -2,6 +2,5 @@
# Makefile for Open-Channel SSDs.
#
obj-$(CONFIG_NVM) := core.o sysblk.o
obj-$(CONFIG_NVM_GENNVM) += gennvm.o
obj-$(CONFIG_NVM) := core.o
obj-$(CONFIG_NVM_RRPC) += rrpc.o
This diff is collapsed.
This diff is collapsed.
/*
* Copyright: Matias Bjorling <mb@bjorling.me>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
*/
#ifndef GENNVM_H_
#define GENNVM_H_
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/lightnvm.h>
struct gen_dev {
struct nvm_dev *dev;
int nr_luns;
struct list_head area_list;
struct mutex lock;
struct list_head targets;
};
/* Map between virtual and physical channel and lun */
struct gen_ch_map {
int ch_off;
int nr_luns;
int *lun_offs;
};
struct gen_dev_map {
struct gen_ch_map *chnls;
int nr_chnls;
};
struct gen_area {
struct list_head list;
sector_t begin;
sector_t end; /* end is excluded */
};
static inline void *ch_map_to_lun_offs(struct gen_ch_map *ch_map)
{
return ch_map + 1;
}
typedef int (gen_trans_fn)(struct nvm_tgt_dev *, struct ppa_addr *);
#define gen_for_each_lun(bm, lun, i) \
for ((i) = 0, lun = &(bm)->luns[0]; \
(i) < (bm)->nr_luns; (i)++, lun = &(bm)->luns[(i)])
#endif /* GENNVM_H_ */
This diff is collapsed.
......@@ -372,7 +372,7 @@ static int nvme_nvm_get_l2p_tbl(struct nvm_dev *nvmdev, u64 slba, u32 nlb,
}
/* Transform physical address to target address space */
nvmdev->mt->part_to_tgt(nvmdev, entries, cmd_nlb);
nvm_part_to_tgt(nvmdev, entries, cmd_nlb);
if (update_l2p(cmd_slba, cmd_nlb, entries, priv)) {
ret = -EINTR;
......@@ -633,10 +633,9 @@ static ssize_t nvm_dev_attr_show(struct device *dev,
return scnprintf(page, PAGE_SIZE, "%u\n", id->cap);
} else if (strcmp(attr->name, "device_mode") == 0) {
return scnprintf(page, PAGE_SIZE, "%u\n", id->dom);
/* kept for compatibility */
} else if (strcmp(attr->name, "media_manager") == 0) {
if (!ndev->mt)
return scnprintf(page, PAGE_SIZE, "%s\n", "none");
return scnprintf(page, PAGE_SIZE, "%s\n", ndev->mt->name);
return scnprintf(page, PAGE_SIZE, "%s\n", "gennvm");
} else if (strcmp(attr->name, "ppa_format") == 0) {
return scnprintf(page, PAGE_SIZE,
"0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
......
......@@ -80,8 +80,6 @@ struct nvm_dev_ops {
unsigned int max_phys_sect;
};
#ifdef CONFIG_NVM
#include <linux/blkdev.h>
......@@ -272,15 +270,6 @@ enum {
NVM_BLK_ST_BAD = 0x8, /* Bad block */
};
/* system block cpu representation */
struct nvm_sb_info {
unsigned long seqnr;
unsigned long erase_cnt;
unsigned int version;
char mmtype[NVM_MMTYPE_LEN];
struct ppa_addr fs_ppa;
};
/* Device generic information */
struct nvm_geo {
int nr_chnls;
......@@ -308,6 +297,7 @@ struct nvm_geo {
int sec_per_lun;
};
/* sub-device structure */
struct nvm_tgt_dev {
/* Device information */
struct nvm_geo geo;
......@@ -329,17 +319,10 @@ struct nvm_dev {
struct list_head devices;
/* Media manager */
struct nvmm_type *mt;
void *mp;
/* System blocks */
struct nvm_sb_info sb;
/* Device information */
struct nvm_geo geo;
/* lower page table */
/* lower page table */
int lps_per_blk;
int *lptbl;
......@@ -359,6 +342,10 @@ struct nvm_dev {
struct mutex mlock;
spinlock_t lock;
/* target management */
struct list_head area_list;
struct list_head targets;
};
static inline struct ppa_addr linear_to_generic_addr(struct nvm_geo *geo,
......@@ -452,11 +439,6 @@ static inline int ppa_cmp_blk(struct ppa_addr ppa1, struct ppa_addr ppa2)
(ppa1.g.blk == ppa2.g.blk));
}
static inline int ppa_to_slc(struct nvm_dev *dev, int slc_pg)
{
return dev->lptbl[slc_pg];
}
typedef blk_qc_t (nvm_tgt_make_rq_fn)(struct request_queue *, struct bio *);
typedef sector_t (nvm_tgt_capacity_fn)(void *);
typedef void *(nvm_tgt_init_fn)(struct nvm_tgt_dev *, struct gendisk *);
......@@ -487,49 +469,6 @@ extern void nvm_unregister_tgt_type(struct nvm_tgt_type *);
extern void *nvm_dev_dma_alloc(struct nvm_dev *, gfp_t, dma_addr_t *);
extern void nvm_dev_dma_free(struct nvm_dev *, void *, dma_addr_t);
typedef int (nvmm_register_fn)(struct nvm_dev *);
typedef void (nvmm_unregister_fn)(struct nvm_dev *);
typedef int (nvmm_create_tgt_fn)(struct nvm_dev *, struct nvm_ioctl_create *);
typedef int (nvmm_remove_tgt_fn)(struct nvm_dev *, struct nvm_ioctl_remove *);
typedef int (nvmm_submit_io_fn)(struct nvm_tgt_dev *, struct nvm_rq *);
typedef int (nvmm_erase_blk_fn)(struct nvm_tgt_dev *, struct ppa_addr *, int);
typedef int (nvmm_get_area_fn)(struct nvm_dev *, sector_t *, sector_t);
typedef void (nvmm_put_area_fn)(struct nvm_dev *, sector_t);
typedef struct ppa_addr (nvmm_trans_ppa_fn)(struct nvm_tgt_dev *,
struct ppa_addr, int);
typedef void (nvmm_part_to_tgt_fn)(struct nvm_dev *, sector_t*, int);
enum {
TRANS_TGT_TO_DEV = 0x0,
TRANS_DEV_TO_TGT = 0x1,
};
struct nvmm_type {
const char *name;
unsigned int version[3];
nvmm_register_fn *register_mgr;
nvmm_unregister_fn *unregister_mgr;
nvmm_create_tgt_fn *create_tgt;
nvmm_remove_tgt_fn *remove_tgt;
nvmm_submit_io_fn *submit_io;
nvmm_erase_blk_fn *erase_blk;
nvmm_get_area_fn *get_area;
nvmm_put_area_fn *put_area;
nvmm_trans_ppa_fn *trans_ppa;
nvmm_part_to_tgt_fn *part_to_tgt;
struct list_head list;
};
extern int nvm_register_mgr(struct nvmm_type *);
extern void nvm_unregister_mgr(struct nvmm_type *);
extern struct nvm_dev *nvm_alloc_dev(int);
extern int nvm_register(struct nvm_dev *);
extern void nvm_unregister(struct nvm_dev *);
......@@ -559,31 +498,9 @@ extern int nvm_bb_tbl_fold(struct nvm_dev *, u8 *, int);
extern int nvm_get_bb_tbl(struct nvm_dev *, struct ppa_addr, u8 *);
extern int nvm_get_tgt_bb_tbl(struct nvm_tgt_dev *, struct ppa_addr, u8 *);
/* sysblk.c */
#define NVM_SYSBLK_MAGIC 0x4E564D53 /* "NVMS" */
/* system block on disk representation */
struct nvm_system_block {
__be32 magic; /* magic signature */
__be32 seqnr; /* sequence number */
__be32 erase_cnt; /* erase count */
__be16 version; /* version number */
u8 mmtype[NVM_MMTYPE_LEN]; /* media manager name */
__be64 fs_ppa; /* PPA for media manager
* superblock */
};
extern int nvm_get_sysblock(struct nvm_dev *, struct nvm_sb_info *);
extern int nvm_update_sysblock(struct nvm_dev *, struct nvm_sb_info *);
extern int nvm_init_sysblock(struct nvm_dev *, struct nvm_sb_info *);
extern int nvm_dev_factory(struct nvm_dev *, int flags);
#define nvm_for_each_lun_ppa(geo, ppa, chid, lunid) \
for ((chid) = 0, (ppa).ppa = 0; (chid) < (geo)->nr_chnls; \
(chid)++, (ppa).g.ch = (chid)) \
for ((lunid) = 0; (lunid) < (geo)->luns_per_chnl; \
(lunid)++, (ppa).g.lun = (lunid))
extern void nvm_part_to_tgt(struct nvm_dev *, sector_t *, int);
#else /* CONFIG_NVM */
struct nvm_dev_ops;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment