blob: 35314d96b4dbdb7415633dc8a0788c90cfc4ecad [file] [log] [blame]
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +02001/*
2 * NVMe over Fabrics loopback device.
3 * Copyright (c) 2015-2016 HGST, a Western Digital Company.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15#include <linux/scatterlist.h>
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +020016#include <linux/blk-mq.h>
17#include <linux/nvme.h>
18#include <linux/module.h>
19#include <linux/parser.h>
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +020020#include "nvmet.h"
21#include "../host/nvme.h"
22#include "../host/fabrics.h"
23
24#define NVME_LOOP_AQ_DEPTH 256
25
26#define NVME_LOOP_MAX_SEGMENTS 256
27
28/*
29 * We handle AEN commands ourselves and don't even let the
30 * block layer know about them.
31 */
32#define NVME_LOOP_NR_AEN_COMMANDS 1
33#define NVME_LOOP_AQ_BLKMQ_DEPTH \
34 (NVME_LOOP_AQ_DEPTH - NVME_LOOP_NR_AEN_COMMANDS)
35
36struct nvme_loop_iod {
Christoph Hellwigd49187e2016-11-10 07:32:33 -080037 struct nvme_request nvme_req;
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +020038 struct nvme_command cmd;
39 struct nvme_completion rsp;
40 struct nvmet_req req;
41 struct nvme_loop_queue *queue;
42 struct work_struct work;
43 struct sg_table sg_table;
44 struct scatterlist first_sgl[];
45};
46
47struct nvme_loop_ctrl {
48 spinlock_t lock;
49 struct nvme_loop_queue *queues;
50 u32 queue_count;
51
52 struct blk_mq_tag_set admin_tag_set;
53
54 struct list_head list;
55 u64 cap;
56 struct blk_mq_tag_set tag_set;
57 struct nvme_loop_iod async_event_iod;
58 struct nvme_ctrl ctrl;
59
60 struct nvmet_ctrl *target_ctrl;
61 struct work_struct delete_work;
62 struct work_struct reset_work;
63};
64
65static inline struct nvme_loop_ctrl *to_loop_ctrl(struct nvme_ctrl *ctrl)
66{
67 return container_of(ctrl, struct nvme_loop_ctrl, ctrl);
68}
69
70struct nvme_loop_queue {
71 struct nvmet_cq nvme_cq;
72 struct nvmet_sq nvme_sq;
73 struct nvme_loop_ctrl *ctrl;
74};
75
76static struct nvmet_port *nvmet_loop_port;
77
78static LIST_HEAD(nvme_loop_ctrl_list);
79static DEFINE_MUTEX(nvme_loop_ctrl_mutex);
80
81static void nvme_loop_queue_response(struct nvmet_req *nvme_req);
82static void nvme_loop_delete_ctrl(struct nvmet_ctrl *ctrl);
83
84static struct nvmet_fabrics_ops nvme_loop_ops;
85
86static inline int nvme_loop_queue_idx(struct nvme_loop_queue *queue)
87{
88 return queue - queue->ctrl->queues;
89}
90
91static void nvme_loop_complete_rq(struct request *req)
92{
93 struct nvme_loop_iod *iod = blk_mq_rq_to_pdu(req);
94 int error = 0;
95
96 nvme_cleanup_cmd(req);
97 sg_free_table_chained(&iod->sg_table, true);
98
99 if (unlikely(req->errors)) {
100 if (nvme_req_needs_retry(req, req->errors)) {
101 nvme_requeue_req(req);
102 return;
103 }
104
Christoph Hellwig57292b52017-01-31 16:57:29 +0100105 if (blk_rq_is_passthrough(req))
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200106 error = req->errors;
107 else
108 error = nvme_error_status(req->errors);
109 }
110
111 blk_mq_end_request(req, error);
112}
113
Sagi Grimberg3b068372017-02-27 18:28:25 +0200114static struct blk_mq_tags *nvme_loop_tagset(struct nvme_loop_queue *queue)
115{
116 u32 queue_idx = nvme_loop_queue_idx(queue);
117
118 if (queue_idx == 0)
119 return queue->ctrl->admin_tag_set.tags[queue_idx];
120 return queue->ctrl->tag_set.tags[queue_idx - 1];
121}
122
Christoph Hellwigd49187e2016-11-10 07:32:33 -0800123static void nvme_loop_queue_response(struct nvmet_req *req)
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200124{
Sagi Grimberg3b068372017-02-27 18:28:25 +0200125 struct nvme_loop_queue *queue =
126 container_of(req->sq, struct nvme_loop_queue, nvme_sq);
127 struct nvme_completion *cqe = req->rsp;
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200128
129 /*
130 * AEN requests are special as they don't time out and can
131 * survive any kind of queue freeze and often don't respond to
132 * aborts. We don't even bother to allocate a struct request
133 * for them but rather special case them here.
134 */
Sagi Grimberg3b068372017-02-27 18:28:25 +0200135 if (unlikely(nvme_loop_queue_idx(queue) == 0 &&
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200136 cqe->command_id >= NVME_LOOP_AQ_BLKMQ_DEPTH)) {
Sagi Grimberg3b068372017-02-27 18:28:25 +0200137 nvme_complete_async_event(&queue->ctrl->ctrl, cqe->status,
Christoph Hellwig7bf58532016-11-10 07:32:34 -0800138 &cqe->result);
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200139 } else {
Sagi Grimberg3b068372017-02-27 18:28:25 +0200140 struct request *rq;
141 struct nvme_loop_iod *iod;
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200142
Sagi Grimberg3b068372017-02-27 18:28:25 +0200143 rq = blk_mq_tag_to_rq(nvme_loop_tagset(queue), cqe->command_id);
144 if (!rq) {
145 dev_err(queue->ctrl->ctrl.device,
146 "tag 0x%x on queue %d not found\n",
147 cqe->command_id, nvme_loop_queue_idx(queue));
148 return;
149 }
150
151 iod = blk_mq_rq_to_pdu(rq);
Christoph Hellwigd49187e2016-11-10 07:32:33 -0800152 iod->nvme_req.result = cqe->result;
153 blk_mq_complete_request(rq, le16_to_cpu(cqe->status) >> 1);
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200154 }
155}
156
157static void nvme_loop_execute_work(struct work_struct *work)
158{
159 struct nvme_loop_iod *iod =
160 container_of(work, struct nvme_loop_iod, work);
161
162 iod->req.execute(&iod->req);
163}
164
165static enum blk_eh_timer_return
166nvme_loop_timeout(struct request *rq, bool reserved)
167{
168 struct nvme_loop_iod *iod = blk_mq_rq_to_pdu(rq);
169
170 /* queue error recovery */
171 schedule_work(&iod->queue->ctrl->reset_work);
172
173 /* fail with DNR on admin cmd timeout */
174 rq->errors = NVME_SC_ABORT_REQ | NVME_SC_DNR;
175
176 return BLK_EH_HANDLED;
177}
178
179static int nvme_loop_queue_rq(struct blk_mq_hw_ctx *hctx,
180 const struct blk_mq_queue_data *bd)
181{
182 struct nvme_ns *ns = hctx->queue->queuedata;
183 struct nvme_loop_queue *queue = hctx->driver_data;
184 struct request *req = bd->rq;
185 struct nvme_loop_iod *iod = blk_mq_rq_to_pdu(req);
186 int ret;
187
188 ret = nvme_setup_cmd(ns, req, &iod->cmd);
Omar Sandovalbac00002016-11-15 11:11:58 -0800189 if (ret != BLK_MQ_RQ_QUEUE_OK)
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200190 return ret;
191
192 iod->cmd.common.flags |= NVME_CMD_SGL_METABUF;
193 iod->req.port = nvmet_loop_port;
194 if (!nvmet_req_init(&iod->req, &queue->nvme_cq,
195 &queue->nvme_sq, &nvme_loop_ops)) {
196 nvme_cleanup_cmd(req);
197 blk_mq_start_request(req);
198 nvme_loop_queue_response(&iod->req);
Omar Sandovalbac00002016-11-15 11:11:58 -0800199 return BLK_MQ_RQ_QUEUE_OK;
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200200 }
201
202 if (blk_rq_bytes(req)) {
203 iod->sg_table.sgl = iod->first_sgl;
204 ret = sg_alloc_table_chained(&iod->sg_table,
Christoph Hellwigf9d03f92016-12-08 15:20:32 -0700205 blk_rq_nr_phys_segments(req),
206 iod->sg_table.sgl);
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200207 if (ret)
208 return BLK_MQ_RQ_QUEUE_BUSY;
209
210 iod->req.sg = iod->sg_table.sgl;
211 iod->req.sg_cnt = blk_rq_map_sg(req->q, req, iod->sg_table.sgl);
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200212 }
213
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200214 blk_mq_start_request(req);
215
216 schedule_work(&iod->work);
Omar Sandovalbac00002016-11-15 11:11:58 -0800217 return BLK_MQ_RQ_QUEUE_OK;
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200218}
219
220static void nvme_loop_submit_async_event(struct nvme_ctrl *arg, int aer_idx)
221{
222 struct nvme_loop_ctrl *ctrl = to_loop_ctrl(arg);
223 struct nvme_loop_queue *queue = &ctrl->queues[0];
224 struct nvme_loop_iod *iod = &ctrl->async_event_iod;
225
226 memset(&iod->cmd, 0, sizeof(iod->cmd));
227 iod->cmd.common.opcode = nvme_admin_async_event;
228 iod->cmd.common.command_id = NVME_LOOP_AQ_BLKMQ_DEPTH;
229 iod->cmd.common.flags |= NVME_CMD_SGL_METABUF;
230
231 if (!nvmet_req_init(&iod->req, &queue->nvme_cq, &queue->nvme_sq,
232 &nvme_loop_ops)) {
233 dev_err(ctrl->ctrl.device, "failed async event work\n");
234 return;
235 }
236
237 schedule_work(&iod->work);
238}
239
240static int nvme_loop_init_iod(struct nvme_loop_ctrl *ctrl,
241 struct nvme_loop_iod *iod, unsigned int queue_idx)
242{
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200243 iod->req.cmd = &iod->cmd;
244 iod->req.rsp = &iod->rsp;
245 iod->queue = &ctrl->queues[queue_idx];
246 INIT_WORK(&iod->work, nvme_loop_execute_work);
247 return 0;
248}
249
250static int nvme_loop_init_request(void *data, struct request *req,
251 unsigned int hctx_idx, unsigned int rq_idx,
252 unsigned int numa_node)
253{
254 return nvme_loop_init_iod(data, blk_mq_rq_to_pdu(req), hctx_idx + 1);
255}
256
257static int nvme_loop_init_admin_request(void *data, struct request *req,
258 unsigned int hctx_idx, unsigned int rq_idx,
259 unsigned int numa_node)
260{
261 return nvme_loop_init_iod(data, blk_mq_rq_to_pdu(req), 0);
262}
263
264static int nvme_loop_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
265 unsigned int hctx_idx)
266{
267 struct nvme_loop_ctrl *ctrl = data;
268 struct nvme_loop_queue *queue = &ctrl->queues[hctx_idx + 1];
269
270 BUG_ON(hctx_idx >= ctrl->queue_count);
271
272 hctx->driver_data = queue;
273 return 0;
274}
275
276static int nvme_loop_init_admin_hctx(struct blk_mq_hw_ctx *hctx, void *data,
277 unsigned int hctx_idx)
278{
279 struct nvme_loop_ctrl *ctrl = data;
280 struct nvme_loop_queue *queue = &ctrl->queues[0];
281
282 BUG_ON(hctx_idx != 0);
283
284 hctx->driver_data = queue;
285 return 0;
286}
287
Eric Biggersf363b082017-03-30 13:39:16 -0700288static const struct blk_mq_ops nvme_loop_mq_ops = {
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200289 .queue_rq = nvme_loop_queue_rq,
290 .complete = nvme_loop_complete_rq,
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200291 .init_request = nvme_loop_init_request,
292 .init_hctx = nvme_loop_init_hctx,
293 .timeout = nvme_loop_timeout,
294};
295
Eric Biggersf363b082017-03-30 13:39:16 -0700296static const struct blk_mq_ops nvme_loop_admin_mq_ops = {
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200297 .queue_rq = nvme_loop_queue_rq,
298 .complete = nvme_loop_complete_rq,
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200299 .init_request = nvme_loop_init_admin_request,
300 .init_hctx = nvme_loop_init_admin_hctx,
301 .timeout = nvme_loop_timeout,
302};
303
304static void nvme_loop_destroy_admin_queue(struct nvme_loop_ctrl *ctrl)
305{
Sagi Grimbergd4769832017-02-27 18:44:45 +0200306 nvmet_sq_destroy(&ctrl->queues[0].nvme_sq);
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200307 blk_cleanup_queue(ctrl->ctrl.admin_q);
308 blk_mq_free_tag_set(&ctrl->admin_tag_set);
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200309}
310
311static void nvme_loop_free_ctrl(struct nvme_ctrl *nctrl)
312{
313 struct nvme_loop_ctrl *ctrl = to_loop_ctrl(nctrl);
314
315 if (list_empty(&ctrl->list))
316 goto free_ctrl;
317
318 mutex_lock(&nvme_loop_ctrl_mutex);
319 list_del(&ctrl->list);
320 mutex_unlock(&nvme_loop_ctrl_mutex);
321
322 if (nctrl->tagset) {
323 blk_cleanup_queue(ctrl->ctrl.connect_q);
324 blk_mq_free_tag_set(&ctrl->tag_set);
325 }
326 kfree(ctrl->queues);
327 nvmf_free_options(nctrl->opts);
328free_ctrl:
329 kfree(ctrl);
330}
331
Sagi Grimberg6ecda702017-03-13 13:27:51 +0200332static void nvme_loop_destroy_io_queues(struct nvme_loop_ctrl *ctrl)
333{
334 int i;
335
336 for (i = 1; i < ctrl->queue_count; i++)
337 nvmet_sq_destroy(&ctrl->queues[i].nvme_sq);
338}
339
340static int nvme_loop_init_io_queues(struct nvme_loop_ctrl *ctrl)
341{
342 struct nvmf_ctrl_options *opts = ctrl->ctrl.opts;
343 unsigned int nr_io_queues;
344 int ret, i;
345
346 nr_io_queues = min(opts->nr_io_queues, num_online_cpus());
347 ret = nvme_set_queue_count(&ctrl->ctrl, &nr_io_queues);
348 if (ret || !nr_io_queues)
349 return ret;
350
351 dev_info(ctrl->ctrl.device, "creating %d I/O queues.\n", nr_io_queues);
352
353 for (i = 1; i <= nr_io_queues; i++) {
354 ctrl->queues[i].ctrl = ctrl;
355 ret = nvmet_sq_init(&ctrl->queues[i].nvme_sq);
356 if (ret)
357 goto out_destroy_queues;
358
359 ctrl->queue_count++;
360 }
361
362 return 0;
363
364out_destroy_queues:
365 nvme_loop_destroy_io_queues(ctrl);
366 return ret;
367}
368
Sagi Grimberg297186d2017-03-13 15:43:44 +0200369static int nvme_loop_connect_io_queues(struct nvme_loop_ctrl *ctrl)
370{
371 int i, ret;
372
373 for (i = 1; i < ctrl->queue_count; i++) {
374 ret = nvmf_connect_io_queue(&ctrl->ctrl, i);
375 if (ret)
376 return ret;
377 }
378
379 return 0;
380}
381
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200382static int nvme_loop_configure_admin_queue(struct nvme_loop_ctrl *ctrl)
383{
384 int error;
385
386 memset(&ctrl->admin_tag_set, 0, sizeof(ctrl->admin_tag_set));
387 ctrl->admin_tag_set.ops = &nvme_loop_admin_mq_ops;
388 ctrl->admin_tag_set.queue_depth = NVME_LOOP_AQ_BLKMQ_DEPTH;
389 ctrl->admin_tag_set.reserved_tags = 2; /* connect + keep-alive */
390 ctrl->admin_tag_set.numa_node = NUMA_NO_NODE;
391 ctrl->admin_tag_set.cmd_size = sizeof(struct nvme_loop_iod) +
392 SG_CHUNK_SIZE * sizeof(struct scatterlist);
393 ctrl->admin_tag_set.driver_data = ctrl;
394 ctrl->admin_tag_set.nr_hw_queues = 1;
395 ctrl->admin_tag_set.timeout = ADMIN_TIMEOUT;
396
397 ctrl->queues[0].ctrl = ctrl;
398 error = nvmet_sq_init(&ctrl->queues[0].nvme_sq);
399 if (error)
400 return error;
401 ctrl->queue_count = 1;
402
403 error = blk_mq_alloc_tag_set(&ctrl->admin_tag_set);
404 if (error)
405 goto out_free_sq;
406
407 ctrl->ctrl.admin_q = blk_mq_init_queue(&ctrl->admin_tag_set);
408 if (IS_ERR(ctrl->ctrl.admin_q)) {
409 error = PTR_ERR(ctrl->ctrl.admin_q);
410 goto out_free_tagset;
411 }
412
413 error = nvmf_connect_admin_queue(&ctrl->ctrl);
414 if (error)
415 goto out_cleanup_queue;
416
417 error = nvmf_reg_read64(&ctrl->ctrl, NVME_REG_CAP, &ctrl->cap);
418 if (error) {
419 dev_err(ctrl->ctrl.device,
420 "prop_get NVME_REG_CAP failed\n");
421 goto out_cleanup_queue;
422 }
423
424 ctrl->ctrl.sqsize =
425 min_t(int, NVME_CAP_MQES(ctrl->cap) + 1, ctrl->ctrl.sqsize);
426
427 error = nvme_enable_ctrl(&ctrl->ctrl, ctrl->cap);
428 if (error)
429 goto out_cleanup_queue;
430
431 ctrl->ctrl.max_hw_sectors =
432 (NVME_LOOP_MAX_SEGMENTS - 1) << (PAGE_SHIFT - 9);
433
434 error = nvme_init_identify(&ctrl->ctrl);
435 if (error)
436 goto out_cleanup_queue;
437
438 nvme_start_keep_alive(&ctrl->ctrl);
439
440 return 0;
441
442out_cleanup_queue:
443 blk_cleanup_queue(ctrl->ctrl.admin_q);
444out_free_tagset:
445 blk_mq_free_tag_set(&ctrl->admin_tag_set);
446out_free_sq:
447 nvmet_sq_destroy(&ctrl->queues[0].nvme_sq);
448 return error;
449}
450
451static void nvme_loop_shutdown_ctrl(struct nvme_loop_ctrl *ctrl)
452{
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200453 nvme_stop_keep_alive(&ctrl->ctrl);
454
455 if (ctrl->queue_count > 1) {
456 nvme_stop_queues(&ctrl->ctrl);
457 blk_mq_tagset_busy_iter(&ctrl->tag_set,
458 nvme_cancel_request, &ctrl->ctrl);
Sagi Grimberg6ecda702017-03-13 13:27:51 +0200459 nvme_loop_destroy_io_queues(ctrl);
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200460 }
461
462 if (ctrl->ctrl.state == NVME_CTRL_LIVE)
463 nvme_shutdown_ctrl(&ctrl->ctrl);
464
465 blk_mq_stop_hw_queues(ctrl->ctrl.admin_q);
466 blk_mq_tagset_busy_iter(&ctrl->admin_tag_set,
467 nvme_cancel_request, &ctrl->ctrl);
468 nvme_loop_destroy_admin_queue(ctrl);
469}
470
471static void nvme_loop_del_ctrl_work(struct work_struct *work)
472{
473 struct nvme_loop_ctrl *ctrl = container_of(work,
474 struct nvme_loop_ctrl, delete_work);
475
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200476 nvme_uninit_ctrl(&ctrl->ctrl);
Sagi Grimberga159c642016-07-24 09:32:08 +0300477 nvme_loop_shutdown_ctrl(ctrl);
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200478 nvme_put_ctrl(&ctrl->ctrl);
479}
480
481static int __nvme_loop_del_ctrl(struct nvme_loop_ctrl *ctrl)
482{
483 if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING))
484 return -EBUSY;
485
486 if (!schedule_work(&ctrl->delete_work))
487 return -EBUSY;
488
489 return 0;
490}
491
492static int nvme_loop_del_ctrl(struct nvme_ctrl *nctrl)
493{
494 struct nvme_loop_ctrl *ctrl = to_loop_ctrl(nctrl);
495 int ret;
496
497 ret = __nvme_loop_del_ctrl(ctrl);
498 if (ret)
499 return ret;
500
501 flush_work(&ctrl->delete_work);
502
503 return 0;
504}
505
506static void nvme_loop_delete_ctrl(struct nvmet_ctrl *nctrl)
507{
508 struct nvme_loop_ctrl *ctrl;
509
510 mutex_lock(&nvme_loop_ctrl_mutex);
511 list_for_each_entry(ctrl, &nvme_loop_ctrl_list, list) {
512 if (ctrl->ctrl.cntlid == nctrl->cntlid)
513 __nvme_loop_del_ctrl(ctrl);
514 }
515 mutex_unlock(&nvme_loop_ctrl_mutex);
516}
517
518static void nvme_loop_reset_ctrl_work(struct work_struct *work)
519{
520 struct nvme_loop_ctrl *ctrl = container_of(work,
521 struct nvme_loop_ctrl, reset_work);
522 bool changed;
Sagi Grimberg297186d2017-03-13 15:43:44 +0200523 int ret;
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200524
525 nvme_loop_shutdown_ctrl(ctrl);
526
527 ret = nvme_loop_configure_admin_queue(ctrl);
528 if (ret)
529 goto out_disable;
530
Sagi Grimberg6ecda702017-03-13 13:27:51 +0200531 ret = nvme_loop_init_io_queues(ctrl);
532 if (ret)
533 goto out_destroy_admin;
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200534
Sagi Grimberg297186d2017-03-13 15:43:44 +0200535 ret = nvme_loop_connect_io_queues(ctrl);
536 if (ret)
537 goto out_destroy_io;
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200538
539 changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE);
540 WARN_ON_ONCE(!changed);
541
542 nvme_queue_scan(&ctrl->ctrl);
543 nvme_queue_async_events(&ctrl->ctrl);
544
545 nvme_start_queues(&ctrl->ctrl);
546
547 return;
548
Sagi Grimberg6ecda702017-03-13 13:27:51 +0200549out_destroy_io:
550 nvme_loop_destroy_io_queues(ctrl);
551out_destroy_admin:
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200552 nvme_loop_destroy_admin_queue(ctrl);
553out_disable:
554 dev_warn(ctrl->ctrl.device, "Removing after reset failure\n");
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200555 nvme_uninit_ctrl(&ctrl->ctrl);
556 nvme_put_ctrl(&ctrl->ctrl);
557}
558
559static int nvme_loop_reset_ctrl(struct nvme_ctrl *nctrl)
560{
561 struct nvme_loop_ctrl *ctrl = to_loop_ctrl(nctrl);
562
563 if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RESETTING))
564 return -EBUSY;
565
566 if (!schedule_work(&ctrl->reset_work))
567 return -EBUSY;
568
569 flush_work(&ctrl->reset_work);
570
571 return 0;
572}
573
574static const struct nvme_ctrl_ops nvme_loop_ctrl_ops = {
575 .name = "loop",
576 .module = THIS_MODULE,
577 .is_fabrics = true,
578 .reg_read32 = nvmf_reg_read32,
579 .reg_read64 = nvmf_reg_read64,
580 .reg_write32 = nvmf_reg_write32,
581 .reset_ctrl = nvme_loop_reset_ctrl,
582 .free_ctrl = nvme_loop_free_ctrl,
583 .submit_async_event = nvme_loop_submit_async_event,
584 .delete_ctrl = nvme_loop_del_ctrl,
585 .get_subsysnqn = nvmf_get_subsysnqn,
586};
587
588static int nvme_loop_create_io_queues(struct nvme_loop_ctrl *ctrl)
589{
Sagi Grimberg297186d2017-03-13 15:43:44 +0200590 int ret;
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200591
Sagi Grimberg6ecda702017-03-13 13:27:51 +0200592 ret = nvme_loop_init_io_queues(ctrl);
593 if (ret)
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200594 return ret;
595
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200596 memset(&ctrl->tag_set, 0, sizeof(ctrl->tag_set));
597 ctrl->tag_set.ops = &nvme_loop_mq_ops;
Jay Freyenseeeadb7cf2016-08-17 15:00:28 -0700598 ctrl->tag_set.queue_depth = ctrl->ctrl.opts->queue_size;
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200599 ctrl->tag_set.reserved_tags = 1; /* fabric connect */
600 ctrl->tag_set.numa_node = NUMA_NO_NODE;
601 ctrl->tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
602 ctrl->tag_set.cmd_size = sizeof(struct nvme_loop_iod) +
603 SG_CHUNK_SIZE * sizeof(struct scatterlist);
604 ctrl->tag_set.driver_data = ctrl;
605 ctrl->tag_set.nr_hw_queues = ctrl->queue_count - 1;
606 ctrl->tag_set.timeout = NVME_IO_TIMEOUT;
607 ctrl->ctrl.tagset = &ctrl->tag_set;
608
609 ret = blk_mq_alloc_tag_set(&ctrl->tag_set);
610 if (ret)
611 goto out_destroy_queues;
612
613 ctrl->ctrl.connect_q = blk_mq_init_queue(&ctrl->tag_set);
614 if (IS_ERR(ctrl->ctrl.connect_q)) {
615 ret = PTR_ERR(ctrl->ctrl.connect_q);
616 goto out_free_tagset;
617 }
618
Sagi Grimberg297186d2017-03-13 15:43:44 +0200619 ret = nvme_loop_connect_io_queues(ctrl);
620 if (ret)
621 goto out_cleanup_connect_q;
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200622
623 return 0;
624
625out_cleanup_connect_q:
626 blk_cleanup_queue(ctrl->ctrl.connect_q);
627out_free_tagset:
628 blk_mq_free_tag_set(&ctrl->tag_set);
629out_destroy_queues:
Sagi Grimberg6ecda702017-03-13 13:27:51 +0200630 nvme_loop_destroy_io_queues(ctrl);
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200631 return ret;
632}
633
634static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev,
635 struct nvmf_ctrl_options *opts)
636{
637 struct nvme_loop_ctrl *ctrl;
638 bool changed;
639 int ret;
640
641 ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
642 if (!ctrl)
643 return ERR_PTR(-ENOMEM);
644 ctrl->ctrl.opts = opts;
645 INIT_LIST_HEAD(&ctrl->list);
646
647 INIT_WORK(&ctrl->delete_work, nvme_loop_del_ctrl_work);
648 INIT_WORK(&ctrl->reset_work, nvme_loop_reset_ctrl_work);
649
650 ret = nvme_init_ctrl(&ctrl->ctrl, dev, &nvme_loop_ctrl_ops,
651 0 /* no quirks, we're perfect! */);
652 if (ret)
653 goto out_put_ctrl;
654
655 spin_lock_init(&ctrl->lock);
656
657 ret = -ENOMEM;
658
Jay Freyenseeeadb7cf2016-08-17 15:00:28 -0700659 ctrl->ctrl.sqsize = opts->queue_size - 1;
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200660 ctrl->ctrl.kato = opts->kato;
661
662 ctrl->queues = kcalloc(opts->nr_io_queues + 1, sizeof(*ctrl->queues),
663 GFP_KERNEL);
664 if (!ctrl->queues)
665 goto out_uninit_ctrl;
666
667 ret = nvme_loop_configure_admin_queue(ctrl);
668 if (ret)
669 goto out_free_queues;
670
671 if (opts->queue_size > ctrl->ctrl.maxcmd) {
672 /* warn if maxcmd is lower than queue_size */
673 dev_warn(ctrl->ctrl.device,
674 "queue_size %zu > ctrl maxcmd %u, clamping down\n",
675 opts->queue_size, ctrl->ctrl.maxcmd);
676 opts->queue_size = ctrl->ctrl.maxcmd;
677 }
678
679 if (opts->nr_io_queues) {
680 ret = nvme_loop_create_io_queues(ctrl);
681 if (ret)
682 goto out_remove_admin_queue;
683 }
684
685 nvme_loop_init_iod(ctrl, &ctrl->async_event_iod, 0);
686
687 dev_info(ctrl->ctrl.device,
688 "new ctrl: \"%s\"\n", ctrl->ctrl.opts->subsysnqn);
689
690 kref_get(&ctrl->ctrl.kref);
691
692 changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE);
693 WARN_ON_ONCE(!changed);
694
695 mutex_lock(&nvme_loop_ctrl_mutex);
696 list_add_tail(&ctrl->list, &nvme_loop_ctrl_list);
697 mutex_unlock(&nvme_loop_ctrl_mutex);
698
699 if (opts->nr_io_queues) {
700 nvme_queue_scan(&ctrl->ctrl);
701 nvme_queue_async_events(&ctrl->ctrl);
702 }
703
704 return &ctrl->ctrl;
705
706out_remove_admin_queue:
707 nvme_loop_destroy_admin_queue(ctrl);
708out_free_queues:
709 kfree(ctrl->queues);
710out_uninit_ctrl:
711 nvme_uninit_ctrl(&ctrl->ctrl);
712out_put_ctrl:
713 nvme_put_ctrl(&ctrl->ctrl);
714 if (ret > 0)
715 ret = -EIO;
716 return ERR_PTR(ret);
717}
718
719static int nvme_loop_add_port(struct nvmet_port *port)
720{
721 /*
722 * XXX: disalow adding more than one port so
723 * there is no connection rejections when a
724 * a subsystem is assigned to a port for which
725 * loop doesn't have a pointer.
726 * This scenario would be possible if we allowed
727 * more than one port to be added and a subsystem
728 * was assigned to a port other than nvmet_loop_port.
729 */
730
731 if (nvmet_loop_port)
732 return -EPERM;
733
734 nvmet_loop_port = port;
735 return 0;
736}
737
738static void nvme_loop_remove_port(struct nvmet_port *port)
739{
740 if (port == nvmet_loop_port)
741 nvmet_loop_port = NULL;
742}
743
744static struct nvmet_fabrics_ops nvme_loop_ops = {
745 .owner = THIS_MODULE,
746 .type = NVMF_TRTYPE_LOOP,
747 .add_port = nvme_loop_add_port,
748 .remove_port = nvme_loop_remove_port,
749 .queue_response = nvme_loop_queue_response,
750 .delete_ctrl = nvme_loop_delete_ctrl,
751};
752
753static struct nvmf_transport_ops nvme_loop_transport = {
754 .name = "loop",
755 .create_ctrl = nvme_loop_create_ctrl,
756};
757
758static int __init nvme_loop_init_module(void)
759{
760 int ret;
761
762 ret = nvmet_register_transport(&nvme_loop_ops);
763 if (ret)
764 return ret;
Sagi Grimbergd19eef02017-03-19 06:26:28 +0200765
766 ret = nvmf_register_transport(&nvme_loop_transport);
767 if (ret)
768 nvmet_unregister_transport(&nvme_loop_ops);
769
770 return ret;
Christoph Hellwig3a85a5d2016-06-21 18:04:21 +0200771}
772
773static void __exit nvme_loop_cleanup_module(void)
774{
775 struct nvme_loop_ctrl *ctrl, *next;
776
777 nvmf_unregister_transport(&nvme_loop_transport);
778 nvmet_unregister_transport(&nvme_loop_ops);
779
780 mutex_lock(&nvme_loop_ctrl_mutex);
781 list_for_each_entry_safe(ctrl, next, &nvme_loop_ctrl_list, list)
782 __nvme_loop_del_ctrl(ctrl);
783 mutex_unlock(&nvme_loop_ctrl_mutex);
784
785 flush_scheduled_work();
786}
787
788module_init(nvme_loop_init_module);
789module_exit(nvme_loop_cleanup_module);
790
791MODULE_LICENSE("GPL v2");
792MODULE_ALIAS("nvmet-transport-254"); /* 254 == NVMF_TRTYPE_LOOP */