mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
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: Matias Bjørling <matias@cnexlabs.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
committed by
Jens Axboe
parent
400f73b23f
commit
ade69e2432
@@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* 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_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user