nvme-tcp-offload: Add device scan implementation
As part of create_ctrl(), it scans the registered devices and calls the claim_dev op on each of them, to find the first devices that matches the connection params. Once the correct devices is found (claim_dev returns true), we raise the refcnt of that device and return that device as the device to be used for ctrl currently being created. Acked-by: Igor Russkikh <irusskikh@marvell.com> Signed-off-by: Dean Balandin <dbalandin@marvell.com> Signed-off-by: Prabhakar Kushwaha <pkushwaha@marvell.com> Signed-off-by: Omkar Kulkarni <okulkarni@marvell.com> Signed-off-by: Michal Kalderon <mkalderon@marvell.com> Signed-off-by: Ariel Elior <aelior@marvell.com> Signed-off-by: Shai Malin <smalin@marvell.com> Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
af527935bd
Коммит
4b8178ec57
|
@ -13,6 +13,11 @@
|
|||
static LIST_HEAD(nvme_tcp_ofld_devices);
|
||||
static DEFINE_MUTEX(nvme_tcp_ofld_devices_mutex);
|
||||
|
||||
static inline struct nvme_tcp_ofld_ctrl *to_tcp_ofld_ctrl(struct nvme_ctrl *nctrl)
|
||||
{
|
||||
return container_of(nctrl, struct nvme_tcp_ofld_ctrl, nctrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* nvme_tcp_ofld_register_dev() - NVMeTCP Offload Library registration
|
||||
* function.
|
||||
|
@ -96,6 +101,77 @@ void nvme_tcp_ofld_req_done(struct nvme_tcp_ofld_req *req,
|
|||
/* Placeholder - complete request with/without error */
|
||||
}
|
||||
|
||||
static struct nvme_tcp_ofld_dev *
|
||||
nvme_tcp_ofld_lookup_dev(struct nvme_tcp_ofld_ctrl *ctrl)
|
||||
{
|
||||
struct nvme_tcp_ofld_dev *dev;
|
||||
|
||||
mutex_lock(&nvme_tcp_ofld_devices_mutex);
|
||||
list_for_each_entry(dev, &nvme_tcp_ofld_devices, entry) {
|
||||
if (dev->ops->claim_dev(dev, ctrl))
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev = NULL;
|
||||
out:
|
||||
mutex_unlock(&nvme_tcp_ofld_devices_mutex);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static struct nvme_ctrl *
|
||||
nvme_tcp_ofld_create_ctrl(struct device *ndev, struct nvmf_ctrl_options *opts)
|
||||
{
|
||||
struct nvme_tcp_ofld_ctrl *ctrl;
|
||||
struct nvme_tcp_ofld_dev *dev;
|
||||
struct nvme_ctrl *nctrl;
|
||||
int rc = 0;
|
||||
|
||||
ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
|
||||
if (!ctrl)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
nctrl = &ctrl->nctrl;
|
||||
|
||||
/* Init nvme_tcp_ofld_ctrl and nvme_ctrl params based on received opts */
|
||||
|
||||
/* Find device that can reach the dest addr */
|
||||
dev = nvme_tcp_ofld_lookup_dev(ctrl);
|
||||
if (!dev) {
|
||||
pr_info("no device found for addr %s:%s.\n",
|
||||
opts->traddr, opts->trsvcid);
|
||||
rc = -EINVAL;
|
||||
goto out_free_ctrl;
|
||||
}
|
||||
|
||||
/* Increase driver refcnt */
|
||||
if (!try_module_get(dev->ops->module)) {
|
||||
pr_err("try_module_get failed\n");
|
||||
dev = NULL;
|
||||
goto out_free_ctrl;
|
||||
}
|
||||
|
||||
ctrl->dev = dev;
|
||||
|
||||
if (ctrl->dev->ops->max_hw_sectors)
|
||||
nctrl->max_hw_sectors = ctrl->dev->ops->max_hw_sectors;
|
||||
if (ctrl->dev->ops->max_segments)
|
||||
nctrl->max_segments = ctrl->dev->ops->max_segments;
|
||||
|
||||
/* Init queues */
|
||||
|
||||
/* Call nvme_init_ctrl */
|
||||
|
||||
/* Setup ctrl */
|
||||
|
||||
return nctrl;
|
||||
|
||||
out_free_ctrl:
|
||||
kfree(ctrl);
|
||||
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
static struct nvmf_transport_ops nvme_tcp_ofld_transport = {
|
||||
.name = "tcp_offload",
|
||||
.module = THIS_MODULE,
|
||||
|
@ -105,6 +181,7 @@ static struct nvmf_transport_ops nvme_tcp_ofld_transport = {
|
|||
NVMF_OPT_RECONNECT_DELAY | NVMF_OPT_HDR_DIGEST |
|
||||
NVMF_OPT_DATA_DIGEST | NVMF_OPT_NR_POLL_QUEUES |
|
||||
NVMF_OPT_TOS,
|
||||
.create_ctrl = nvme_tcp_ofld_create_ctrl,
|
||||
};
|
||||
|
||||
static int __init nvme_tcp_ofld_init_module(void)
|
||||
|
|
Загрузка…
Ссылка в новой задаче