From patchwork Mon Sep 27 05:17:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Klaus Jensen X-Patchwork-Id: 12519147 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F29DDC433EF for ; Mon, 27 Sep 2021 05:50:37 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6A5936115B for ; Mon, 27 Sep 2021 05:50:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 6A5936115B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=irrelevant.dk Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:44060 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mUjXA-0002gc-Cu for qemu-devel@archiver.kernel.org; Mon, 27 Sep 2021 01:50:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34184) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mUj2K-0003Ik-7H; Mon, 27 Sep 2021 01:18:44 -0400 Received: from wnew3-smtp.messagingengine.com ([64.147.123.17]:37617) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mUj2F-0000F7-VW; Mon, 27 Sep 2021 01:18:43 -0400 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailnew.west.internal (Postfix) with ESMTP id 77A102B0120E; Mon, 27 Sep 2021 01:18:37 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Mon, 27 Sep 2021 01:18:38 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=irrelevant.dk; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm1; bh=S0eB+tPU702Wi bNvU9mwb0TP3Y70N5xeoeyuAJElhN0=; b=lh94gXCFzBW6gHNu5FWt4Is0yUg/F rw2btI+zncG0Zqt8fhH22T6mvcwHemmrB6jnmL9eXWTtziQXEI/dzTpIEHNvDn/u LCCBWz6GBjYAovGJkBzsB372WzLpkmOeuZ0eO65hPmoHVlgxZpSttx21rr2F/N/d WYPsLNCnsb9R0yJfHGEXgbaKFUn4A5NwbbWE7lPBqi7h8MgBR4e35MiqGlM1oz/J OkfeFHz1NwUmAr/Yj1PlZd21myvs8UHlxgkb19F2lzOv3vGLEiaNdaC+NBYNMxWx KxpXSTWqKFdDNK4u0+Bd47Gbxvbl2hDXw+3u/+GRloO83qAsaBsHlTxMQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=S0eB+tPU702WibNvU9mwb0TP3Y70N5xeoeyuAJElhN0=; b=A3HKfpES uIcmL2T4UKJYJXxk1mZrBbYKIK4UmjdIBhBTSiUWcHwGoxtTELCsOAwdLL+h6xr3 kbzGqnnsjkfPTSLlGN/sCkItM0uL1Fi3Vgps0tmT9tLxDcsAeLrO9wgCwy8Fsqzc 9Pxd43PQMjC9Q5aEdWJxSknCmUUAiiTitx9rIfc5SG+5RQFilpRqcvkK3CQU1kXY 3YwkvM6xhtKxrS26UX4zyHRNTzMtwiJ0s1vH0fq5bGvOvFlplsVmm7UG6RgrLcVl iyw8snkV8qUDd78p5YSG6osM9cmJwHJ8JWF5ITZApbfUw+SWIa6bhkF+MGVUmcFZ iELfVbWap0cqvA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrudejjedgledvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefmlhgruhhs ucflvghnshgvnhcuoehithhssehirhhrvghlvghvrghnthdrughkqeenucggtffrrghtth gvrhhnpeeiudehfeejteegueeffeekhfelgfekheetfffgteejgeekuefgtddujeeuudeg ieenucffohhmrghinhepuhhuihgurdgurghtrgenucevlhhushhtvghrufhiiigvpedtne curfgrrhgrmhepmhgrihhlfhhrohhmpehithhssehirhhrvghlvghvrghnthdrughk X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 Sep 2021 01:18:34 -0400 (EDT) From: Klaus Jensen To: qemu-devel@nongnu.org Subject: [PATCH RFC v2 08/16] hw/nvme: hoist qdev state from namespace Date: Mon, 27 Sep 2021 07:17:51 +0200 Message-Id: <20210927051759.447305-9-its@irrelevant.dk> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210927051759.447305-1-its@irrelevant.dk> References: <20210927051759.447305-1-its@irrelevant.dk> MIME-Version: 1.0 Received-SPF: pass client-ip=64.147.123.17; envelope-from=its@irrelevant.dk; helo=wnew3-smtp.messagingengine.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Fam Zheng , Kevin Wolf , =?utf-8?q?Dan?= =?utf-8?q?iel_P=2E_Berrang=C3=A9?= , Eduardo Habkost , qemu-block@nongnu.org, =?utf-8?q?Phi?= =?utf-8?q?lippe_Mathieu-Daud=C3=A9?= , Markus Armbruster , Klaus Jensen , Hanna Reitz , Hannes Reinecke , Stefan Hajnoczi , Klaus Jensen , Keith Busch , Paolo Bonzini , Eric Blake Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Klaus Jensen Signed-off-by: Klaus Jensen --- hw/nvme/ctrl.c | 32 +++--- hw/nvme/ns.c | 263 +++++++++++++++++++++++++---------------------- hw/nvme/nvme.h | 44 +++++--- hw/nvme/subsys.c | 2 +- 4 files changed, 186 insertions(+), 155 deletions(-) diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 3e561a13f76f..67600d075d32 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -4620,10 +4620,10 @@ static uint16_t nvme_identify_nslist(NvmeCtrl *n, NvmeRequest *req, continue; } } - if (ns->params.nsid <= min_nsid) { + if (ns->nsid <= min_nsid) { continue; } - list_ptr[j++] = cpu_to_le32(ns->params.nsid); + list_ptr[j++] = cpu_to_le32(ns->nsid); if (j == data_len / sizeof(uint32_t)) { break; } @@ -4668,10 +4668,10 @@ static uint16_t nvme_identify_nslist_csi(NvmeCtrl *n, NvmeRequest *req, continue; } } - if (ns->params.nsid <= min_nsid || c->csi != ns->csi) { + if (ns->nsid <= min_nsid || c->csi != ns->csi) { continue; } - list_ptr[j++] = cpu_to_le32(ns->params.nsid); + list_ptr[j++] = cpu_to_le32(ns->nsid); if (j == data_len / sizeof(uint32_t)) { break; } @@ -4718,14 +4718,14 @@ static uint16_t nvme_identify_ns_descr_list(NvmeCtrl *n, NvmeRequest *req) */ uuid.hdr.nidt = NVME_NIDT_UUID; uuid.hdr.nidl = NVME_NIDL_UUID; - memcpy(uuid.v, ns->params.uuid.data, NVME_NIDL_UUID); + memcpy(uuid.v, ns->uuid.data, NVME_NIDL_UUID); memcpy(pos, &uuid, sizeof(uuid)); pos += sizeof(uuid); - if (ns->params.eui64) { + if (ns->eui64.v) { eui64.hdr.nidt = NVME_NIDT_EUI64; eui64.hdr.nidl = NVME_NIDL_EUI64; - eui64.v = cpu_to_be64(ns->params.eui64); + eui64.v = cpu_to_be64(ns->eui64.v); memcpy(pos, &eui64, sizeof(eui64)); pos += sizeof(eui64); } @@ -5264,7 +5264,7 @@ static uint16_t nvme_ns_attachment(NvmeCtrl *n, NvmeRequest *req) return NVME_NS_ALREADY_ATTACHED | NVME_DNR; } - if (ns->attached && !ns->params.shared) { + if (ns->attached && !(ns->flags & NVME_NS_SHARED)) { return NVME_NS_PRIVATE | NVME_DNR; } @@ -5342,12 +5342,12 @@ static void nvme_format_set(NvmeNamespace *ns, NvmeCmd *cmd) uint8_t mset = (dw10 >> 4) & 0x1; uint8_t pil = (dw10 >> 8) & 0x1; - trace_pci_nvme_format_set(ns->params.nsid, lbaf, mset, pi, pil); + trace_pci_nvme_format_set(ns->nsid, lbaf, mset, pi, pil); nvm->id_ns.dps = (pil << 3) | pi; nvm->id_ns.flbas = lbaf | (mset << 4); - nvme_ns_init_format(ns); + nvme_ns_nvm_init_format(nvm); } static void nvme_format_ns_cb(void *opaque, int ret) @@ -6552,7 +6552,7 @@ static int nvme_init_subsys(NvmeCtrl *n, Error **errp) void nvme_attach_ns(NvmeCtrl *n, NvmeNamespace *ns) { NvmeNamespaceNvm *nvm = NVME_NAMESPACE_NVM(ns); - uint32_t nsid = ns->params.nsid; + uint32_t nsid = ns->nsid; assert(nsid && nsid <= NVME_MAX_NAMESPACES); n->namespaces[nsid] = ns; @@ -6565,7 +6565,6 @@ void nvme_attach_ns(NvmeCtrl *n, NvmeNamespace *ns) static void nvme_realize(PCIDevice *pci_dev, Error **errp) { NvmeCtrl *n = NVME(pci_dev); - NvmeNamespace *ns; Error *local_err = NULL; nvme_check_constraints(n, &local_err); @@ -6590,12 +6589,11 @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp) /* setup a namespace if the controller drive property was given */ if (n->namespace.blkconf.blk) { - ns = &n->namespace; - ns->params.nsid = 1; + NvmeNamespaceDevice *nsdev = &n->namespace; + NvmeNamespace *ns = &nsdev->ns; + ns->nsid = 1; - if (nvme_ns_setup(ns, errp)) { - return; - } + nvme_ns_init(ns); nvme_attach_ns(n, ns); } diff --git a/hw/nvme/ns.c b/hw/nvme/ns.c index 9b59beb0324d..582ff7d0236b 100644 --- a/hw/nvme/ns.c +++ b/hw/nvme/ns.c @@ -26,9 +26,8 @@ #define MIN_DISCARD_GRANULARITY (4 * KiB) -void nvme_ns_init_format(NvmeNamespace *ns) +void nvme_ns_nvm_init_format(NvmeNamespaceNvm *nvm) { - NvmeNamespaceNvm *nvm = NVME_NAMESPACE_NVM(ns); NvmeIdNs *id_ns = &nvm->id_ns; BlockDriverInfo bdi; int npdg, nlbas, ret; @@ -48,7 +47,7 @@ void nvme_ns_init_format(NvmeNamespace *ns) npdg = nvm->discard_granularity / nvm->lbasz; - ret = bdrv_get_info(blk_bs(ns->blkconf.blk), &bdi); + ret = bdrv_get_info(blk_bs(nvm->blk), &bdi); if (ret >= 0 && bdi.cluster_size > nvm->discard_granularity) { npdg = bdi.cluster_size / nvm->lbasz; } @@ -56,53 +55,39 @@ void nvme_ns_init_format(NvmeNamespace *ns) id_ns->npda = id_ns->npdg = npdg - 1; } -static int nvme_ns_init(NvmeNamespace *ns, Error **errp) +void nvme_ns_init(NvmeNamespace *ns) { NvmeNamespaceNvm *nvm = NVME_NAMESPACE_NVM(ns); - static uint64_t ns_count; NvmeIdNs *id_ns = &nvm->id_ns; uint8_t ds; uint16_t ms; int i; - ns->csi = NVME_CSI_NVM; - ns->status = 0x0; - - nvm->id_ns.dlfeat = 0x1; + id_ns->dlfeat = 0x1; /* support DULBE and I/O optimization fields */ id_ns->nsfeat |= (0x4 | 0x10); - if (ns->params.shared) { + if (ns->flags & NVME_NS_SHARED) { id_ns->nmic |= NVME_NMIC_NS_SHARED; } - /* Substitute a missing EUI-64 by an autogenerated one */ - ++ns_count; - if (!ns->params.eui64 && ns->params.eui64_default) { - ns->params.eui64 = ns_count + NVME_EUI64_DEFAULT; - } - /* simple copy */ id_ns->mssrl = cpu_to_le16(nvm->mssrl); id_ns->mcl = cpu_to_le32(nvm->mcl); id_ns->msrc = nvm->msrc; - id_ns->eui64 = cpu_to_be64(ns->params.eui64); + id_ns->eui64 = cpu_to_be64(ns->eui64.v); ds = 31 - clz32(nvm->lbasz); - ms = ns->params.ms; + ms = nvm->lbaf.ms; id_ns->mc = NVME_ID_NS_MC_EXTENDED | NVME_ID_NS_MC_SEPARATE; - if (ms && ns->params.mset) { + if (ms && nvm->flags & NVME_NS_NVM_EXTENDED_LBA) { id_ns->flbas |= NVME_ID_NS_FLBAS_EXTENDED; } id_ns->dpc = 0x1f; - id_ns->dps = ns->params.pi; - if (ns->params.pi && ns->params.pil) { - id_ns->dps |= NVME_ID_NS_DPS_FIRST_EIGHT; - } static const NvmeLBAF lbaf[16] = { [0] = { .ds = 9 }, @@ -135,59 +120,63 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp) id_ns->flbas |= id_ns->nlbaf; lbaf_found: - nvme_ns_init_format(ns); - - return 0; + nvme_ns_nvm_init_format(nvm); } -static int nvme_ns_init_blk(NvmeNamespace *ns, Error **errp) +static int nvme_nsdev_init_blk(NvmeNamespaceDevice *nsdev, + Error **errp) { + NvmeNamespace *ns = &nsdev->ns; NvmeNamespaceNvm *nvm = NVME_NAMESPACE_NVM(ns); + BlockConf *blkconf = &nsdev->blkconf; bool read_only; - if (!blkconf_blocksizes(&ns->blkconf, errp)) { + if (!blkconf_blocksizes(blkconf, errp)) { return -1; } - read_only = !blk_supports_write_perm(ns->blkconf.blk); - if (!blkconf_apply_backend_options(&ns->blkconf, read_only, false, errp)) { + read_only = !blk_supports_write_perm(blkconf->blk); + if (!blkconf_apply_backend_options(blkconf, read_only, false, errp)) { return -1; } - if (ns->blkconf.discard_granularity == -1) { - ns->blkconf.discard_granularity = - MAX(ns->blkconf.logical_block_size, MIN_DISCARD_GRANULARITY); + if (blkconf->discard_granularity == -1) { + blkconf->discard_granularity = + MAX(blkconf->logical_block_size, MIN_DISCARD_GRANULARITY); } - nvm->lbasz = ns->blkconf.logical_block_size; - nvm->discard_granularity = ns->blkconf.discard_granularity; + nvm->lbasz = blkconf->logical_block_size; + nvm->discard_granularity = blkconf->discard_granularity; nvm->lbaf.ds = 31 - clz32(nvm->lbasz); - nvm->lbaf.ms = ns->params.ms; + nvm->lbaf.ms = nsdev->params.ms; + nvm->blk = blkconf->blk; - nvm->size = blk_getlength(ns->blkconf.blk); + nvm->size = blk_getlength(nvm->blk); if (nvm->size < 0) { - error_setg_errno(errp, -nvm->size, "could not get blockdev size"); + error_setg_errno(errp, -(nvm->size), "could not get blockdev size"); return -1; } return 0; } -static int nvme_zns_check_calc_geometry(NvmeNamespace *ns, Error **errp) +static int nvme_nsdev_zns_check_calc_geometry(NvmeNamespaceDevice *nsdev, + Error **errp) { + NvmeNamespace *ns = &nsdev->ns; NvmeNamespaceNvm *nvm = NVME_NAMESPACE_NVM(ns); NvmeNamespaceZoned *zoned = NVME_NAMESPACE_ZONED(ns); uint64_t zone_size, zone_cap; /* Make sure that the values of ZNS properties are sane */ - if (ns->params.zone_size_bs) { - zone_size = ns->params.zone_size_bs; + if (nsdev->params.zone_size_bs) { + zone_size = nsdev->params.zone_size_bs; } else { zone_size = NVME_DEFAULT_ZONE_SIZE; } - if (ns->params.zone_cap_bs) { - zone_cap = ns->params.zone_cap_bs; + if (nsdev->params.zone_cap_bs) { + zone_cap = nsdev->params.zone_cap_bs; } else { zone_cap = zone_size; } @@ -359,46 +348,47 @@ static void nvme_zns_shutdown(NvmeNamespaceZoned *zoned) assert(zoned->nr_open_zones == 0); } -static int nvme_ns_check_constraints(NvmeNamespace *ns, Error **errp) +static int nvme_nsdev_check_constraints(NvmeNamespaceDevice *nsdev, + Error **errp) { - if (!ns->blkconf.blk) { + if (!nsdev->blkconf.blk) { error_setg(errp, "block backend not configured"); return -1; } - if (ns->params.pi && ns->params.ms < 8) { + if (nsdev->params.pi && nsdev->params.ms < 8) { error_setg(errp, "at least 8 bytes of metadata required to enable " "protection information"); return -1; } - if (ns->params.nsid > NVME_MAX_NAMESPACES) { + if (nsdev->params.nsid > NVME_MAX_NAMESPACES) { error_setg(errp, "invalid namespace id (must be between 0 and %d)", NVME_MAX_NAMESPACES); return -1; } - if (ns->params.zoned) { - if (ns->params.max_active_zones) { - if (ns->params.max_open_zones > ns->params.max_active_zones) { + if (nsdev->params.zoned) { + if (nsdev->params.max_active_zones) { + if (nsdev->params.max_open_zones > nsdev->params.max_active_zones) { error_setg(errp, "max_open_zones (%u) exceeds " - "max_active_zones (%u)", ns->params.max_open_zones, - ns->params.max_active_zones); + "max_active_zones (%u)", nsdev->params.max_open_zones, + nsdev->params.max_active_zones); return -1; } - if (!ns->params.max_open_zones) { - ns->params.max_open_zones = ns->params.max_active_zones; + if (!nsdev->params.max_open_zones) { + nsdev->params.max_open_zones = nsdev->params.max_active_zones; } } - if (ns->params.zd_extension_size) { - if (ns->params.zd_extension_size & 0x3f) { + if (nsdev->params.zd_extension_size) { + if (nsdev->params.zd_extension_size & 0x3f) { error_setg(errp, "zone descriptor extension size must be a " "multiple of 64B"); return -1; } - if ((ns->params.zd_extension_size >> 6) > 0xff) { + if ((nsdev->params.zd_extension_size >> 6) > 0xff) { error_setg(errp, "zone descriptor extension size is too large"); return -1; @@ -409,35 +399,57 @@ static int nvme_ns_check_constraints(NvmeNamespace *ns, Error **errp) return 0; } -int nvme_ns_setup(NvmeNamespace *ns, Error **errp) +static int nvme_nsdev_setup(NvmeNamespaceDevice *nsdev, Error **errp) { - if (nvme_ns_check_constraints(ns, errp)) { + NvmeNamespaceNvm *nvm = NVME_NAMESPACE_NVM(&nsdev->ns); + static uint64_t ns_count; + + if (nvme_nsdev_check_constraints(nsdev, errp)) { return -1; } - if (nvme_ns_init_blk(ns, errp)) { - return -1; + if (nsdev->params.shared) { + nsdev->ns.flags |= NVME_NS_SHARED; } - if (nvme_ns_init(ns, errp)) { - return -1; - } - if (ns->params.zoned) { - NvmeNamespaceZoned *zoned = NVME_NAMESPACE_ZONED(ns); + nsdev->ns.nsid = nsdev->params.nsid; + memcpy(&nsdev->ns.uuid, &nsdev->params.uuid, sizeof(nsdev->ns.uuid)); - if (nvme_zns_check_calc_geometry(ns, errp) != 0) { + if (nsdev->params.eui64) { + stq_be_p(&nsdev->ns.eui64.v, nsdev->params.eui64); + } + + /* Substitute a missing EUI-64 by an autogenerated one */ + ++ns_count; + if (!nsdev->ns.eui64.v && nsdev->params.eui64_default) { + nsdev->ns.eui64.v = ns_count + NVME_EUI64_DEFAULT; + } + + nvm->id_ns.dps = nsdev->params.pi; + if (nsdev->params.pi && nsdev->params.pil) { + nvm->id_ns.dps |= NVME_ID_NS_DPS_FIRST_EIGHT; + } + + nsdev->ns.csi = NVME_CSI_NVM; + + nvme_ns_init(&nsdev->ns); + + if (nsdev->params.zoned) { + NvmeNamespaceZoned *zoned = NVME_NAMESPACE_ZONED(&nsdev->ns); + + if (nvme_nsdev_zns_check_calc_geometry(nsdev, errp) != 0) { return -1; } /* copy device parameters */ - zoned->zd_extension_size = ns->params.zd_extension_size; - zoned->max_open_zones = ns->params.max_open_zones; - zoned->max_active_zones = ns->params.max_open_zones; - if (ns->params.cross_zone_read) { + zoned->zd_extension_size = nsdev->params.zd_extension_size; + zoned->max_open_zones = nsdev->params.max_open_zones; + zoned->max_active_zones = nsdev->params.max_open_zones; + if (nsdev->params.cross_zone_read) { zoned->flags |= NVME_NS_ZONED_CROSS_READ; } - nvme_zns_init(ns); + nvme_zns_init(&nsdev->ns); } return 0; @@ -445,12 +457,12 @@ int nvme_ns_setup(NvmeNamespace *ns, Error **errp) void nvme_ns_drain(NvmeNamespace *ns) { - blk_drain(ns->blkconf.blk); + blk_drain(nvme_blk(ns)); } void nvme_ns_shutdown(NvmeNamespace *ns) { - blk_flush(ns->blkconf.blk); + blk_flush(nvme_blk(ns)); if (nvme_ns_zoned(ns)) { nvme_zns_shutdown(NVME_NAMESPACE_ZONED(ns)); } @@ -466,26 +478,28 @@ void nvme_ns_cleanup(NvmeNamespace *ns) } } -static void nvme_ns_unrealize(DeviceState *dev) +static void nvme_nsdev_unrealize(DeviceState *dev) { - NvmeNamespace *ns = NVME_NS(dev); + NvmeNamespaceDevice *nsdev = NVME_NAMESPACE_DEVICE(dev); + NvmeNamespace *ns = &nsdev->ns; nvme_ns_drain(ns); nvme_ns_shutdown(ns); nvme_ns_cleanup(ns); } -static void nvme_ns_realize(DeviceState *dev, Error **errp) +static void nvme_nsdev_realize(DeviceState *dev, Error **errp) { - NvmeNamespace *ns = NVME_NS(dev); + NvmeNamespaceDevice *nsdev = NVME_NAMESPACE_DEVICE(dev); + NvmeNamespace *ns = &nsdev->ns; BusState *s = qdev_get_parent_bus(dev); NvmeCtrl *n = NVME(s->parent); NvmeSubsystem *subsys = n->subsys; - uint32_t nsid = ns->params.nsid; + uint32_t nsid = nsdev->params.nsid; int i; if (!n->subsys) { - if (ns->params.detached) { + if (nsdev->params.detached) { error_setg(errp, "detached requires that the nvme device is " "linked to an nvme-subsys device"); return; @@ -500,7 +514,11 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp) } } - if (nvme_ns_setup(ns, errp)) { + if (nvme_nsdev_init_blk(nsdev, errp)) { + return; + } + + if (nvme_nsdev_setup(nsdev, errp)) { return; } @@ -510,7 +528,7 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp) continue; } - nsid = ns->params.nsid = i; + nsid = ns->nsid = i; break; } @@ -528,11 +546,11 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp) if (subsys) { subsys->namespaces[nsid] = ns; - if (ns->params.detached) { + if (nsdev->params.detached) { return; } - if (ns->params.shared) { + if (nsdev->params.shared) { for (i = 0; i < ARRAY_SIZE(subsys->ctrls); i++) { NvmeCtrl *ctrl = subsys->ctrls[i]; @@ -548,73 +566,74 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp) nvme_attach_ns(n, ns); } -static Property nvme_ns_props[] = { - DEFINE_BLOCK_PROPERTIES(NvmeNamespace, blkconf), - DEFINE_PROP_BOOL("detached", NvmeNamespace, params.detached, false), - DEFINE_PROP_BOOL("shared", NvmeNamespace, params.shared, true), - DEFINE_PROP_UINT32("nsid", NvmeNamespace, params.nsid, 0), - DEFINE_PROP_UUID("uuid", NvmeNamespace, params.uuid), - DEFINE_PROP_UINT64("eui64", NvmeNamespace, params.eui64, 0), - DEFINE_PROP_UINT16("ms", NvmeNamespace, params.ms, 0), - DEFINE_PROP_UINT8("mset", NvmeNamespace, params.mset, 0), - DEFINE_PROP_UINT8("pi", NvmeNamespace, params.pi, 0), - DEFINE_PROP_UINT8("pil", NvmeNamespace, params.pil, 0), - DEFINE_PROP_UINT16("mssrl", NvmeNamespace, params.mssrl, 128), - DEFINE_PROP_UINT32("mcl", NvmeNamespace, params.mcl, 128), - DEFINE_PROP_UINT8("msrc", NvmeNamespace, params.msrc, 127), - DEFINE_PROP_BOOL("zoned", NvmeNamespace, params.zoned, false), - DEFINE_PROP_SIZE("zoned.zone_size", NvmeNamespace, params.zone_size_bs, +static Property nvme_nsdev_props[] = { + DEFINE_BLOCK_PROPERTIES(NvmeNamespaceDevice, blkconf), + DEFINE_PROP_BOOL("detached", NvmeNamespaceDevice, params.detached, false), + DEFINE_PROP_BOOL("shared", NvmeNamespaceDevice, params.shared, true), + DEFINE_PROP_UINT32("nsid", NvmeNamespaceDevice, params.nsid, 0), + DEFINE_PROP_UUID("uuid", NvmeNamespaceDevice, params.uuid), + DEFINE_PROP_UINT64("eui64", NvmeNamespaceDevice, params.eui64, 0), + DEFINE_PROP_UINT16("ms", NvmeNamespaceDevice, params.ms, 0), + DEFINE_PROP_UINT8("mset", NvmeNamespaceDevice, params.mset, 0), + DEFINE_PROP_UINT8("pi", NvmeNamespaceDevice, params.pi, 0), + DEFINE_PROP_UINT8("pil", NvmeNamespaceDevice, params.pil, 0), + DEFINE_PROP_UINT16("mssrl", NvmeNamespaceDevice, params.mssrl, 128), + DEFINE_PROP_UINT32("mcl", NvmeNamespaceDevice, params.mcl, 128), + DEFINE_PROP_UINT8("msrc", NvmeNamespaceDevice, params.msrc, 127), + DEFINE_PROP_BOOL("zoned", NvmeNamespaceDevice, params.zoned, false), + DEFINE_PROP_SIZE("zoned.zone_size", NvmeNamespaceDevice, params.zone_size_bs, NVME_DEFAULT_ZONE_SIZE), - DEFINE_PROP_SIZE("zoned.zone_capacity", NvmeNamespace, params.zone_cap_bs, + DEFINE_PROP_SIZE("zoned.zone_capacity", NvmeNamespaceDevice, params.zone_cap_bs, 0), - DEFINE_PROP_BOOL("zoned.cross_read", NvmeNamespace, + DEFINE_PROP_BOOL("zoned.cross_read", NvmeNamespaceDevice, params.cross_zone_read, false), - DEFINE_PROP_UINT32("zoned.max_active", NvmeNamespace, + DEFINE_PROP_UINT32("zoned.max_active", NvmeNamespaceDevice, params.max_active_zones, 0), - DEFINE_PROP_UINT32("zoned.max_open", NvmeNamespace, + DEFINE_PROP_UINT32("zoned.max_open", NvmeNamespaceDevice, params.max_open_zones, 0), - DEFINE_PROP_UINT32("zoned.descr_ext_size", NvmeNamespace, + DEFINE_PROP_UINT32("zoned.descr_ext_size", NvmeNamespaceDevice, params.zd_extension_size, 0), - DEFINE_PROP_BOOL("eui64-default", NvmeNamespace, params.eui64_default, + DEFINE_PROP_BOOL("eui64-default", NvmeNamespaceDevice, params.eui64_default, true), DEFINE_PROP_END_OF_LIST(), }; -static void nvme_ns_class_init(ObjectClass *oc, void *data) +static void nvme_nsdev_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); dc->bus_type = TYPE_NVME_BUS; - dc->realize = nvme_ns_realize; - dc->unrealize = nvme_ns_unrealize; - device_class_set_props(dc, nvme_ns_props); + dc->realize = nvme_nsdev_realize; + dc->unrealize = nvme_nsdev_unrealize; + device_class_set_props(dc, nvme_nsdev_props); dc->desc = "Virtual NVMe namespace"; } -static void nvme_ns_instance_init(Object *obj) +static void nvme_nsdev_instance_init(Object *obj) { - NvmeNamespace *ns = NVME_NS(obj); - char *bootindex = g_strdup_printf("/namespace@%d,0", ns->params.nsid); + NvmeNamespaceDevice *nsdev = NVME_NAMESPACE_DEVICE(obj); + char *bootindex = g_strdup_printf("/namespace@%d,0", + nsdev->params.nsid); - device_add_bootindex_property(obj, &ns->bootindex, "bootindex", + device_add_bootindex_property(obj, &nsdev->bootindex, "bootindex", bootindex, DEVICE(obj)); g_free(bootindex); } -static const TypeInfo nvme_ns_info = { - .name = TYPE_NVME_NS, +static const TypeInfo nvme_nsdev_info = { + .name = TYPE_NVME_NAMESPACE_DEVICE, .parent = TYPE_DEVICE, - .class_init = nvme_ns_class_init, - .instance_size = sizeof(NvmeNamespace), - .instance_init = nvme_ns_instance_init, + .class_init = nvme_nsdev_class_init, + .instance_size = sizeof(NvmeNamespaceDevice), + .instance_init = nvme_nsdev_instance_init, }; -static void nvme_ns_register_types(void) +static void register_types(void) { - type_register_static(&nvme_ns_info); + type_register_static(&nvme_nsdev_info); } -type_init(nvme_ns_register_types) +type_init(register_types) diff --git a/hw/nvme/nvme.h b/hw/nvme/nvme.h index 525bfd0ca831..356d95805f9e 100644 --- a/hw/nvme/nvme.h +++ b/hw/nvme/nvme.h @@ -80,9 +80,8 @@ static inline NvmeNamespace *nvme_subsys_ns(NvmeSubsystem *subsys, return subsys->namespaces[nsid]; } -#define TYPE_NVME_NS "nvme-ns" -#define NVME_NS(obj) \ - OBJECT_CHECK(NvmeNamespace, (obj), TYPE_NVME_NS) +#define TYPE_NVME_NAMESPACE_DEVICE "nvme-ns" +OBJECT_DECLARE_SIMPLE_TYPE(NvmeNamespaceDevice, NVME_NAMESPACE_DEVICE) typedef struct NvmeNamespaceParams { bool detached; @@ -170,19 +169,25 @@ typedef struct NvmeNamespaceNvm { unsigned long flags; } NvmeNamespaceNvm; +enum NvmeNamespaceFlags { + NVME_NS_SHARED = 1 << 0, +}; + typedef struct NvmeNamespace { - DeviceState parent_obj; - BlockConf blkconf; - int32_t bootindex; + uint32_t nsid; + uint8_t csi; + QemuUUID uuid; + union { + uint64_t v; + uint8_t a[8]; + } eui64; + + unsigned long flags; + const uint32_t *iocs; - uint8_t csi; uint16_t status; int attached; - QTAILQ_ENTRY(NvmeNamespace) entry; - - NvmeNamespaceParams params; - struct { uint32_t err_rec; } features; @@ -199,10 +204,19 @@ static inline BlockBackend *nvme_blk(NvmeNamespace *ns) return NVME_NAMESPACE_NVM(ns)->blk; } +typedef struct NvmeNamespaceDevice { + DeviceState parent_obj; + BlockConf blkconf; + int32_t bootindex; + + NvmeNamespace ns; + NvmeNamespaceParams params; +} NvmeNamespaceDevice; + static inline uint32_t nvme_nsid(NvmeNamespace *ns) { if (ns) { - return ns->params.nsid; + return ns->nsid; } return 0; @@ -228,8 +242,8 @@ static inline bool nvme_ns_ext(NvmeNamespaceNvm *nvm) return !!NVME_ID_NS_FLBAS_EXTENDED(nvm->id_ns.flbas); } -void nvme_ns_init_format(NvmeNamespace *ns); -int nvme_ns_setup(NvmeNamespace *ns, Error **errp); +void nvme_ns_nvm_init_format(NvmeNamespaceNvm *nvm); +void nvme_ns_init(NvmeNamespace *ns); void nvme_ns_drain(NvmeNamespace *ns); void nvme_ns_shutdown(NvmeNamespace *ns); void nvme_ns_cleanup(NvmeNamespace *ns); @@ -424,7 +438,7 @@ typedef struct NvmeCtrl { NvmeSubsystem *subsys; - NvmeNamespace namespace; + NvmeNamespaceDevice namespace; NvmeNamespace *namespaces[NVME_MAX_NAMESPACES + 1]; NvmeSQueue **sq; NvmeCQueue **cq; diff --git a/hw/nvme/subsys.c b/hw/nvme/subsys.c index 6b2e4c975f5b..5a9405d05fbe 100644 --- a/hw/nvme/subsys.c +++ b/hw/nvme/subsys.c @@ -31,7 +31,7 @@ int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp) for (nsid = 1; nsid < ARRAY_SIZE(subsys->namespaces); nsid++) { NvmeNamespace *ns = subsys->namespaces[nsid]; - if (ns && ns->params.shared && !ns->params.detached) { + if (ns && (ns->flags & NVME_NS_SHARED)) { nvme_attach_ns(n, ns); } }