hw/block/nvme: introduce nvme-subsys device
To support multi-path in QEMU NVMe device model, We need to have NVMe subsystem hierarchy to map controllers and namespaces to a NVMe subsystem. This patch introduced a simple nvme-subsys device model. The subsystem will be prepared with subsystem NQN with <subsys_id> provided in nvme-subsys device: ex) -device nvme-subsys,id=subsys0: nqn.2019-08.org.qemu:subsys0 Signed-off-by: Minwoo Im <minwoo.im.dev@gmail.com> Tested-by: Klaus Jensen <k.jensen@samsung.com> Reviewed-by: Klaus Jensen <k.jensen@samsung.com> Reviewed-by: Keith Busch <kbusch@kernel.org> [k.jensen: added 'nqn' device parameter per request] Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
This commit is contained in:
parent
229a834518
commit
eb2e89747e
@ -13,7 +13,7 @@ softmmu_ss.add(when: 'CONFIG_SSI_M25P80', if_true: files('m25p80.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_SWIM', if_true: files('swim.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_XEN', if_true: files('xen-block.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_TC58128', if_true: files('tc58128.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_NVME_PCI', if_true: files('nvme.c', 'nvme-ns.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_NVME_PCI', if_true: files('nvme.c', 'nvme-ns.c', 'nvme-subsys.c'))
|
||||
|
||||
specific_ss.add(when: 'CONFIG_VIRTIO_BLK', if_true: files('virtio-blk.c'))
|
||||
specific_ss.add(when: 'CONFIG_VHOST_USER_BLK', if_true: files('vhost-user-blk.c'))
|
||||
|
70
hw/block/nvme-subsys.c
Normal file
70
hw/block/nvme-subsys.c
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* QEMU NVM Express Subsystem: nvme-subsys
|
||||
*
|
||||
* Copyright (c) 2021 Minwoo Im <minwoo.im.dev@gmail.com>
|
||||
*
|
||||
* This code is licensed under the GNU GPL v2. Refer COPYING.
|
||||
*/
|
||||
|
||||
#include "qemu/units.h"
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/uuid.h"
|
||||
#include "qemu/iov.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qapi/error.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/qdev-core.h"
|
||||
#include "hw/block/block.h"
|
||||
#include "block/aio.h"
|
||||
#include "block/accounting.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "nvme.h"
|
||||
#include "nvme-subsys.h"
|
||||
|
||||
static void nvme_subsys_setup(NvmeSubsystem *subsys)
|
||||
{
|
||||
const char *nqn = subsys->params.nqn ?
|
||||
subsys->params.nqn : subsys->parent_obj.id;
|
||||
|
||||
snprintf((char *)subsys->subnqn, sizeof(subsys->subnqn),
|
||||
"nqn.2019-08.org.qemu:%s", nqn);
|
||||
}
|
||||
|
||||
static void nvme_subsys_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
NvmeSubsystem *subsys = NVME_SUBSYS(dev);
|
||||
|
||||
nvme_subsys_setup(subsys);
|
||||
}
|
||||
|
||||
static Property nvme_subsystem_props[] = {
|
||||
DEFINE_PROP_STRING("nqn", NvmeSubsystem, params.nqn),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void nvme_subsys_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
|
||||
|
||||
dc->realize = nvme_subsys_realize;
|
||||
dc->desc = "Virtual NVMe subsystem";
|
||||
|
||||
device_class_set_props(dc, nvme_subsystem_props);
|
||||
}
|
||||
|
||||
static const TypeInfo nvme_subsys_info = {
|
||||
.name = TYPE_NVME_SUBSYS,
|
||||
.parent = TYPE_DEVICE,
|
||||
.class_init = nvme_subsys_class_init,
|
||||
.instance_size = sizeof(NvmeSubsystem),
|
||||
};
|
||||
|
||||
static void nvme_subsys_register_types(void)
|
||||
{
|
||||
type_register_static(&nvme_subsys_info);
|
||||
}
|
||||
|
||||
type_init(nvme_subsys_register_types)
|
29
hw/block/nvme-subsys.h
Normal file
29
hw/block/nvme-subsys.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* QEMU NVM Express Subsystem: nvme-subsys
|
||||
*
|
||||
* Copyright (c) 2021 Minwoo Im <minwoo.im.dev@gmail.com>
|
||||
*
|
||||
* This code is licensed under the GNU GPL v2. Refer COPYING.
|
||||
*/
|
||||
|
||||
#ifndef NVME_SUBSYS_H
|
||||
#define NVME_SUBSYS_H
|
||||
|
||||
#define TYPE_NVME_SUBSYS "nvme-subsys"
|
||||
#define NVME_SUBSYS(obj) \
|
||||
OBJECT_CHECK(NvmeSubsystem, (obj), TYPE_NVME_SUBSYS)
|
||||
|
||||
#define NVME_SUBSYS_MAX_CTRLS 32
|
||||
|
||||
typedef struct NvmeCtrl NvmeCtrl;
|
||||
typedef struct NvmeNamespace NvmeNamespace;
|
||||
typedef struct NvmeSubsystem {
|
||||
DeviceState parent_obj;
|
||||
uint8_t subnqn[256];
|
||||
|
||||
struct {
|
||||
char *nqn;
|
||||
} params;
|
||||
} NvmeSubsystem;
|
||||
|
||||
#endif /* NVME_SUBSYS_H */
|
@ -17,6 +17,7 @@
|
||||
/**
|
||||
* Usage: add options:
|
||||
* -drive file=<file>,if=none,id=<drive_id>
|
||||
* -device nvme-subsys,id=<subsys_id>,nqn=<nqn_id>
|
||||
* -device nvme,serial=<serial>,id=<bus_name>, \
|
||||
* cmb_size_mb=<cmb_size_mb[optional]>, \
|
||||
* [pmrdev=<mem_backend_file_id>,] \
|
||||
@ -38,6 +39,17 @@
|
||||
*
|
||||
* The PMR will use BAR 4/5 exclusively.
|
||||
*
|
||||
* To place controller(s) and namespace(s) to a subsystem, then provide
|
||||
* nvme-subsys device as above.
|
||||
*
|
||||
* nvme subsystem device parameters
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* - `nqn`
|
||||
* This parameter provides the `<nqn_id>` part of the string
|
||||
* `nqn.2019-08.org.qemu:<nqn_id>` which will be reported in the SUBNQN field
|
||||
* of subsystem controllers. Note that `<nqn_id>` should be unique per
|
||||
* subsystem, but this is not enforced by QEMU. If not specified, it will
|
||||
* default to the value of the `id` parameter (`<subsys_id>`).
|
||||
*
|
||||
* nvme device parameters
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
Loading…
Reference in New Issue
Block a user