mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
lightnvm: simplify geometry structure
Currently, the device geometry is stored redundantly in the nvm_id and nvm_geo structures at a device level. Moreover, when instantiating targets on a specific number of LUNs, these structures are replicated and manually modified to fit the instance channel and LUN partitioning. Instead, create a generic geometry around nvm_geo, which can be used by (i) the underlying device to describe the geometry of the whole device, and (ii) instances to describe their geometry independently. Signed-off-by: Javier González <javier@cnexlabs.com> Signed-off-by: Matias Bjørling <mb@lightnvm.io> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
43d4712721
commit
e46f4e4822
12 changed files with 452 additions and 426 deletions
|
@ -50,7 +50,7 @@ struct nvm_id;
|
|||
struct nvm_dev;
|
||||
struct nvm_tgt_dev;
|
||||
|
||||
typedef int (nvm_id_fn)(struct nvm_dev *, struct nvm_id *);
|
||||
typedef int (nvm_id_fn)(struct nvm_dev *);
|
||||
typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, u8 *);
|
||||
typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct ppa_addr *, int, int);
|
||||
typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
|
||||
|
@ -152,62 +152,48 @@ struct nvm_id_lp_tbl {
|
|||
struct nvm_id_lp_mlc mlc;
|
||||
};
|
||||
|
||||
struct nvm_addr_format {
|
||||
u8 ch_offset;
|
||||
struct nvm_addrf_12 {
|
||||
u8 ch_len;
|
||||
u8 lun_offset;
|
||||
u8 lun_len;
|
||||
u8 pln_offset;
|
||||
u8 pln_len;
|
||||
u8 blk_offset;
|
||||
u8 blk_len;
|
||||
u8 pg_offset;
|
||||
u8 pg_len;
|
||||
u8 sect_offset;
|
||||
u8 pln_len;
|
||||
u8 sect_len;
|
||||
|
||||
u8 ch_offset;
|
||||
u8 lun_offset;
|
||||
u8 blk_offset;
|
||||
u8 pg_offset;
|
||||
u8 pln_offset;
|
||||
u8 sect_offset;
|
||||
|
||||
u64 ch_mask;
|
||||
u64 lun_mask;
|
||||
u64 blk_mask;
|
||||
u64 pg_mask;
|
||||
u64 pln_mask;
|
||||
u64 sec_mask;
|
||||
};
|
||||
|
||||
struct nvm_id {
|
||||
u8 ver_id;
|
||||
u8 vmnt;
|
||||
u32 cap;
|
||||
u32 dom;
|
||||
struct nvm_addrf {
|
||||
u8 ch_len;
|
||||
u8 lun_len;
|
||||
u8 chk_len;
|
||||
u8 sec_len;
|
||||
u8 rsv_len[2];
|
||||
|
||||
struct nvm_addr_format ppaf;
|
||||
u8 ch_offset;
|
||||
u8 lun_offset;
|
||||
u8 chk_offset;
|
||||
u8 sec_offset;
|
||||
u8 rsv_off[2];
|
||||
|
||||
u8 num_ch;
|
||||
u8 num_lun;
|
||||
u16 num_chk;
|
||||
u16 clba;
|
||||
u16 csecs;
|
||||
u16 sos;
|
||||
|
||||
u32 ws_min;
|
||||
u32 ws_opt;
|
||||
u32 mw_cunits;
|
||||
|
||||
u32 trdt;
|
||||
u32 trdm;
|
||||
u32 tprt;
|
||||
u32 tprm;
|
||||
u32 tbet;
|
||||
u32 tbem;
|
||||
u32 mpos;
|
||||
u32 mccap;
|
||||
u16 cpar;
|
||||
|
||||
/* calculated values */
|
||||
u16 ws_seq;
|
||||
u16 ws_per_chk;
|
||||
|
||||
/* 1.2 compatibility */
|
||||
u8 mtype;
|
||||
u8 fmtype;
|
||||
|
||||
u8 num_pln;
|
||||
u16 num_pg;
|
||||
u16 fpg_sz;
|
||||
} __packed;
|
||||
u64 ch_mask;
|
||||
u64 lun_mask;
|
||||
u64 chk_mask;
|
||||
u64 sec_mask;
|
||||
u64 rsv_mask[2];
|
||||
};
|
||||
|
||||
struct nvm_target {
|
||||
struct list_head list;
|
||||
|
@ -274,36 +260,63 @@ enum {
|
|||
NVM_BLK_ST_BAD = 0x8, /* Bad block */
|
||||
};
|
||||
|
||||
|
||||
/* Device generic information */
|
||||
/* Instance geometry */
|
||||
struct nvm_geo {
|
||||
/* generic geometry */
|
||||
/* device reported version */
|
||||
u8 ver_id;
|
||||
|
||||
/* instance specific geometry */
|
||||
int nr_chnls;
|
||||
int all_luns; /* across channels */
|
||||
int nr_luns; /* per channel */
|
||||
int nr_chks; /* per lun */
|
||||
int nr_luns; /* per channel */
|
||||
|
||||
int sec_size;
|
||||
int oob_size;
|
||||
int mccap;
|
||||
/* calculated values */
|
||||
int all_luns; /* across channels */
|
||||
int all_chunks; /* across channels */
|
||||
|
||||
int sec_per_chk;
|
||||
int sec_per_lun;
|
||||
int op; /* over-provision in instance */
|
||||
|
||||
int ws_min;
|
||||
int ws_opt;
|
||||
int ws_seq;
|
||||
int ws_per_chk;
|
||||
sector_t total_secs; /* across channels */
|
||||
|
||||
int op;
|
||||
/* chunk geometry */
|
||||
u32 nr_chks; /* chunks per lun */
|
||||
u32 clba; /* sectors per chunk */
|
||||
u16 csecs; /* sector size */
|
||||
u16 sos; /* out-of-band area size */
|
||||
|
||||
struct nvm_addr_format ppaf;
|
||||
/* device write constrains */
|
||||
u32 ws_min; /* minimum write size */
|
||||
u32 ws_opt; /* optimal write size */
|
||||
u32 mw_cunits; /* distance required for successful read */
|
||||
|
||||
/* Legacy 1.2 specific geometry */
|
||||
int plane_mode; /* drive device in single, double or quad mode */
|
||||
int nr_planes;
|
||||
int sec_per_pg; /* only sectors for a single page */
|
||||
int sec_per_pl; /* all sectors across planes */
|
||||
/* device capabilities */
|
||||
u32 mccap;
|
||||
|
||||
/* device timings */
|
||||
u32 trdt; /* Avg. Tread (ns) */
|
||||
u32 trdm; /* Max Tread (ns) */
|
||||
u32 tprt; /* Avg. Tprog (ns) */
|
||||
u32 tprm; /* Max Tprog (ns) */
|
||||
u32 tbet; /* Avg. Terase (ns) */
|
||||
u32 tbem; /* Max Terase (ns) */
|
||||
|
||||
/* generic address format */
|
||||
struct nvm_addrf addrf;
|
||||
|
||||
/* 1.2 compatibility */
|
||||
u8 vmnt;
|
||||
u32 cap;
|
||||
u32 dom;
|
||||
|
||||
u8 mtype;
|
||||
u8 fmtype;
|
||||
|
||||
u16 cpar;
|
||||
u32 mpos;
|
||||
|
||||
u8 num_pln;
|
||||
u8 plane_mode;
|
||||
u16 num_pg;
|
||||
u16 fpg_sz;
|
||||
};
|
||||
|
||||
/* sub-device structure */
|
||||
|
@ -314,9 +327,6 @@ struct nvm_tgt_dev {
|
|||
/* Base ppas for target LUNs */
|
||||
struct ppa_addr *luns;
|
||||
|
||||
sector_t total_secs;
|
||||
|
||||
struct nvm_id identity;
|
||||
struct request_queue *q;
|
||||
|
||||
struct nvm_dev *parent;
|
||||
|
@ -331,13 +341,9 @@ struct nvm_dev {
|
|||
/* Device information */
|
||||
struct nvm_geo geo;
|
||||
|
||||
unsigned long total_secs;
|
||||
|
||||
unsigned long *lun_map;
|
||||
void *dma_pool;
|
||||
|
||||
struct nvm_id identity;
|
||||
|
||||
/* Backend device */
|
||||
struct request_queue *q;
|
||||
char name[DISK_NAME_LEN];
|
||||
|
@ -357,14 +363,15 @@ static inline struct ppa_addr generic_to_dev_addr(struct nvm_tgt_dev *tgt_dev,
|
|||
struct ppa_addr r)
|
||||
{
|
||||
struct nvm_geo *geo = &tgt_dev->geo;
|
||||
struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&geo->addrf;
|
||||
struct ppa_addr l;
|
||||
|
||||
l.ppa = ((u64)r.g.blk) << geo->ppaf.blk_offset;
|
||||
l.ppa |= ((u64)r.g.pg) << geo->ppaf.pg_offset;
|
||||
l.ppa |= ((u64)r.g.sec) << geo->ppaf.sect_offset;
|
||||
l.ppa |= ((u64)r.g.pl) << geo->ppaf.pln_offset;
|
||||
l.ppa |= ((u64)r.g.lun) << geo->ppaf.lun_offset;
|
||||
l.ppa |= ((u64)r.g.ch) << geo->ppaf.ch_offset;
|
||||
l.ppa = ((u64)r.g.ch) << ppaf->ch_offset;
|
||||
l.ppa |= ((u64)r.g.lun) << ppaf->lun_offset;
|
||||
l.ppa |= ((u64)r.g.blk) << ppaf->blk_offset;
|
||||
l.ppa |= ((u64)r.g.pg) << ppaf->pg_offset;
|
||||
l.ppa |= ((u64)r.g.pl) << ppaf->pln_offset;
|
||||
l.ppa |= ((u64)r.g.sec) << ppaf->sect_offset;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
@ -373,24 +380,17 @@ static inline struct ppa_addr dev_to_generic_addr(struct nvm_tgt_dev *tgt_dev,
|
|||
struct ppa_addr r)
|
||||
{
|
||||
struct nvm_geo *geo = &tgt_dev->geo;
|
||||
struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&geo->addrf;
|
||||
struct ppa_addr l;
|
||||
|
||||
l.ppa = 0;
|
||||
/*
|
||||
* (r.ppa << X offset) & X len bitmask. X eq. blk, pg, etc.
|
||||
*/
|
||||
l.g.blk = (r.ppa >> geo->ppaf.blk_offset) &
|
||||
(((1 << geo->ppaf.blk_len) - 1));
|
||||
l.g.pg |= (r.ppa >> geo->ppaf.pg_offset) &
|
||||
(((1 << geo->ppaf.pg_len) - 1));
|
||||
l.g.sec |= (r.ppa >> geo->ppaf.sect_offset) &
|
||||
(((1 << geo->ppaf.sect_len) - 1));
|
||||
l.g.pl |= (r.ppa >> geo->ppaf.pln_offset) &
|
||||
(((1 << geo->ppaf.pln_len) - 1));
|
||||
l.g.lun |= (r.ppa >> geo->ppaf.lun_offset) &
|
||||
(((1 << geo->ppaf.lun_len) - 1));
|
||||
l.g.ch |= (r.ppa >> geo->ppaf.ch_offset) &
|
||||
(((1 << geo->ppaf.ch_len) - 1));
|
||||
|
||||
l.g.ch = (r.ppa & ppaf->ch_mask) >> ppaf->ch_offset;
|
||||
l.g.lun = (r.ppa & ppaf->lun_mask) >> ppaf->lun_offset;
|
||||
l.g.blk = (r.ppa & ppaf->blk_mask) >> ppaf->blk_offset;
|
||||
l.g.pg = (r.ppa & ppaf->pg_mask) >> ppaf->pg_offset;
|
||||
l.g.pl = (r.ppa & ppaf->pln_mask) >> ppaf->pln_offset;
|
||||
l.g.sec = (r.ppa & ppaf->sec_mask) >> ppaf->sect_offset;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue