Hi,

I don't dig into code logic, just some nit below.

On 2021/3/1 0:10, Minwoo Im wrote:
> Given that now we have nvme-subsys device supported, we can manage
> namespace allocated, but not attached: detached.  This patch introduced
s/introduced/introduces

> a parameter for nvme-ns device named 'detached'.  This parameter
> indicates whether the given namespace device is detached from
> a entire NVMe subsystem('subsys' given case, shared namespace) or a
> controller('bus' given case, private namespace).
> 
> - Allocated namespace
> 
>   1) Shared ns in the subsystem 'subsys0':
> 
>      -device nvme-ns,id=ns1,drive=blknvme0,nsid=1,subsys=subsys0,detached=true
> 
>   2) Private ns for the controller 'nvme0' of the subsystem 'subsys0':
> 
>      -device nvme-subsys,id=subsys0
>      -device nvme,serial=foo,id=nvme0,subsys=subsys0
>      -device nvme-ns,id=ns1,drive=blknvme0,nsid=1,bus=nvme0,detached=true
> 
>   3) (Invalid case) Controller 'nvme0' has no subsystem to manage ns:
> 
>      -device nvme,serial=foo,id=nvme0
>      -device nvme-ns,id=ns1,drive=blknvme0,nsid=1,bus=nvme0,detached=true
> 
> Signed-off-by: Minwoo Im <minwoo.im....@gmail.com>
> Tested-by: Klaus Jensen <k.jen...@samsung.com>
> Reviewed-by: Klaus Jensen <k.jen...@samsung.com>
> ---
>  hw/block/nvme-ns.c     |  1 +
>  hw/block/nvme-ns.h     |  1 +
>  hw/block/nvme-subsys.h |  1 +
>  hw/block/nvme.c        | 41 +++++++++++++++++++++++++++++++++++++++--
>  hw/block/nvme.h        | 22 ++++++++++++++++++++++
>  5 files changed, 64 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c
> index 0e8760020483..eda6a0c003a4 100644
> --- a/hw/block/nvme-ns.c
> +++ b/hw/block/nvme-ns.c
> @@ -399,6 +399,7 @@ static Property nvme_ns_props[] = {
>      DEFINE_BLOCK_PROPERTIES(NvmeNamespace, blkconf),
>      DEFINE_PROP_LINK("subsys", NvmeNamespace, subsys, TYPE_NVME_SUBSYS,
>                       NvmeSubsystem *),
> +    DEFINE_PROP_BOOL("detached", NvmeNamespace, params.detached, false),
>      DEFINE_PROP_UINT32("nsid", NvmeNamespace, params.nsid, 0),
>      DEFINE_PROP_UUID("uuid", NvmeNamespace, params.uuid),
>      DEFINE_PROP_UINT16("mssrl", NvmeNamespace, params.mssrl, 128),
> diff --git a/hw/block/nvme-ns.h b/hw/block/nvme-ns.h
> index 7af6884862b5..b0c00e115d81 100644
> --- a/hw/block/nvme-ns.h
> +++ b/hw/block/nvme-ns.h
> @@ -26,6 +26,7 @@ typedef struct NvmeZone {
>  } NvmeZone;
>  
>  typedef struct NvmeNamespaceParams {
> +    bool     detached;
>      uint32_t nsid;
>      QemuUUID uuid;
>  
> diff --git a/hw/block/nvme-subsys.h b/hw/block/nvme-subsys.h
> index ccf6a71398d3..890d118117dc 100644
> --- a/hw/block/nvme-subsys.h
> +++ b/hw/block/nvme-subsys.h
> @@ -23,6 +23,7 @@ typedef struct NvmeSubsystem {
>      uint8_t     subnqn[256];
>  
>      NvmeCtrl    *ctrls[NVME_SUBSYS_MAX_CTRLS];
> +    /* Allocated namespaces for this subsystem */
>      NvmeNamespace *namespaces[NVME_SUBSYS_MAX_NAMESPACES];
>  } NvmeSubsystem;
>  
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index edd0b85c10ce..f6aeae081840 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -23,7 +23,7 @@
>   *              max_ioqpairs=<N[optional]>, \
>   *              aerl=<N[optional]>, aer_max_queued=<N[optional]>, \
>   *              mdts=<N[optional]>,zoned.append_size_limit=<N[optional]>, \
> - *              subsys=<subsys_id> \
> + *              subsys=<subsys_id>,detached=<true|false[optional]>
>   *      -device nvme-ns,drive=<drive_id>,bus=<bus_name>,nsid=<nsid>,\
>   *              zoned=<true|false[optional]>, \
>   *              subsys=<subsys_id>
> @@ -82,6 +82,13 @@
>   *   controllers in the subsystem. Otherwise, `bus` must be given to attach
>   *   this namespace to a specified single controller as a non-shared 
> namespace.
>   *
> + * - `detached`
> + *   Not to attach the namespace device to controllers in the NVMe subsystem
> + *   during boot-up. If not given, namespaces are all attahced to all
s/attahced/attached

> + *   controllers in the subsystem by default.
> + *   It's mutual exclusive with 'bus' parameter. It's only valid in case
> + *   `subsys` is provided.
> + *
>   * Setting `zoned` to true selects Zoned Command Set at the namespace.
>   * In this case, the following namespace properties are available to 
> configure
>   * zoned operation:
> @@ -4613,6 +4620,20 @@ static void nvme_init_state(NvmeCtrl *n)
>      n->aer_reqs = g_new0(NvmeRequest *, n->params.aerl + 1);
>  }
>  
> +static int nvme_attach_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error 
> **errp)
> +{
> +    if (nvme_ns_is_attached(n, ns)) {
> +        error_setg(errp,
> +                   "namespace %d is already attached to controller %d",
> +                   nvme_nsid(ns), n->cntlid);
> +        return -1;
> +    }
> +
> +    nvme_ns_attach(n, ns);
> +
> +    return 0;
> +}
> +
>  int nvme_register_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error **errp)
>  {
>      uint32_t nsid = nvme_nsid(ns);
> @@ -4644,7 +4665,23 @@ int nvme_register_namespace(NvmeCtrl *n, NvmeNamespace 
> *ns, Error **errp)
>  
>      trace_pci_nvme_register_namespace(nsid);
>  
> -    n->namespaces[nsid - 1] = ns;
> +    /*
> +     * If subsys is not given, namespae is always attached to the controller
s/namespae/namespace

> +     * because there's no subsystem to manage namespace allocation.
> +     */
> +    if (!n->subsys) {
> +        if (ns->params.detached) {
> +            error_setg(errp,
> +                       "detached needs nvme-subsys specified nvme or 
> nvme-ns");
> +            return -1;
> +        }
> +
> +        return nvme_attach_namespace(n, ns, errp);
> +    } else {
> +        if (!ns->params.detached) {
> +            return nvme_attach_namespace(n, ns, errp);
> +        }
> +    }
>  
>      return 0;
>  }
> diff --git a/hw/block/nvme.h b/hw/block/nvme.h
> index f45ace0cff5b..51b8739b4d1e 100644
> --- a/hw/block/nvme.h
> +++ b/hw/block/nvme.h
> @@ -174,6 +174,10 @@ typedef struct NvmeCtrl {
>      NvmeSubsystem   *subsys;
>  
>      NvmeNamespace   namespace;
> +    /*
> +     * Attached namespaces to this controller.  If subsys is not given, all
> +     * namespaces in this list will always be attached.
> +     */
>      NvmeNamespace   *namespaces[NVME_MAX_NAMESPACES];
>      NvmeSQueue      **sq;
>      NvmeCQueue      **cq;
> @@ -192,6 +196,24 @@ static inline NvmeNamespace *nvme_ns(NvmeCtrl *n, 
> uint32_t nsid)
>      return n->namespaces[nsid - 1];
>  }
>  
> +static inline bool nvme_ns_is_attached(NvmeCtrl *n, NvmeNamespace *ns)
> +{
> +    int nsid;
> +
> +    for (nsid = 1; nsid <= n->num_namespaces; nsid++) {
> +        if (nvme_ns(n, nsid) == ns) {
> +            return true;
> +        }
> +    }
> +
> +    return false;
> +}
> +
> +static inline void nvme_ns_attach(NvmeCtrl *n, NvmeNamespace *ns)
> +{
> +    n->namespaces[nvme_nsid(ns) - 1] = ns;
> +}
> +
>  static inline NvmeCQueue *nvme_cq(NvmeRequest *req)
>  {
>      NvmeSQueue *sq = req->sq;
> 

Reply via email to