From: m@bjorling.me (Matias Bjorling)
Subject: [PATCH v3 7/7] nvme: LightNVM support
Date: Tue, 05 May 2015 20:51:03 +0200 [thread overview]
Message-ID: <55491117.6080902@bjorling.me> (raw)
In-Reply-To: <1429712816-10336-8-git-send-email-m@bjorling.me>
> --- a/drivers/block/nvme-core.c
> +++ b/drivers/block/nvme-core.c
> @@ -39,6 +39,7 @@
> #include <linux/slab.h>
> #include <linux/t10-pi.h>
> #include <linux/types.h>
> +#include <linux/lightnvm.h>
> #include <scsi/sg.h>
> #include <asm-generic/io-64-nonatomic-lo-hi.h>
>
> @@ -134,6 +135,11 @@ static inline void _nvme_check_size(void)
> BUILD_BUG_ON(sizeof(struct nvme_id_ns) != 4096);
> BUILD_BUG_ON(sizeof(struct nvme_lba_range_type) != 64);
> BUILD_BUG_ON(sizeof(struct nvme_smart_log) != 512);
> + BUILD_BUG_ON(sizeof(struct nvme_nvm_hb_rw) != 64);
> + BUILD_BUG_ON(sizeof(struct nvme_nvm_l2ptbl) != 64);
> + BUILD_BUG_ON(sizeof(struct nvme_nvm_bbtbl) != 64);
> + BUILD_BUG_ON(sizeof(struct nvme_nvm_set_resp) != 64);
> + BUILD_BUG_ON(sizeof(struct nvme_nvm_erase_blk) != 64);
> }
Keith, should I move the lightnvm definition into the nvme-lightnvm.c
file as well?
> static int nvme_submit_iod(struct nvme_queue *nvmeq, struct nvme_iod *iod,
> struct nvme_ns *ns)
> {
> @@ -888,12 +937,29 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
> }
> }
>
> + if (ns->type == NVME_NS_NVM) {
> + switch (nvm_prep_rq(req, &iod->nvm_rqdata)) {
> + case NVM_PREP_DONE:
> + goto done_cmd;
> + case NVM_PREP_REQUEUE:
> + blk_mq_requeue_request(req);
> + blk_mq_kick_requeue_list(hctx->queue);
> + goto done_cmd;
> + case NVM_PREP_BUSY:
> + goto retry_cmd;
> + case NVM_PREP_ERROR:
> + goto error_cmd;
> + }
> + }
> +
Regarding the prep part. I'm not 100% satisfied with it. I can refactor
it into a function and clean it up. There is still a need for the
jumping, as it depends on the iod.
Another possibility is to only call it on lightnvm capable controllers.
With its own queue_rq function. It would be global for all namespaces.
The flow would then look like
register -> nvme_nvm_queue_rq
nvme_nvm_queue_rq()
if (ns is normal command set)
return nvme_queue_rq();
__nvme_nvm_queue_rq()
Any thoughts?
> index aef9a81..5292906 100644
> --- a/include/uapi/linux/nvme.h
> +++ b/include/uapi/linux/nvme.h
> @@ -85,6 +85,35 @@ struct nvme_id_ctrl {
> __u8 vs[1024];
> };
>
> +struct nvme_nvm_id_chnl {
> + __le64 laddr_begin;
> + __le64 laddr_end;
> + __le32 oob_size;
> + __le32 queue_size;
> + __le32 gran_read;
> + __le32 gran_write;
> + __le32 gran_erase;
> + __le32 t_r;
> + __le32 t_sqr;
> + __le32 t_w;
> + __le32 t_sqw;
> + __le32 t_e;
> + __le16 chnl_parallelism;
> + __u8 io_sched;
> + __u8 reserved[133];
> +} __attribute__((packed));
> +
> +struct nvme_nvm_id {
> + __u8 ver_id;
> + __u8 nvm_type;
> + __le16 nchannels;
> + __u8 reserved[252];
> + struct nvme_nvm_id_chnl chnls[];
> +} __attribute__((packed));
> +
> +#define NVME_NVM_CHNLS_PR_REQ ((4096U - sizeof(struct nvme_nvm_id)) \
> + / sizeof(struct nvme_nvm_id_chnl))
> +
> enum {
> NVME_CTRL_ONCS_COMPARE = 1 << 0,
> NVME_CTRL_ONCS_WRITE_UNCORRECTABLE = 1 << 1,
> @@ -130,6 +159,7 @@ struct nvme_id_ns {
>
> enum {
> NVME_NS_FEAT_THIN = 1 << 0,
> + NVME_NS_FEAT_NVM = 1 << 3,
> NVME_NS_FLBAS_LBA_MASK = 0xf,
> NVME_NS_FLBAS_META_EXT = 0x10,
> NVME_LBAF_RP_BEST = 0,
> @@ -146,6 +176,8 @@ enum {
> NVME_NS_DPS_PI_TYPE1 = 1,
> NVME_NS_DPS_PI_TYPE2 = 2,
> NVME_NS_DPS_PI_TYPE3 = 3,
> +
> + NVME_NS_NVM = 1,
> };
>
> struct nvme_smart_log {
> @@ -229,6 +261,12 @@ enum nvme_opcode {
> nvme_cmd_resv_report = 0x0e,
> nvme_cmd_resv_acquire = 0x11,
> nvme_cmd_resv_release = 0x15,
> +
> + nvme_nvm_cmd_hb_write = 0x81,
> + nvme_nvm_cmd_hb_read = 0x02,
> + nvme_nvm_cmd_phys_write = 0x91,
> + nvme_nvm_cmd_phys_read = 0x92,
> + nvme_nvm_cmd_erase = 0x90,
> };
>
> struct nvme_common_command {
> @@ -261,6 +299,74 @@ struct nvme_rw_command {
> __le16 appmask;
> };
>
> +struct nvme_nvm_hb_rw {
> + __u8 opcode;
> + __u8 flags;
> + __u16 command_id;
> + __le32 nsid;
> + __u64 rsvd2;
> + __le64 metadata;
> + __le64 prp1;
> + __le64 prp2;
> + __le64 slba;
> + __le16 length;
> + __le16 control;
> + __le32 dsmgmt;
> + __le64 phys_addr;
> +};
> +
> +struct nvme_nvm_l2ptbl {
> + __u8 opcode;
> + __u8 flags;
> + __u16 command_id;
> + __le32 nsid;
> + __le32 cdw2[4];
> + __le64 prp1;
> + __le64 prp2;
> + __le64 slba;
> + __le32 nlb;
> + __u16 prp1_len;
> + __le16 cdw14[5];
> +};
> +
> +struct nvme_nvm_bbtbl {
> + __u8 opcode;
> + __u8 flags;
> + __u16 command_id;
> + __le32 nsid;
> + __u64 rsvd[2];
> + __le64 prp1;
> + __le64 prp2;
> + __le32 prp1_len;
> + __le32 prp2_len;
> + __le32 lbb;
> + __u32 rsvd11[3];
> +};
> +
> +struct nvme_nvm_set_resp {
> + __u8 opcode;
> + __u8 flags;
> + __u16 command_id;
> + __le32 nsid;
> + __u64 rsvd[2];
> + __le64 prp1;
> + __le64 prp2;
> + __le64 resp;
> + __u32 rsvd11[4];
> +};
> +
> +struct nvme_nvm_erase_blk {
> + __u8 opcode;
> + __u8 flags;
> + __u16 command_id;
> + __le32 nsid;
> + __u64 rsvd[2];
> + __le64 prp1;
> + __le64 prp2;
> + __le64 blk_addr;
> + __u32 rsvd11[4];
> +};
> +
> enum {
> NVME_RW_LR = 1 << 15,
> NVME_RW_FUA = 1 << 14,
> @@ -328,6 +434,13 @@ enum nvme_admin_opcode {
> nvme_admin_format_nvm = 0x80,
> nvme_admin_security_send = 0x81,
> nvme_admin_security_recv = 0x82,
> +
> + nvme_nvm_admin_identify = 0xe2,
> + nvme_nvm_admin_get_features = 0xe6,
> + nvme_nvm_admin_set_resp = 0xe5,
> + nvme_nvm_admin_get_l2p_tbl = 0xea,
> + nvme_nvm_admin_get_bb_tbl = 0xf2,
> + nvme_nvm_admin_set_bb_tbl = 0xf1,
> };
>
> enum {
> @@ -457,6 +570,18 @@ struct nvme_format_cmd {
> __u32 rsvd11[5];
> };
>
> +struct nvme_nvm_identify {
> + __u8 opcode;
> + __u8 flags;
> + __u16 command_id;
> + __le32 nsid;
> + __u64 rsvd[2];
> + __le64 prp1;
> + __le64 prp2;
> + __le32 cns;
> + __u32 rsvd11[5];
> +};
> +
> struct nvme_command {
> union {
> struct nvme_common_command common;
> @@ -470,6 +595,13 @@ struct nvme_command {
> struct nvme_format_cmd format;
> struct nvme_dsm_cmd dsm;
> struct nvme_abort_cmd abort;
> + struct nvme_nvm_identify nvm_identify;
> + struct nvme_nvm_hb_rw nvm_hb_rw;
> + struct nvme_nvm_l2ptbl nvm_l2p;
> + struct nvme_nvm_bbtbl nvm_get_bb;
> + struct nvme_nvm_bbtbl nvm_set_bb;
> + struct nvme_nvm_set_resp nvm_resp;
> + struct nvme_nvm_erase_blk nvm_erase;
> };
> };
>
All these could be moved into the nvme-lightnvm.c file. Taking the
previous discussion with Christoph regarding exposing user headers with
the protocol. It maybe shouldn't be exposed.
Should I push it into nvme-lightnvm.h? (there is still a need for
struct nvme_nvm_hb_rw. The other defs can be moved)
Anything else?
WARNING: multiple messages have this Message-ID (diff)
From: Matias Bjorling <m@bjorling.me>
To: hch@infradead.org, axboe@fb.com, linux-fsdevel@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-nvme@lists.infradead.org,
keith.busch@intel.com
Cc: javier@paletta.io
Subject: Re: [PATCH v3 7/7] nvme: LightNVM support
Date: Tue, 05 May 2015 20:51:03 +0200 [thread overview]
Message-ID: <55491117.6080902@bjorling.me> (raw)
In-Reply-To: <1429712816-10336-8-git-send-email-m@bjorling.me>
> --- a/drivers/block/nvme-core.c
> +++ b/drivers/block/nvme-core.c
> @@ -39,6 +39,7 @@
> #include <linux/slab.h>
> #include <linux/t10-pi.h>
> #include <linux/types.h>
> +#include <linux/lightnvm.h>
> #include <scsi/sg.h>
> #include <asm-generic/io-64-nonatomic-lo-hi.h>
>
> @@ -134,6 +135,11 @@ static inline void _nvme_check_size(void)
> BUILD_BUG_ON(sizeof(struct nvme_id_ns) != 4096);
> BUILD_BUG_ON(sizeof(struct nvme_lba_range_type) != 64);
> BUILD_BUG_ON(sizeof(struct nvme_smart_log) != 512);
> + BUILD_BUG_ON(sizeof(struct nvme_nvm_hb_rw) != 64);
> + BUILD_BUG_ON(sizeof(struct nvme_nvm_l2ptbl) != 64);
> + BUILD_BUG_ON(sizeof(struct nvme_nvm_bbtbl) != 64);
> + BUILD_BUG_ON(sizeof(struct nvme_nvm_set_resp) != 64);
> + BUILD_BUG_ON(sizeof(struct nvme_nvm_erase_blk) != 64);
> }
Keith, should I move the lightnvm definition into the nvme-lightnvm.c
file as well?
> static int nvme_submit_iod(struct nvme_queue *nvmeq, struct nvme_iod *iod,
> struct nvme_ns *ns)
> {
> @@ -888,12 +937,29 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
> }
> }
>
> + if (ns->type == NVME_NS_NVM) {
> + switch (nvm_prep_rq(req, &iod->nvm_rqdata)) {
> + case NVM_PREP_DONE:
> + goto done_cmd;
> + case NVM_PREP_REQUEUE:
> + blk_mq_requeue_request(req);
> + blk_mq_kick_requeue_list(hctx->queue);
> + goto done_cmd;
> + case NVM_PREP_BUSY:
> + goto retry_cmd;
> + case NVM_PREP_ERROR:
> + goto error_cmd;
> + }
> + }
> +
Regarding the prep part. I'm not 100% satisfied with it. I can refactor
it into a function and clean it up. There is still a need for the
jumping, as it depends on the iod.
Another possibility is to only call it on lightnvm capable controllers.
With its own queue_rq function. It would be global for all namespaces.
The flow would then look like
register -> nvme_nvm_queue_rq
nvme_nvm_queue_rq()
if (ns is normal command set)
return nvme_queue_rq();
__nvme_nvm_queue_rq()
Any thoughts?
> index aef9a81..5292906 100644
> --- a/include/uapi/linux/nvme.h
> +++ b/include/uapi/linux/nvme.h
> @@ -85,6 +85,35 @@ struct nvme_id_ctrl {
> __u8 vs[1024];
> };
>
> +struct nvme_nvm_id_chnl {
> + __le64 laddr_begin;
> + __le64 laddr_end;
> + __le32 oob_size;
> + __le32 queue_size;
> + __le32 gran_read;
> + __le32 gran_write;
> + __le32 gran_erase;
> + __le32 t_r;
> + __le32 t_sqr;
> + __le32 t_w;
> + __le32 t_sqw;
> + __le32 t_e;
> + __le16 chnl_parallelism;
> + __u8 io_sched;
> + __u8 reserved[133];
> +} __attribute__((packed));
> +
> +struct nvme_nvm_id {
> + __u8 ver_id;
> + __u8 nvm_type;
> + __le16 nchannels;
> + __u8 reserved[252];
> + struct nvme_nvm_id_chnl chnls[];
> +} __attribute__((packed));
> +
> +#define NVME_NVM_CHNLS_PR_REQ ((4096U - sizeof(struct nvme_nvm_id)) \
> + / sizeof(struct nvme_nvm_id_chnl))
> +
> enum {
> NVME_CTRL_ONCS_COMPARE = 1 << 0,
> NVME_CTRL_ONCS_WRITE_UNCORRECTABLE = 1 << 1,
> @@ -130,6 +159,7 @@ struct nvme_id_ns {
>
> enum {
> NVME_NS_FEAT_THIN = 1 << 0,
> + NVME_NS_FEAT_NVM = 1 << 3,
> NVME_NS_FLBAS_LBA_MASK = 0xf,
> NVME_NS_FLBAS_META_EXT = 0x10,
> NVME_LBAF_RP_BEST = 0,
> @@ -146,6 +176,8 @@ enum {
> NVME_NS_DPS_PI_TYPE1 = 1,
> NVME_NS_DPS_PI_TYPE2 = 2,
> NVME_NS_DPS_PI_TYPE3 = 3,
> +
> + NVME_NS_NVM = 1,
> };
>
> struct nvme_smart_log {
> @@ -229,6 +261,12 @@ enum nvme_opcode {
> nvme_cmd_resv_report = 0x0e,
> nvme_cmd_resv_acquire = 0x11,
> nvme_cmd_resv_release = 0x15,
> +
> + nvme_nvm_cmd_hb_write = 0x81,
> + nvme_nvm_cmd_hb_read = 0x02,
> + nvme_nvm_cmd_phys_write = 0x91,
> + nvme_nvm_cmd_phys_read = 0x92,
> + nvme_nvm_cmd_erase = 0x90,
> };
>
> struct nvme_common_command {
> @@ -261,6 +299,74 @@ struct nvme_rw_command {
> __le16 appmask;
> };
>
> +struct nvme_nvm_hb_rw {
> + __u8 opcode;
> + __u8 flags;
> + __u16 command_id;
> + __le32 nsid;
> + __u64 rsvd2;
> + __le64 metadata;
> + __le64 prp1;
> + __le64 prp2;
> + __le64 slba;
> + __le16 length;
> + __le16 control;
> + __le32 dsmgmt;
> + __le64 phys_addr;
> +};
> +
> +struct nvme_nvm_l2ptbl {
> + __u8 opcode;
> + __u8 flags;
> + __u16 command_id;
> + __le32 nsid;
> + __le32 cdw2[4];
> + __le64 prp1;
> + __le64 prp2;
> + __le64 slba;
> + __le32 nlb;
> + __u16 prp1_len;
> + __le16 cdw14[5];
> +};
> +
> +struct nvme_nvm_bbtbl {
> + __u8 opcode;
> + __u8 flags;
> + __u16 command_id;
> + __le32 nsid;
> + __u64 rsvd[2];
> + __le64 prp1;
> + __le64 prp2;
> + __le32 prp1_len;
> + __le32 prp2_len;
> + __le32 lbb;
> + __u32 rsvd11[3];
> +};
> +
> +struct nvme_nvm_set_resp {
> + __u8 opcode;
> + __u8 flags;
> + __u16 command_id;
> + __le32 nsid;
> + __u64 rsvd[2];
> + __le64 prp1;
> + __le64 prp2;
> + __le64 resp;
> + __u32 rsvd11[4];
> +};
> +
> +struct nvme_nvm_erase_blk {
> + __u8 opcode;
> + __u8 flags;
> + __u16 command_id;
> + __le32 nsid;
> + __u64 rsvd[2];
> + __le64 prp1;
> + __le64 prp2;
> + __le64 blk_addr;
> + __u32 rsvd11[4];
> +};
> +
> enum {
> NVME_RW_LR = 1 << 15,
> NVME_RW_FUA = 1 << 14,
> @@ -328,6 +434,13 @@ enum nvme_admin_opcode {
> nvme_admin_format_nvm = 0x80,
> nvme_admin_security_send = 0x81,
> nvme_admin_security_recv = 0x82,
> +
> + nvme_nvm_admin_identify = 0xe2,
> + nvme_nvm_admin_get_features = 0xe6,
> + nvme_nvm_admin_set_resp = 0xe5,
> + nvme_nvm_admin_get_l2p_tbl = 0xea,
> + nvme_nvm_admin_get_bb_tbl = 0xf2,
> + nvme_nvm_admin_set_bb_tbl = 0xf1,
> };
>
> enum {
> @@ -457,6 +570,18 @@ struct nvme_format_cmd {
> __u32 rsvd11[5];
> };
>
> +struct nvme_nvm_identify {
> + __u8 opcode;
> + __u8 flags;
> + __u16 command_id;
> + __le32 nsid;
> + __u64 rsvd[2];
> + __le64 prp1;
> + __le64 prp2;
> + __le32 cns;
> + __u32 rsvd11[5];
> +};
> +
> struct nvme_command {
> union {
> struct nvme_common_command common;
> @@ -470,6 +595,13 @@ struct nvme_command {
> struct nvme_format_cmd format;
> struct nvme_dsm_cmd dsm;
> struct nvme_abort_cmd abort;
> + struct nvme_nvm_identify nvm_identify;
> + struct nvme_nvm_hb_rw nvm_hb_rw;
> + struct nvme_nvm_l2ptbl nvm_l2p;
> + struct nvme_nvm_bbtbl nvm_get_bb;
> + struct nvme_nvm_bbtbl nvm_set_bb;
> + struct nvme_nvm_set_resp nvm_resp;
> + struct nvme_nvm_erase_blk nvm_erase;
> };
> };
>
All these could be moved into the nvme-lightnvm.c file. Taking the
previous discussion with Christoph regarding exposing user headers with
the protocol. It maybe shouldn't be exposed.
Should I push it into nvme-lightnvm.h? (there is still a need for
struct nvme_nvm_hb_rw. The other defs can be moved)
Anything else?
next prev parent reply other threads:[~2015-05-05 18:51 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-22 14:26 [PATCH v3 0/7] Support for Open-Channel SSDs Matias Bjørling
2015-04-22 14:26 ` Matias Bjørling
2015-04-22 14:26 ` [PATCH v3 1/7] bio: Introduce LightNVM payload Matias Bjørling
2015-04-22 14:26 ` Matias Bjørling
2015-05-09 16:00 ` Christoph Hellwig
2015-05-09 16:00 ` Christoph Hellwig
2015-05-11 11:58 ` Matias Bjørling
2015-05-11 11:58 ` Matias Bjørling
2015-05-12 7:21 ` Christoph Hellwig
2015-05-12 7:21 ` Christoph Hellwig
2015-04-22 14:26 ` [PATCH v3 2/7] block: add REQ_NVM_GC for targets gc Matias Bjørling
2015-04-22 14:26 ` Matias Bjørling
2015-05-09 16:00 ` Christoph Hellwig
2015-05-09 16:00 ` Christoph Hellwig
2015-04-22 14:26 ` [PATCH v3 3/7] lightnvm: Support for Open-Channel SSDs Matias Bjørling
2015-04-22 14:26 ` Matias Bjørling
2015-04-22 14:26 ` [PATCH v3 4/7] lightnvm: RRPC target Matias Bjørling
2015-04-22 14:26 ` Matias Bjørling
2015-04-22 14:26 ` [PATCH v3 5/7] null_blk: LightNVM support Matias Bjørling
2015-04-22 14:26 ` Matias Bjørling
2015-04-22 14:26 ` [PATCH v3 6/7] nvme: rename and expose nvme_alloc_iod Matias Bjørling
2015-04-22 14:26 ` Matias Bjørling
2015-04-22 14:26 ` [PATCH v3 7/7] nvme: LightNVM support Matias Bjørling
2015-04-22 14:26 ` Matias Bjørling
2015-04-22 14:26 ` Matias Bjørling
2015-05-05 18:51 ` Matias Bjorling [this message]
2015-05-05 18:51 ` Matias Bjorling
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55491117.6080902@bjorling.me \
--to=m@bjorling.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.