summaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm/pblk.h
diff options
context:
space:
mode:
authorJavier González <javier@cnexlabs.com>2018-03-30 00:05:10 +0200
committerJens Axboe <axboe@kernel.dk>2018-03-29 17:29:09 -0600
commite46f4e4822bdecf9bcbc2e71b2a3ae7f37464a2d (patch)
treef69895ed8945edc7be7e80186ad7b4568d367db5 /drivers/lightnvm/pblk.h
parent43d47127219de1dd674b917c1835baa14c4c1768 (diff)
downloadlinux-stable-e46f4e4822bdecf9bcbc2e71b2a3ae7f37464a2d.tar.gz
linux-stable-e46f4e4822bdecf9bcbc2e71b2a3ae7f37464a2d.tar.bz2
linux-stable-e46f4e4822bdecf9bcbc2e71b2a3ae7f37464a2d.zip
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>
Diffstat (limited to 'drivers/lightnvm/pblk.h')
-rw-r--r--drivers/lightnvm/pblk.h83
1 files changed, 33 insertions, 50 deletions
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index f0309d8172c0..898c4e49f77d 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -551,21 +551,6 @@ struct pblk_line_meta {
unsigned int meta_distance; /* Distance between data and metadata */
};
-struct pblk_addr_format {
- u64 ch_mask;
- u64 lun_mask;
- u64 pln_mask;
- u64 blk_mask;
- u64 pg_mask;
- u64 sec_mask;
- u8 ch_offset;
- u8 lun_offset;
- u8 pln_offset;
- u8 blk_offset;
- u8 pg_offset;
- u8 sec_offset;
-};
-
enum {
PBLK_STATE_RUNNING = 0,
PBLK_STATE_STOPPING = 1,
@@ -585,8 +570,8 @@ struct pblk {
struct pblk_line_mgmt l_mg; /* Line management */
struct pblk_line_meta lm; /* Line metadata */
+ struct nvm_addrf ppaf;
int ppaf_bitsize;
- struct pblk_addr_format ppaf;
struct pblk_rb rwb;
@@ -941,14 +926,12 @@ static inline int pblk_line_vsc(struct pblk_line *line)
return le32_to_cpu(*line->vsc);
}
-#define NVM_MEM_PAGE_WRITE (8)
-
static inline int pblk_pad_distance(struct pblk *pblk)
{
struct nvm_tgt_dev *dev = pblk->dev;
struct nvm_geo *geo = &dev->geo;
- return NVM_MEM_PAGE_WRITE * geo->all_luns * geo->sec_per_pl;
+ return geo->mw_cunits * geo->all_luns * geo->ws_opt;
}
static inline int pblk_ppa_to_line(struct ppa_addr p)
@@ -964,15 +947,16 @@ static inline int pblk_ppa_to_pos(struct nvm_geo *geo, struct ppa_addr p)
static inline struct ppa_addr addr_to_gen_ppa(struct pblk *pblk, u64 paddr,
u64 line_id)
{
+ struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&pblk->ppaf;
struct ppa_addr ppa;
ppa.ppa = 0;
ppa.g.blk = line_id;
- ppa.g.pg = (paddr & pblk->ppaf.pg_mask) >> pblk->ppaf.pg_offset;
- ppa.g.lun = (paddr & pblk->ppaf.lun_mask) >> pblk->ppaf.lun_offset;
- ppa.g.ch = (paddr & pblk->ppaf.ch_mask) >> pblk->ppaf.ch_offset;
- ppa.g.pl = (paddr & pblk->ppaf.pln_mask) >> pblk->ppaf.pln_offset;
- ppa.g.sec = (paddr & pblk->ppaf.sec_mask) >> pblk->ppaf.sec_offset;
+ ppa.g.pg = (paddr & ppaf->pg_mask) >> ppaf->pg_offset;
+ ppa.g.lun = (paddr & ppaf->lun_mask) >> ppaf->lun_offset;
+ ppa.g.ch = (paddr & ppaf->ch_mask) >> ppaf->ch_offset;
+ ppa.g.pl = (paddr & ppaf->pln_mask) >> ppaf->pln_offset;
+ ppa.g.sec = (paddr & ppaf->sec_mask) >> ppaf->sect_offset;
return ppa;
}
@@ -980,13 +964,14 @@ static inline struct ppa_addr addr_to_gen_ppa(struct pblk *pblk, u64 paddr,
static inline u64 pblk_dev_ppa_to_line_addr(struct pblk *pblk,
struct ppa_addr p)
{
+ struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&pblk->ppaf;
u64 paddr;
- paddr = (u64)p.g.pg << pblk->ppaf.pg_offset;
- paddr |= (u64)p.g.lun << pblk->ppaf.lun_offset;
- paddr |= (u64)p.g.ch << pblk->ppaf.ch_offset;
- paddr |= (u64)p.g.pl << pblk->ppaf.pln_offset;
- paddr |= (u64)p.g.sec << pblk->ppaf.sec_offset;
+ paddr = (u64)p.g.ch << ppaf->ch_offset;
+ paddr |= (u64)p.g.lun << ppaf->lun_offset;
+ paddr |= (u64)p.g.pg << ppaf->pg_offset;
+ paddr |= (u64)p.g.pl << ppaf->pln_offset;
+ paddr |= (u64)p.g.sec << ppaf->sect_offset;
return paddr;
}
@@ -1003,18 +988,14 @@ static inline struct ppa_addr pblk_ppa32_to_ppa64(struct pblk *pblk, u32 ppa32)
ppa64.c.line = ppa32 & ((~0U) >> 1);
ppa64.c.is_cached = 1;
} else {
- ppa64.g.blk = (ppa32 & pblk->ppaf.blk_mask) >>
- pblk->ppaf.blk_offset;
- ppa64.g.pg = (ppa32 & pblk->ppaf.pg_mask) >>
- pblk->ppaf.pg_offset;
- ppa64.g.lun = (ppa32 & pblk->ppaf.lun_mask) >>
- pblk->ppaf.lun_offset;
- ppa64.g.ch = (ppa32 & pblk->ppaf.ch_mask) >>
- pblk->ppaf.ch_offset;
- ppa64.g.pl = (ppa32 & pblk->ppaf.pln_mask) >>
- pblk->ppaf.pln_offset;
- ppa64.g.sec = (ppa32 & pblk->ppaf.sec_mask) >>
- pblk->ppaf.sec_offset;
+ struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&pblk->ppaf;
+
+ ppa64.g.ch = (ppa32 & ppaf->ch_mask) >> ppaf->ch_offset;
+ ppa64.g.lun = (ppa32 & ppaf->lun_mask) >> ppaf->lun_offset;
+ ppa64.g.blk = (ppa32 & ppaf->blk_mask) >> ppaf->blk_offset;
+ ppa64.g.pg = (ppa32 & ppaf->pg_mask) >> ppaf->pg_offset;
+ ppa64.g.pl = (ppa32 & ppaf->pln_mask) >> ppaf->pln_offset;
+ ppa64.g.sec = (ppa32 & ppaf->sec_mask) >> ppaf->sect_offset;
}
return ppa64;
@@ -1030,12 +1011,14 @@ static inline u32 pblk_ppa64_to_ppa32(struct pblk *pblk, struct ppa_addr ppa64)
ppa32 |= ppa64.c.line;
ppa32 |= 1U << 31;
} else {
- ppa32 |= ppa64.g.blk << pblk->ppaf.blk_offset;
- ppa32 |= ppa64.g.pg << pblk->ppaf.pg_offset;
- ppa32 |= ppa64.g.lun << pblk->ppaf.lun_offset;
- ppa32 |= ppa64.g.ch << pblk->ppaf.ch_offset;
- ppa32 |= ppa64.g.pl << pblk->ppaf.pln_offset;
- ppa32 |= ppa64.g.sec << pblk->ppaf.sec_offset;
+ struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&pblk->ppaf;
+
+ ppa32 |= ppa64.g.ch << ppaf->ch_offset;
+ ppa32 |= ppa64.g.lun << ppaf->lun_offset;
+ ppa32 |= ppa64.g.blk << ppaf->blk_offset;
+ ppa32 |= ppa64.g.pg << ppaf->pg_offset;
+ ppa32 |= ppa64.g.pl << ppaf->pln_offset;
+ ppa32 |= ppa64.g.sec << ppaf->sect_offset;
}
return ppa32;
@@ -1229,10 +1212,10 @@ static inline int pblk_boundary_ppa_checks(struct nvm_tgt_dev *tgt_dev,
if (!ppa->c.is_cached &&
ppa->g.ch < geo->nr_chnls &&
ppa->g.lun < geo->nr_luns &&
- ppa->g.pl < geo->nr_planes &&
+ ppa->g.pl < geo->num_pln &&
ppa->g.blk < geo->nr_chks &&
- ppa->g.pg < geo->ws_per_chk &&
- ppa->g.sec < geo->sec_per_pg)
+ ppa->g.pg < geo->num_pg &&
+ ppa->g.sec < geo->ws_min)
continue;
print_ppa(ppa, "boundary", i);