Message ID | 20200617213415.22417-13-dmitry.fomichev@wdc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | hw/block/nvme: Support Namespace Types and Zoned Namespace Command Set | expand |
On Wed, Jun 17, 2020 at 2:52 PM Dmitry Fomichev <dmitry.fomichev@wdc.com> wrote: > > Added a Boolean flag to turn on simulation of Zone Active Excursions. > If the flag, "active_excursions", is set to true, the driver will try > to finish one of the currently open zone if max active zones limit is > going to get exceeded. > > Signed-off-by: Dmitry Fomichev <dmitry.fomichev@wdc.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > hw/block/nvme.c | 24 +++++++++++++++++++++++- > hw/block/nvme.h | 1 + > 2 files changed, 24 insertions(+), 1 deletion(-) > > diff --git a/hw/block/nvme.c b/hw/block/nvme.c > index 05a7cbcfcc..a29cbfcc96 100644 > --- a/hw/block/nvme.c > +++ b/hw/block/nvme.c > @@ -540,6 +540,26 @@ static void nvme_auto_transition_zone(NvmeCtrl *n, NvmeNamespace *ns, > { > NvmeZone *zone; > > + if (n->params.active_excursions && adding_active && > + n->params.max_active_zones && > + ns->nr_active_zones == n->params.max_active_zones) { > + zone = nvme_peek_zone_head(ns, ns->closed_zones); > + if (zone) { > + /* > + * The namespace is at the limit of active zones. > + * Try to finish one of the currently active zones > + * to make the needed active zone resource available. > + */ > + nvme_aor_dec_active(n, ns); > + nvme_assign_zone_state(n, ns, zone, NVME_ZONE_STATE_FULL); > + zone->d.za &= ~(NVME_ZA_FINISH_RECOMMENDED | > + NVME_ZA_RESET_RECOMMENDED); > + zone->d.za |= NVME_ZA_FINISHED_BY_CTLR; > + zone->tstamp = 0; > + trace_pci_nvme_zone_finished_by_controller(zone->d.zslba); > + } > + } > + > if (implicit && n->params.max_open_zones && > ns->nr_open_zones == n->params.max_open_zones) { > zone = nvme_remove_zone_head(n, ns, ns->imp_open_zones); > @@ -2631,7 +2651,7 @@ static int nvme_zoned_init_ns(NvmeCtrl *n, NvmeNamespace *ns, int lba_index, > /* MAR/MOR are zeroes-based, 0xffffffff means no limit */ > ns->id_ns_zoned->mar = cpu_to_le32(n->params.max_active_zones - 1); > ns->id_ns_zoned->mor = cpu_to_le32(n->params.max_open_zones - 1); > - ns->id_ns_zoned->zoc = 0; > + ns->id_ns_zoned->zoc = cpu_to_le16(n->params.active_excursions ? 0x2 : 0); > ns->id_ns_zoned->ozcs = n->params.cross_zone_read ? 0x01 : 0x00; > > ns->id_ns_zoned->lbafe[lba_index].zsze = cpu_to_le64(n->params.zone_size); > @@ -2993,6 +3013,8 @@ static Property nvme_props[] = { > DEFINE_PROP_INT32("max_active", NvmeCtrl, params.max_active_zones, 0), > DEFINE_PROP_INT32("max_open", NvmeCtrl, params.max_open_zones, 0), > DEFINE_PROP_BOOL("cross_zone_read", NvmeCtrl, params.cross_zone_read, true), > + DEFINE_PROP_BOOL("active_excursions", NvmeCtrl, params.active_excursions, > + false), > DEFINE_PROP_UINT8("fill_pattern", NvmeCtrl, params.fill_pattern, 0), > DEFINE_PROP_END_OF_LIST(), > }; > diff --git a/hw/block/nvme.h b/hw/block/nvme.h > index f5a4679702..8a0aaeb09a 100644 > --- a/hw/block/nvme.h > +++ b/hw/block/nvme.h > @@ -15,6 +15,7 @@ typedef struct NvmeParams { > > bool zoned; > bool cross_zone_read; > + bool active_excursions; > uint8_t fill_pattern; > uint32_t zamds_bs; > uint64_t zone_size; > -- > 2.21.0 > >
On Jun 18 06:34, Dmitry Fomichev wrote: > Added a Boolean flag to turn on simulation of Zone Active Excursions. > If the flag, "active_excursions", is set to true, the driver will try > to finish one of the currently open zone if max active zones limit is > going to get exceeded. > > Signed-off-by: Dmitry Fomichev <dmitry.fomichev@wdc.com> > --- > hw/block/nvme.c | 24 +++++++++++++++++++++++- > hw/block/nvme.h | 1 + > 2 files changed, 24 insertions(+), 1 deletion(-) > > diff --git a/hw/block/nvme.c b/hw/block/nvme.c > index 05a7cbcfcc..a29cbfcc96 100644 > --- a/hw/block/nvme.c > +++ b/hw/block/nvme.c > @@ -540,6 +540,26 @@ static void nvme_auto_transition_zone(NvmeCtrl *n, NvmeNamespace *ns, > { > NvmeZone *zone; > > + if (n->params.active_excursions && adding_active && > + n->params.max_active_zones && > + ns->nr_active_zones == n->params.max_active_zones) { > + zone = nvme_peek_zone_head(ns, ns->closed_zones); > + if (zone) { > + /* > + * The namespace is at the limit of active zones. > + * Try to finish one of the currently active zones > + * to make the needed active zone resource available. > + */ > + nvme_aor_dec_active(n, ns); > + nvme_assign_zone_state(n, ns, zone, NVME_ZONE_STATE_FULL); > + zone->d.za &= ~(NVME_ZA_FINISH_RECOMMENDED | > + NVME_ZA_RESET_RECOMMENDED); > + zone->d.za |= NVME_ZA_FINISHED_BY_CTLR; > + zone->tstamp = 0; > + trace_pci_nvme_zone_finished_by_controller(zone->d.zslba); > + } > + } Open Zones should also be considered for excursions. > + > if (implicit && n->params.max_open_zones && > ns->nr_open_zones == n->params.max_open_zones) { > zone = nvme_remove_zone_head(n, ns, ns->imp_open_zones); > @@ -2631,7 +2651,7 @@ static int nvme_zoned_init_ns(NvmeCtrl *n, NvmeNamespace *ns, int lba_index, > /* MAR/MOR are zeroes-based, 0xffffffff means no limit */ > ns->id_ns_zoned->mar = cpu_to_le32(n->params.max_active_zones - 1); > ns->id_ns_zoned->mor = cpu_to_le32(n->params.max_open_zones - 1); > - ns->id_ns_zoned->zoc = 0; > + ns->id_ns_zoned->zoc = cpu_to_le16(n->params.active_excursions ? 0x2 : 0); > ns->id_ns_zoned->ozcs = n->params.cross_zone_read ? 0x01 : 0x00; > > ns->id_ns_zoned->lbafe[lba_index].zsze = cpu_to_le64(n->params.zone_size); > @@ -2993,6 +3013,8 @@ static Property nvme_props[] = { > DEFINE_PROP_INT32("max_active", NvmeCtrl, params.max_active_zones, 0), > DEFINE_PROP_INT32("max_open", NvmeCtrl, params.max_open_zones, 0), > DEFINE_PROP_BOOL("cross_zone_read", NvmeCtrl, params.cross_zone_read, true), > + DEFINE_PROP_BOOL("active_excursions", NvmeCtrl, params.active_excursions, > + false), > DEFINE_PROP_UINT8("fill_pattern", NvmeCtrl, params.fill_pattern, 0), > DEFINE_PROP_END_OF_LIST(), > }; > diff --git a/hw/block/nvme.h b/hw/block/nvme.h > index f5a4679702..8a0aaeb09a 100644 > --- a/hw/block/nvme.h > +++ b/hw/block/nvme.h > @@ -15,6 +15,7 @@ typedef struct NvmeParams { > > bool zoned; > bool cross_zone_read; > + bool active_excursions; > uint8_t fill_pattern; > uint32_t zamds_bs; > uint64_t zone_size; > -- > 2.21.0 > >
diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 05a7cbcfcc..a29cbfcc96 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -540,6 +540,26 @@ static void nvme_auto_transition_zone(NvmeCtrl *n, NvmeNamespace *ns, { NvmeZone *zone; + if (n->params.active_excursions && adding_active && + n->params.max_active_zones && + ns->nr_active_zones == n->params.max_active_zones) { + zone = nvme_peek_zone_head(ns, ns->closed_zones); + if (zone) { + /* + * The namespace is at the limit of active zones. + * Try to finish one of the currently active zones + * to make the needed active zone resource available. + */ + nvme_aor_dec_active(n, ns); + nvme_assign_zone_state(n, ns, zone, NVME_ZONE_STATE_FULL); + zone->d.za &= ~(NVME_ZA_FINISH_RECOMMENDED | + NVME_ZA_RESET_RECOMMENDED); + zone->d.za |= NVME_ZA_FINISHED_BY_CTLR; + zone->tstamp = 0; + trace_pci_nvme_zone_finished_by_controller(zone->d.zslba); + } + } + if (implicit && n->params.max_open_zones && ns->nr_open_zones == n->params.max_open_zones) { zone = nvme_remove_zone_head(n, ns, ns->imp_open_zones); @@ -2631,7 +2651,7 @@ static int nvme_zoned_init_ns(NvmeCtrl *n, NvmeNamespace *ns, int lba_index, /* MAR/MOR are zeroes-based, 0xffffffff means no limit */ ns->id_ns_zoned->mar = cpu_to_le32(n->params.max_active_zones - 1); ns->id_ns_zoned->mor = cpu_to_le32(n->params.max_open_zones - 1); - ns->id_ns_zoned->zoc = 0; + ns->id_ns_zoned->zoc = cpu_to_le16(n->params.active_excursions ? 0x2 : 0); ns->id_ns_zoned->ozcs = n->params.cross_zone_read ? 0x01 : 0x00; ns->id_ns_zoned->lbafe[lba_index].zsze = cpu_to_le64(n->params.zone_size); @@ -2993,6 +3013,8 @@ static Property nvme_props[] = { DEFINE_PROP_INT32("max_active", NvmeCtrl, params.max_active_zones, 0), DEFINE_PROP_INT32("max_open", NvmeCtrl, params.max_open_zones, 0), DEFINE_PROP_BOOL("cross_zone_read", NvmeCtrl, params.cross_zone_read, true), + DEFINE_PROP_BOOL("active_excursions", NvmeCtrl, params.active_excursions, + false), DEFINE_PROP_UINT8("fill_pattern", NvmeCtrl, params.fill_pattern, 0), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/block/nvme.h b/hw/block/nvme.h index f5a4679702..8a0aaeb09a 100644 --- a/hw/block/nvme.h +++ b/hw/block/nvme.h @@ -15,6 +15,7 @@ typedef struct NvmeParams { bool zoned; bool cross_zone_read; + bool active_excursions; uint8_t fill_pattern; uint32_t zamds_bs; uint64_t zone_size;
Added a Boolean flag to turn on simulation of Zone Active Excursions. If the flag, "active_excursions", is set to true, the driver will try to finish one of the currently open zone if max active zones limit is going to get exceeded. Signed-off-by: Dmitry Fomichev <dmitry.fomichev@wdc.com> --- hw/block/nvme.c | 24 +++++++++++++++++++++++- hw/block/nvme.h | 1 + 2 files changed, 24 insertions(+), 1 deletion(-)