From 23fe8f8b1101ec77befc995ab15fad82d9d91d16 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 24 Mar 2015 16:22:32 -0700 Subject: block, drbd: fix drbd_req_new() initialization mempool_alloc() does not support __GFP_ZERO since elements may come from memory that has already been released by mempool_free(). Remove __GFP_ZERO from mempool_alloc() in drbd_req_new() and properly initialize it to 0. Cc: Lars Ellenberg Cc: Jens Axboe Signed-off-by: David Rientjes Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_req.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/block') diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 34f2f0ba409b..3907202fb9d9 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -52,9 +52,10 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device, { struct drbd_request *req; - req = mempool_alloc(drbd_request_mempool, GFP_NOIO | __GFP_ZERO); + req = mempool_alloc(drbd_request_mempool, GFP_NOIO); if (!req) return NULL; + memset(req, 0, sizeof(*req)); drbd_req_make_private_bio(req, bio_src); req->rq_state = bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0; -- cgit v1.2.1 From cbc4ffdbe72a1bad3dbed27bb6b2eaba2b11bcc3 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 24 Mar 2015 16:22:54 -0700 Subject: block, drbd: use mempool_create_slab_pool() Mempools created for slab caches should use mempool_create_slab_pool(). Cc: Lars Ellenberg Cc: Jens Axboe Signed-off-by: David Rientjes Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 1fc83427199c..81fde9ef7f8e 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2107,13 +2107,12 @@ static int drbd_create_mempools(void) if (drbd_md_io_page_pool == NULL) goto Enomem; - drbd_request_mempool = mempool_create(number, - mempool_alloc_slab, mempool_free_slab, drbd_request_cache); + drbd_request_mempool = mempool_create_slab_pool(number, + drbd_request_cache); if (drbd_request_mempool == NULL) goto Enomem; - drbd_ee_mempool = mempool_create(number, - mempool_alloc_slab, mempool_free_slab, drbd_ee_cache); + drbd_ee_mempool = mempool_create_slab_pool(number, drbd_ee_cache); if (drbd_ee_mempool == NULL) goto Enomem; -- cgit v1.2.1 From 6df3dbc83fb8043a5975d75970d296d6d14f7273 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 26 Mar 2015 13:49:33 -0600 Subject: NVMe: Freeze admin queue on device failure This fixes a race accessing an invalid address when a controller's admin queue is in use during a reset for failure or hot removal occurs. The admin queue will be frozen to prevent new users from entering prior to the doorbell queue being unmapped. Signed-off-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index ceb32dd52a6c..ee83554c28ba 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1347,6 +1347,9 @@ static int nvme_suspend_queue(struct nvme_queue *nvmeq) nvmeq->cq_vector = -1; spin_unlock_irq(&nvmeq->q_lock); + if (!nvmeq->qid && nvmeq->dev->admin_q) + blk_mq_freeze_queue_start(nvmeq->dev->admin_q); + irq_set_affinity_hint(vector, NULL); free_irq(vector, nvmeq); @@ -1378,8 +1381,6 @@ static void nvme_disable_queue(struct nvme_dev *dev, int qid) adapter_delete_sq(dev, qid); adapter_delete_cq(dev, qid); } - if (!qid && dev->admin_q) - blk_mq_freeze_queue_start(dev->admin_q); spin_lock_irq(&nvmeq->q_lock); nvme_process_cq(nvmeq); -- cgit v1.2.1 From fda631ffe5422424579e1649e04cc468d0215b85 Mon Sep 17 00:00:00 2001 From: Chong Yuan Date: Fri, 27 Mar 2015 09:21:32 +0800 Subject: NVMe: embedded iod mask cleanup Remove unused mask in nvme_alloc_iod Signed-off-by: Chong Yuan Reviewed-by: Wenbo Wang Acked-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index ee83554c28ba..7ed618125c27 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -152,6 +152,7 @@ struct nvme_cmd_info { */ #define NVME_INT_PAGES 2 #define NVME_INT_BYTES(dev) (NVME_INT_PAGES * (dev)->page_size) +#define NVME_INT_MASK 0x01 /* * Will slightly overestimate the number of pages needed. This is OK @@ -257,7 +258,7 @@ static void *iod_get_private(struct nvme_iod *iod) */ static bool iod_should_kfree(struct nvme_iod *iod) { - return (iod->private & 0x01) == 0; + return (iod->private & NVME_INT_MASK) == 0; } /* Special values must be less than 0x1000 */ @@ -432,7 +433,6 @@ static struct nvme_iod *nvme_alloc_iod(struct request *rq, struct nvme_dev *dev, { unsigned size = !(rq->cmd_flags & REQ_DISCARD) ? blk_rq_bytes(rq) : sizeof(struct nvme_dsm_range); - unsigned long mask = 0; struct nvme_iod *iod; if (rq->nr_phys_segments <= NVME_INT_PAGES && @@ -440,9 +440,8 @@ static struct nvme_iod *nvme_alloc_iod(struct request *rq, struct nvme_dev *dev, struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(rq); iod = cmd->iod; - mask = 0x01; iod_init(iod, size, rq->nr_phys_segments, - (unsigned long) rq | 0x01); + (unsigned long) rq | NVME_INT_MASK); return iod; } -- cgit v1.2.1 From 1efccc9ddb98fd533169669160201b027562af7e Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 31 Mar 2015 10:37:17 -0600 Subject: NVMe: Fix blk-mq hot cpu notification The driver may issue commands to a device that may never return, so its request_queue could always have active requests while the controller is running. Waiting for the queue to freeze could block forever, which is what blk-mq's hot cpu notification handler was doing when nvme drives were in use. This has the nvme driver make the asynchronous event command's tag reserved and does not keep the request active. We can't have more than one since the request is released back to the request_queue before the command is completed. Having only one avoids potential tag collisions, and reserving the tag for this purpose prevents other admin tasks from reusing the tag. I also couldn't think of a scenario where issuing AEN requests single depth is worse than issuing them in batches, so I don't think we lose anything with this change. As an added bonus, doing it this way removes "Cancelling I/O" warnings observed when unbinding the nvme driver from a device. Reported-by: Yigal Korman Signed-off-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 7ed618125c27..c12c95cf2e55 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -302,8 +302,6 @@ static void *cancel_cmd_info(struct nvme_cmd_info *cmd, nvme_completion_fn *fn) static void async_req_completion(struct nvme_queue *nvmeq, void *ctx, struct nvme_completion *cqe) { - struct request *req = ctx; - u32 result = le32_to_cpup(&cqe->result); u16 status = le16_to_cpup(&cqe->status) >> 1; @@ -312,8 +310,6 @@ static void async_req_completion(struct nvme_queue *nvmeq, void *ctx, if (status == NVME_SC_SUCCESS) dev_warn(nvmeq->q_dmadev, "async event result %08x\n", result); - - blk_mq_free_hctx_request(nvmeq->hctx, req); } static void abort_completion(struct nvme_queue *nvmeq, void *ctx, @@ -1027,18 +1023,19 @@ static int nvme_submit_async_admin_req(struct nvme_dev *dev) struct nvme_cmd_info *cmd_info; struct request *req; - req = blk_mq_alloc_request(dev->admin_q, WRITE, GFP_ATOMIC, false); + req = blk_mq_alloc_request(dev->admin_q, WRITE, GFP_ATOMIC, true); if (IS_ERR(req)) return PTR_ERR(req); req->cmd_flags |= REQ_NO_TIMEOUT; cmd_info = blk_mq_rq_to_pdu(req); - nvme_set_info(cmd_info, req, async_req_completion); + nvme_set_info(cmd_info, NULL, async_req_completion); memset(&c, 0, sizeof(c)); c.common.opcode = nvme_admin_async_event; c.common.command_id = req->tag; + blk_mq_free_hctx_request(nvmeq->hctx, req); return __nvme_submit_cmd(nvmeq, &c); } @@ -1583,6 +1580,7 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev) dev->admin_tagset.ops = &nvme_mq_admin_ops; dev->admin_tagset.nr_hw_queues = 1; dev->admin_tagset.queue_depth = NVME_AQ_DEPTH - 1; + dev->admin_tagset.reserved_tags = 1; dev->admin_tagset.timeout = ADMIN_TIMEOUT; dev->admin_tagset.numa_node = dev_to_node(&dev->pci_dev->dev); dev->admin_tagset.cmd_size = nvme_cmd_size(dev); @@ -2334,7 +2332,6 @@ static int nvme_dev_add(struct nvme_dev *dev) dev->oncs = le16_to_cpup(&ctrl->oncs); dev->abort_limit = ctrl->acl + 1; dev->vwc = ctrl->vwc; - dev->event_limit = min(ctrl->aerl + 1, 8); memcpy(dev->serial, ctrl->sn, sizeof(ctrl->sn)); memcpy(dev->model, ctrl->mn, sizeof(ctrl->mn)); memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr)); @@ -2881,6 +2878,7 @@ static int nvme_dev_start(struct nvme_dev *dev) nvme_set_irq_hints(dev); + dev->event_limit = 1; return result; free_tags: -- cgit v1.2.1 From f137e0f15101c0a0ff8a5d956042e50247f1fef9 Mon Sep 17 00:00:00 2001 From: Murali Iyer Date: Thu, 26 Mar 2015 11:07:51 -0500 Subject: nvme: Fix PRP list calculation for non-4k system page size PRP list calculation is supposed to be based on device's page size. Systems with page size larger than device's page size cause corruption to the name space as well as system memory with out this fix. Systems like x86 might not experience this issue because it uses PAGE_SIZE of 4K where as powerpc uses PAGE_SIZE of 64k while NVMe device's page size varies depending upon the vendor. Signed-off-by: Murali Iyer Signed-off-by: Brian King Acked-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index c12c95cf2e55..4dc858b43c92 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -640,12 +640,12 @@ int nvme_setup_prps(struct nvme_dev *dev, struct nvme_iod *iod, int total_len, struct scatterlist *sg = iod->sg; int dma_len = sg_dma_len(sg); u64 dma_addr = sg_dma_address(sg); - int offset = offset_in_page(dma_addr); + u32 page_size = dev->page_size; + int offset = dma_addr & (page_size - 1); __le64 *prp_list; __le64 **list = iod_list(iod); dma_addr_t prp_dma; int nprps, i; - u32 page_size = dev->page_size; length -= (page_size - offset); if (length <= 0) -- cgit v1.2.1 From d31af0a325ca4ff8e57b8616ab2228913df369ad Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 6 Mar 2015 12:56:13 -0700 Subject: NVMe: increase depth of admin queue Usually the admin queue depth of 64 is plenty, but for some use cases we really need it larger. Examples are use cases like MAT, where you have to touch all of NAND for init/format like purposes. In those cases, we see a good 2x increase with an increased queue depth. Signed-off-by: Jens Axboe Acked-by: Keith Busch --- drivers/block/nvme-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/block') diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 4dc858b43c92..ef432786213b 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -44,7 +44,7 @@ #define NVME_MINORS (1U << MINORBITS) #define NVME_Q_DEPTH 1024 -#define NVME_AQ_DEPTH 64 +#define NVME_AQ_DEPTH 256 #define SQ_SIZE(depth) (depth * sizeof(struct nvme_command)) #define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion)) #define ADMIN_TIMEOUT (admin_timeout * HZ) -- cgit v1.2.1 From 13e71d69cc7444b7d840bab581dbe831e440fb62 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Thu, 2 Apr 2015 10:11:35 +0200 Subject: nbd: Remove kernel internal header The header is not included anywhere. Remove it and include the private nbd_device struct in nbd.c. Signed-off-by: Markus Pargmann Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers/block') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index a98c41f72c63..1aaabcc2af92 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -38,6 +38,28 @@ #include +struct nbd_device { + int flags; + int harderror; /* Code of hard error */ + struct socket * sock; /* If == NULL, device is not ready, yet */ + int magic; + + spinlock_t queue_lock; + struct list_head queue_head; /* Requests waiting result */ + struct request *active_req; + wait_queue_head_t active_wq; + struct list_head waiting_queue; /* Requests to be sent */ + wait_queue_head_t waiting_wq; + + struct mutex tx_lock; + struct gendisk *disk; + int blksize; + u64 bytesize; + pid_t pid; /* pid of nbd-client, if attached */ + int xmit_timeout; + int disconnect; /* a disconnect has been requested by user */ +}; + #define NBD_MAGIC 0x68797548 #ifdef NDEBUG -- cgit v1.2.1 From d06df60b9460838553d37d01049d04c43a36f396 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Thu, 2 Apr 2015 10:11:36 +0200 Subject: nbd: Replace kthread_create with kthread_run kthread_run includes the wake_up_process() call, so instead of kthread_create() followed by wake_up_process() we can use this macro. Signed-off-by: Markus Pargmann Acked-by: Pavel Machek Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 1aaabcc2af92..5bc221693304 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -728,13 +728,13 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, else blk_queue_flush(nbd->disk->queue, 0); - thread = kthread_create(nbd_thread, nbd, "%s", - nbd->disk->disk_name); + thread = kthread_run(nbd_thread, nbd, "%s", + nbd->disk->disk_name); if (IS_ERR(thread)) { mutex_lock(&nbd->tx_lock); return PTR_ERR(thread); } - wake_up_process(thread); + error = nbd_do_it(nbd); kthread_stop(thread); -- cgit v1.2.1 From b9c495bb6d8edc719fd23af2ac67de8303cfc1e8 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Thu, 2 Apr 2015 10:11:37 +0200 Subject: nbd: Fix device bytesize type The block subsystem uses loff_t to store the device size. Change the type for nbd_device bytesize to loff_t. Signed-off-by: Markus Pargmann Acked-by: Pavel Machek Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/block') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 5bc221693304..7139c8aae7a1 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -54,7 +55,7 @@ struct nbd_device { struct mutex tx_lock; struct gendisk *disk; int blksize; - u64 bytesize; + loff_t bytesize; pid_t pid; /* pid of nbd-client, if attached */ int xmit_timeout; int disconnect; /* a disconnect has been requested by user */ -- cgit v1.2.1 From d18509f5979881ae326e910115ab2ba914c016b6 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Thu, 2 Apr 2015 10:11:38 +0200 Subject: nbd: Restructure debugging prints dprintk has some name collisions with other frameworks and drivers. It is also not necessary to have these custom debug print filters. Dynamic debug offers the same amount of filtered debugging. This patch replaces all dprintks with dev_dbg(). It also removes the ioctl dprintk which prints the ingoing ioctls which should be replaceable by strace or similar stuff. Signed-off-by: Markus Pargmann Acked-by: Pavel Machek Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 88 ++++++++++++++--------------------------------------- 1 file changed, 22 insertions(+), 66 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 7139c8aae7a1..9e553a753410 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -63,21 +63,6 @@ struct nbd_device { #define NBD_MAGIC 0x68797548 -#ifdef NDEBUG -#define dprintk(flags, fmt...) -#else /* NDEBUG */ -#define dprintk(flags, fmt...) do { \ - if (debugflags & (flags)) printk(KERN_DEBUG fmt); \ -} while (0) -#define DBG_IOCTL 0x0004 -#define DBG_INIT 0x0010 -#define DBG_EXIT 0x0020 -#define DBG_BLKDEV 0x0100 -#define DBG_RX 0x0200 -#define DBG_TX 0x0400 -static unsigned int debugflags; -#endif /* NDEBUG */ - static unsigned int nbds_max = 16; static struct nbd_device *nbd_dev; static int max_part; @@ -94,25 +79,9 @@ static int max_part; */ static DEFINE_SPINLOCK(nbd_lock); -#ifndef NDEBUG -static const char *ioctl_cmd_to_ascii(int cmd) +static inline struct device *nbd_to_dev(struct nbd_device *nbd) { - switch (cmd) { - case NBD_SET_SOCK: return "set-sock"; - case NBD_SET_BLKSIZE: return "set-blksize"; - case NBD_SET_SIZE: return "set-size"; - case NBD_SET_TIMEOUT: return "set-timeout"; - case NBD_SET_FLAGS: return "set-flags"; - case NBD_DO_IT: return "do-it"; - case NBD_CLEAR_SOCK: return "clear-sock"; - case NBD_CLEAR_QUE: return "clear-que"; - case NBD_PRINT_DEBUG: return "print-debug"; - case NBD_SET_SIZE_BLOCKS: return "set-size-blocks"; - case NBD_DISCONNECT: return "disconnect"; - case BLKROSET: return "set-read-only"; - case BLKFLSBUF: return "flush-buffer-cache"; - } - return "unknown"; + return disk_to_dev(nbd->disk); } static const char *nbdcmd_to_ascii(int cmd) @@ -126,16 +95,15 @@ static const char *nbdcmd_to_ascii(int cmd) } return "invalid"; } -#endif /* NDEBUG */ -static void nbd_end_request(struct request *req) +static void nbd_end_request(struct nbd_device *nbd, struct request *req) { int error = req->errors ? -EIO : 0; struct request_queue *q = req->q; unsigned long flags; - dprintk(DBG_BLKDEV, "%s: request %p: %s\n", req->rq_disk->disk_name, - req, error ? "failed" : "done"); + dev_dbg(nbd_to_dev(nbd), "request %p: %s\n", req, + error ? "failed" : "done"); spin_lock_irqsave(q->queue_lock, flags); __blk_end_request_all(req, error); @@ -276,11 +244,9 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req) } memcpy(request.handle, &req, sizeof(req)); - dprintk(DBG_TX, "%s: request %p: sending control (%s@%llu,%uB)\n", - nbd->disk->disk_name, req, - nbdcmd_to_ascii(nbd_cmd(req)), - (unsigned long long)blk_rq_pos(req) << 9, - blk_rq_bytes(req)); + dev_dbg(nbd_to_dev(nbd), "request %p: sending control (%s@%llu,%uB)\n", + req, nbdcmd_to_ascii(nbd_cmd(req)), + (unsigned long long)blk_rq_pos(req) << 9, blk_rq_bytes(req)); result = sock_xmit(nbd, 1, &request, sizeof(request), (nbd_cmd(req) == NBD_CMD_WRITE) ? MSG_MORE : 0); if (result <= 0) { @@ -300,8 +266,8 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req) flags = 0; if (!rq_iter_last(bvec, iter)) flags = MSG_MORE; - dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n", - nbd->disk->disk_name, req, bvec.bv_len); + dev_dbg(nbd_to_dev(nbd), "request %p: sending %d bytes data\n", + req, bvec.bv_len); result = sock_send_bvec(nbd, &bvec, flags); if (result <= 0) { dev_err(disk_to_dev(nbd->disk), @@ -394,8 +360,7 @@ static struct request *nbd_read_stat(struct nbd_device *nbd) return req; } - dprintk(DBG_RX, "%s: request %p: got reply\n", - nbd->disk->disk_name, req); + dev_dbg(nbd_to_dev(nbd), "request %p: got reply\n", req); if (nbd_cmd(req) == NBD_CMD_READ) { struct req_iterator iter; struct bio_vec bvec; @@ -408,8 +373,8 @@ static struct request *nbd_read_stat(struct nbd_device *nbd) req->errors++; return req; } - dprintk(DBG_RX, "%s: request %p: got %d bytes data\n", - nbd->disk->disk_name, req, bvec.bv_len); + dev_dbg(nbd_to_dev(nbd), "request %p: got %d bytes data\n", + req, bvec.bv_len); } } return req; @@ -449,7 +414,7 @@ static int nbd_do_it(struct nbd_device *nbd) } while ((req = nbd_read_stat(nbd)) != NULL) - nbd_end_request(req); + nbd_end_request(nbd, req); device_remove_file(disk_to_dev(nbd->disk), &pid_attr); nbd->pid = 0; @@ -478,7 +443,7 @@ static void nbd_clear_que(struct nbd_device *nbd) queuelist); list_del_init(&req->queuelist); req->errors++; - nbd_end_request(req); + nbd_end_request(nbd, req); } while (!list_empty(&nbd->waiting_queue)) { @@ -486,7 +451,7 @@ static void nbd_clear_que(struct nbd_device *nbd) queuelist); list_del_init(&req->queuelist); req->errors++; - nbd_end_request(req); + nbd_end_request(nbd, req); } } @@ -530,7 +495,7 @@ static void nbd_handle_req(struct nbd_device *nbd, struct request *req) if (nbd_send_req(nbd, req) != 0) { dev_err(disk_to_dev(nbd->disk), "Request send failed\n"); req->errors++; - nbd_end_request(req); + nbd_end_request(nbd, req); } else { spin_lock(&nbd->queue_lock); list_add_tail(&req->queuelist, &nbd->queue_head); @@ -545,7 +510,7 @@ static void nbd_handle_req(struct nbd_device *nbd, struct request *req) error_out: req->errors++; - nbd_end_request(req); + nbd_end_request(nbd, req); } static int nbd_thread(void *data) @@ -593,18 +558,18 @@ static void do_nbd_request(struct request_queue *q) spin_unlock_irq(q->queue_lock); - dprintk(DBG_BLKDEV, "%s: request %p: dequeued (flags=%x)\n", - req->rq_disk->disk_name, req, req->cmd_type); - nbd = req->rq_disk->private_data; BUG_ON(nbd->magic != NBD_MAGIC); + dev_dbg(nbd_to_dev(nbd), "request %p: dequeued (flags=%x)\n", + req, req->cmd_type); + if (unlikely(!nbd->sock)) { dev_err(disk_to_dev(nbd->disk), "Attempted send on closed socket\n"); req->errors++; - nbd_end_request(req); + nbd_end_request(nbd, req); spin_lock_irq(q->queue_lock); continue; } @@ -791,10 +756,6 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode, BUG_ON(nbd->magic != NBD_MAGIC); - /* Anyone capable of this syscall can do *real bad* things */ - dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n", - nbd->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg); - mutex_lock(&nbd->tx_lock); error = __nbd_ioctl(bdev, nbd, cmd, arg); mutex_unlock(&nbd->tx_lock); @@ -884,7 +845,6 @@ static int __init nbd_init(void) } printk(KERN_INFO "nbd: registered device at major %d\n", NBD_MAJOR); - dprintk(DBG_INIT, "nbd: debugflags=0x%x\n", debugflags); for (i = 0; i < nbds_max; i++) { struct gendisk *disk = nbd_dev[i].disk; @@ -943,7 +903,3 @@ module_param(nbds_max, int, 0444); MODULE_PARM_DESC(nbds_max, "number of network block devices to initialize (default: 16)"); module_param(max_part, int, 0444); MODULE_PARM_DESC(max_part, "number of partitions per device (default: 0)"); -#ifndef NDEBUG -module_param(debugflags, int, 0644); -MODULE_PARM_DESC(debugflags, "flags for controlling debug output"); -#endif -- cgit v1.2.1 From e018e7570c8b0f9f5a4bb0e1eff9b1e7f768f49b Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Thu, 2 Apr 2015 10:11:39 +0200 Subject: nbd: Remove fixme that was already fixed The mentioned problem is not present anymore. Signed-off-by: Markus Pargmann Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 9e553a753410..ef57e7d83aed 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -110,14 +110,11 @@ static void nbd_end_request(struct nbd_device *nbd, struct request *req) spin_unlock_irqrestore(q->queue_lock, flags); } +/* + * Forcibly shutdown the socket causing all listeners to error + */ static void sock_shutdown(struct nbd_device *nbd, int lock) { - /* Forcibly shutdown the socket causing all listeners - * to error - * - * FIXME: This code is duplicated from sys_shutdown, but - * there should be a more generic interface rather than - * calling socket ops directly here */ if (lock) mutex_lock(&nbd->tx_lock); if (nbd->sock) { -- cgit v1.2.1 From dab5313aa4e668d87253dd4289c816cb08f63e52 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Thu, 2 Apr 2015 10:11:40 +0200 Subject: nbd: Return error code directly By returning the error code directly, we can avoid the jump label error_out. Signed-off-by: Markus Pargmann Acked-by: Pavel Machek Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index ef57e7d83aed..54bf633c9013 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -249,7 +249,7 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req) if (result <= 0) { dev_err(disk_to_dev(nbd->disk), "Send control failed (result %d)\n", result); - goto error_out; + return -EIO; } if (nbd_cmd(req) == NBD_CMD_WRITE) { @@ -270,14 +270,11 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req) dev_err(disk_to_dev(nbd->disk), "Send data failed (result %d)\n", result); - goto error_out; + return -EIO; } } } return 0; - -error_out: - return -EIO; } static struct request *nbd_find_request(struct nbd_device *nbd, -- cgit v1.2.1 From de9ad6d4edb63e0ba5d5aae365fb3565064fc00d Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Thu, 2 Apr 2015 10:11:41 +0200 Subject: nbd: Return error pointer directly Signed-off-by: Markus Pargmann Acked-by: Pavel Machek Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 54bf633c9013..39e5f7fae3ef 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -285,7 +285,7 @@ static struct request *nbd_find_request(struct nbd_device *nbd, err = wait_event_interruptible(nbd->active_wq, nbd->active_req != xreq); if (unlikely(err)) - goto out; + return ERR_PTR(err); spin_lock(&nbd->queue_lock); list_for_each_entry_safe(req, tmp, &nbd->queue_head, queuelist) { @@ -297,10 +297,7 @@ static struct request *nbd_find_request(struct nbd_device *nbd, } spin_unlock(&nbd->queue_lock); - err = -ENOENT; - -out: - return ERR_PTR(err); + return ERR_PTR(-ENOENT); } static inline int sock_recv_bvec(struct nbd_device *nbd, struct bio_vec *bvec) -- cgit v1.2.1 From 1375590d3e18b4d87d2f768178e93a0c8644a7dc Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Fri, 27 Mar 2015 13:15:54 +0000 Subject: xen-blkback: enlarge the array size of blkback name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The blkback name is like blkback.domid.xvd[a-z], if domid has four digits (means larger than 1000), then the backmost xvd wouldn't be fully shown. Define a BLKBACK_NAME_LEN macro to be 20, enlarge the array size of blkback name, so it will be fully shown in any case. Signed-off-by: Tao Chen Signed-off-by: Konrad Rzeszutek Wilk Acked-by: Roger Pau Monné --- drivers/block/xen-blkback/xenbus.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index e3afe97280b1..b33083e67f8c 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -21,6 +21,9 @@ #include #include "common.h" +/* Enlarge the array size in order to fully show blkback name. */ +#define BLKBACK_NAME_LEN (20) + struct backend_info { struct xenbus_device *dev; struct xen_blkif *blkif; @@ -70,7 +73,7 @@ static int blkback_name(struct xen_blkif *blkif, char *buf) else devname = devpath; - snprintf(buf, TASK_COMM_LEN, "blkback.%d.%s", blkif->domid, devname); + snprintf(buf, BLKBACK_NAME_LEN, "blkback.%d.%s", blkif->domid, devname); kfree(devpath); return 0; @@ -79,7 +82,7 @@ static int blkback_name(struct xen_blkif *blkif, char *buf) static void xen_update_blkif_status(struct xen_blkif *blkif) { int err; - char name[TASK_COMM_LEN]; + char name[BLKBACK_NAME_LEN]; /* Not ready to connect? */ if (!blkif->irq || !blkif->vbd.bdev) -- cgit v1.2.1 From 77387b82d1b2bada25a7b566ab7716408fedc5e9 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Wed, 1 Apr 2015 15:04:22 +0000 Subject: xen-blkback: define pr_fmt macro to avoid the duplication of DRV_PFX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define pr_fmt macro with {xen-blkback: } prefix, then remove all use of DRV_PFX in the pr sentences. Replace all DPRINTK with pr sentences, and get rid of DPRINTK macro. It will simplify the code. And if the pr sentences miss a \n, add it in the end. If the DPRINTK sentences have redundant \n, remove it. It will format the code. These all make the readability of the code become better. Signed-off-by: Tao Chen Signed-off-by: Konrad Rzeszutek Wilk Acked-by: Roger Pau Monné --- drivers/block/xen-blkback/blkback.c | 62 ++++++++++++++++++------------------- drivers/block/xen-blkback/common.h | 6 ---- drivers/block/xen-blkback/xenbus.c | 31 +++++++++++-------- 3 files changed, 49 insertions(+), 50 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 2a04d341e598..bd2b3bbbb22c 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -34,6 +34,8 @@ * IN THE SOFTWARE. */ +#define pr_fmt(fmt) "xen-blkback: " fmt + #include #include #include @@ -211,7 +213,7 @@ static int add_persistent_gnt(struct xen_blkif *blkif, else if (persistent_gnt->gnt > this->gnt) new = &((*new)->rb_right); else { - pr_alert_ratelimited(DRV_PFX " trying to add a gref that's already in the tree\n"); + pr_alert_ratelimited("trying to add a gref that's already in the tree\n"); return -EINVAL; } } @@ -242,7 +244,7 @@ static struct persistent_gnt *get_persistent_gnt(struct xen_blkif *blkif, node = node->rb_right; else { if(test_bit(PERSISTENT_GNT_ACTIVE, data->flags)) { - pr_alert_ratelimited(DRV_PFX " requesting a grant already in use\n"); + pr_alert_ratelimited("requesting a grant already in use\n"); return NULL; } set_bit(PERSISTENT_GNT_ACTIVE, data->flags); @@ -257,7 +259,7 @@ static void put_persistent_gnt(struct xen_blkif *blkif, struct persistent_gnt *persistent_gnt) { if(!test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags)) - pr_alert_ratelimited(DRV_PFX " freeing a grant already unused"); + pr_alert_ratelimited("freeing a grant already unused\n"); set_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags); clear_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags); atomic_dec(&blkif->persistent_gnt_in_use); @@ -374,7 +376,7 @@ static void purge_persistent_gnt(struct xen_blkif *blkif) } if (work_pending(&blkif->persistent_purge_work)) { - pr_alert_ratelimited(DRV_PFX "Scheduled work from previous purge is still pending, cannot purge list\n"); + pr_alert_ratelimited("Scheduled work from previous purge is still pending, cannot purge list\n"); return; } @@ -396,7 +398,7 @@ static void purge_persistent_gnt(struct xen_blkif *blkif) total = num_clean; - pr_debug(DRV_PFX "Going to purge %u persistent grants\n", num_clean); + pr_debug("Going to purge %u persistent grants\n", num_clean); BUG_ON(!list_empty(&blkif->persistent_purge_list)); root = &blkif->persistent_gnts; @@ -428,13 +430,13 @@ purge_list: * with the requested num */ if (!scan_used && !clean_used) { - pr_debug(DRV_PFX "Still missing %u purged frames\n", num_clean); + pr_debug("Still missing %u purged frames\n", num_clean); scan_used = true; goto purge_list; } finished: if (!clean_used) { - pr_debug(DRV_PFX "Finished scanning for grants to clean, removing used flag\n"); + pr_debug("Finished scanning for grants to clean, removing used flag\n"); clean_used = true; goto purge_list; } @@ -444,7 +446,7 @@ finished: /* We can defer this work */ schedule_work(&blkif->persistent_purge_work); - pr_debug(DRV_PFX "Purged %u/%u\n", (total - num_clean), total); + pr_debug("Purged %u/%u\n", (total - num_clean), total); return; } @@ -520,20 +522,20 @@ static void xen_vbd_resize(struct xen_blkif *blkif) struct xenbus_device *dev = xen_blkbk_xenbus(blkif->be); unsigned long long new_size = vbd_sz(vbd); - pr_info(DRV_PFX "VBD Resize: Domid: %d, Device: (%d, %d)\n", + pr_info("VBD Resize: Domid: %d, Device: (%d, %d)\n", blkif->domid, MAJOR(vbd->pdevice), MINOR(vbd->pdevice)); - pr_info(DRV_PFX "VBD Resize: new size %llu\n", new_size); + pr_info("VBD Resize: new size %llu\n", new_size); vbd->size = new_size; again: err = xenbus_transaction_start(&xbt); if (err) { - pr_warn(DRV_PFX "Error starting transaction"); + pr_warn("Error starting transaction\n"); return; } err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu", (unsigned long long)vbd_sz(vbd)); if (err) { - pr_warn(DRV_PFX "Error writing new size"); + pr_warn("Error writing new size\n"); goto abort; } /* @@ -543,7 +545,7 @@ again: */ err = xenbus_printf(xbt, dev->nodename, "state", "%d", dev->state); if (err) { - pr_warn(DRV_PFX "Error writing the state"); + pr_warn("Error writing the state\n"); goto abort; } @@ -551,7 +553,7 @@ again: if (err == -EAGAIN) goto again; if (err) - pr_warn(DRV_PFX "Error ending transaction"); + pr_warn("Error ending transaction\n"); return; abort: xenbus_transaction_end(xbt, 1); @@ -578,7 +580,7 @@ irqreturn_t xen_blkif_be_int(int irq, void *dev_id) static void print_stats(struct xen_blkif *blkif) { - pr_info("xen-blkback (%s): oo %3llu | rd %4llu | wr %4llu | f %4llu" + pr_info("(%s): oo %3llu | rd %4llu | wr %4llu | f %4llu" " | ds %4llu | pg: %4u/%4d\n", current->comm, blkif->st_oo_req, blkif->st_rd_req, blkif->st_wr_req, @@ -855,7 +857,7 @@ again: /* This is a newly mapped grant */ BUG_ON(new_map_idx >= segs_to_map); if (unlikely(map[new_map_idx].status != 0)) { - pr_debug(DRV_PFX "invalid buffer -- could not remap it\n"); + pr_debug("invalid buffer -- could not remap it\n"); put_free_pages(blkif, &pages[seg_idx]->page, 1); pages[seg_idx]->handle = BLKBACK_INVALID_HANDLE; ret |= 1; @@ -891,14 +893,14 @@ again: goto next; } pages[seg_idx]->persistent_gnt = persistent_gnt; - pr_debug(DRV_PFX " grant %u added to the tree of persistent grants, using %u/%u\n", + pr_debug("grant %u added to the tree of persistent grants, using %u/%u\n", persistent_gnt->gnt, blkif->persistent_gnt_c, xen_blkif_max_pgrants); goto next; } if (use_persistent_gnts && !blkif->vbd.overflow_max_grants) { blkif->vbd.overflow_max_grants = 1; - pr_debug(DRV_PFX " domain %u, device %#x is using maximum number of persistent grants\n", + pr_debug("domain %u, device %#x is using maximum number of persistent grants\n", blkif->domid, blkif->vbd.handle); } /* @@ -916,7 +918,7 @@ next: return ret; out_of_memory: - pr_alert(DRV_PFX "%s: out of memory\n", __func__); + pr_alert("%s: out of memory\n", __func__); put_free_pages(blkif, pages_to_gnt, segs_to_map); return -ENOMEM; } @@ -996,7 +998,7 @@ static int dispatch_discard_io(struct xen_blkif *blkif, err = xen_vbd_translate(&preq, blkif, WRITE); if (err) { - pr_warn(DRV_PFX "access denied: DISCARD [%llu->%llu] on dev=%04x\n", + pr_warn("access denied: DISCARD [%llu->%llu] on dev=%04x\n", preq.sector_number, preq.sector_number + preq.nr_sects, blkif->vbd.pdevice); goto fail_response; @@ -1012,7 +1014,7 @@ static int dispatch_discard_io(struct xen_blkif *blkif, GFP_KERNEL, secure); fail_response: if (err == -EOPNOTSUPP) { - pr_debug(DRV_PFX "discard op failed, not supported\n"); + pr_debug("discard op failed, not supported\n"); status = BLKIF_RSP_EOPNOTSUPP; } else if (err) status = BLKIF_RSP_ERROR; @@ -1056,16 +1058,16 @@ static void __end_block_io_op(struct pending_req *pending_req, int error) /* An error fails the entire request. */ if ((pending_req->operation == BLKIF_OP_FLUSH_DISKCACHE) && (error == -EOPNOTSUPP)) { - pr_debug(DRV_PFX "flush diskcache op failed, not supported\n"); + pr_debug("flush diskcache op failed, not supported\n"); xen_blkbk_flush_diskcache(XBT_NIL, pending_req->blkif->be, 0); pending_req->status = BLKIF_RSP_EOPNOTSUPP; } else if ((pending_req->operation == BLKIF_OP_WRITE_BARRIER) && (error == -EOPNOTSUPP)) { - pr_debug(DRV_PFX "write barrier op failed, not supported\n"); + pr_debug("write barrier op failed, not supported\n"); xen_blkbk_barrier(XBT_NIL, pending_req->blkif->be, 0); pending_req->status = BLKIF_RSP_EOPNOTSUPP; } else if (error) { - pr_debug(DRV_PFX "Buffer not up-to-date at end of operation," + pr_debug("Buffer not up-to-date at end of operation," " error=%d\n", error); pending_req->status = BLKIF_RSP_ERROR; } @@ -1110,7 +1112,7 @@ __do_block_io_op(struct xen_blkif *blkif) if (RING_REQUEST_PROD_OVERFLOW(&blk_rings->common, rp)) { rc = blk_rings->common.rsp_prod_pvt; - pr_warn(DRV_PFX "Frontend provided bogus ring requests (%d - %d = %d). Halting ring processing on dev=%04x\n", + pr_warn("Frontend provided bogus ring requests (%d - %d = %d). Halting ring processing on dev=%04x\n", rp, rc, rp - rc, blkif->vbd.pdevice); return -EACCES; } @@ -1217,8 +1219,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, if ((req->operation == BLKIF_OP_INDIRECT) && (req_operation != BLKIF_OP_READ) && (req_operation != BLKIF_OP_WRITE)) { - pr_debug(DRV_PFX "Invalid indirect operation (%u)\n", - req_operation); + pr_debug("Invalid indirect operation (%u)\n", req_operation); goto fail_response; } @@ -1252,8 +1253,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, (nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) || unlikely((req->operation == BLKIF_OP_INDIRECT) && (nseg > MAX_INDIRECT_SEGMENTS))) { - pr_debug(DRV_PFX "Bad number of segments in request (%d)\n", - nseg); + pr_debug("Bad number of segments in request (%d)\n", nseg); /* Haven't submitted any bio's yet. */ goto fail_response; } @@ -1288,7 +1288,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, } if (xen_vbd_translate(&preq, blkif, operation) != 0) { - pr_debug(DRV_PFX "access denied: %s of [%llu,%llu] on dev=%04x\n", + pr_debug("access denied: %s of [%llu,%llu] on dev=%04x\n", operation == READ ? "read" : "write", preq.sector_number, preq.sector_number + preq.nr_sects, @@ -1303,7 +1303,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, for (i = 0; i < nseg; i++) { if (((int)preq.sector_number|(int)seg[i].nsec) & ((bdev_logical_block_size(preq.bdev) >> 9) - 1)) { - pr_debug(DRV_PFX "Misaligned I/O request from domain %d", + pr_debug("Misaligned I/O request from domain %d\n", blkif->domid); goto fail_response; } diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 375d28851860..f620b5d3f77c 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -44,12 +44,6 @@ #include #include -#define DRV_PFX "xen-blkback:" -#define DPRINTK(fmt, args...) \ - pr_debug(DRV_PFX "(%s:%d) " fmt ".\n", \ - __func__, __LINE__, ##args) - - /* * This is the maximum number of segments that would be allowed in indirect * requests. This value will also be passed to the frontend. diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index b33083e67f8c..5448dc899d32 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -14,6 +14,8 @@ */ +#define pr_fmt(fmt) "xen-blkback: " fmt + #include #include #include @@ -426,14 +428,14 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle, FMODE_READ : FMODE_WRITE, NULL); if (IS_ERR(bdev)) { - DPRINTK("xen_vbd_create: device %08x could not be opened.\n", + pr_warn("xen_vbd_create: device %08x could not be opened\n", vbd->pdevice); return -ENOENT; } vbd->bdev = bdev; if (vbd->bdev->bd_disk == NULL) { - DPRINTK("xen_vbd_create: device %08x doesn't exist.\n", + pr_warn("xen_vbd_create: device %08x doesn't exist\n", vbd->pdevice); xen_vbd_free(vbd); return -ENOENT; @@ -452,7 +454,7 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle, if (q && blk_queue_secdiscard(q)) vbd->discard_secure = true; - DPRINTK("Successful creation of handle=%04x (dom=%u)\n", + pr_debug("Successful creation of handle=%04x (dom=%u)\n", handle, blkif->domid); return 0; } @@ -460,7 +462,7 @@ static int xen_blkbk_remove(struct xenbus_device *dev) { struct backend_info *be = dev_get_drvdata(&dev->dev); - DPRINTK(""); + pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id); if (be->major || be->minor) xenvbd_sysfs_delif(dev); @@ -566,6 +568,10 @@ static int xen_blkbk_probe(struct xenbus_device *dev, int err; struct backend_info *be = kzalloc(sizeof(struct backend_info), GFP_KERNEL); + + /* match the pr_debug in xen_blkbk_remove */ + pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id); + if (!be) { xenbus_dev_fatal(dev, -ENOMEM, "allocating backend structure"); @@ -597,7 +603,7 @@ static int xen_blkbk_probe(struct xenbus_device *dev, return 0; fail: - DPRINTK("failed"); + pr_warn("%s failed\n", __func__); xen_blkbk_remove(dev); return err; } @@ -621,7 +627,7 @@ static void backend_changed(struct xenbus_watch *watch, unsigned long handle; char *device_type; - DPRINTK(""); + pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id); err = xenbus_scanf(XBT_NIL, dev->nodename, "physical-device", "%x:%x", &major, &minor); @@ -640,7 +646,7 @@ static void backend_changed(struct xenbus_watch *watch, if (be->major | be->minor) { if (be->major != major || be->minor != minor) - pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n", + pr_warn("changing physical device (from %x:%x to %x:%x) not supported.\n", be->major, be->minor, major, minor); return; } @@ -701,13 +707,12 @@ static void frontend_changed(struct xenbus_device *dev, struct backend_info *be = dev_get_drvdata(&dev->dev); int err; - DPRINTK("%s", xenbus_strstate(frontend_state)); + pr_debug("%s %p %s\n", __func__, dev, xenbus_strstate(frontend_state)); switch (frontend_state) { case XenbusStateInitialising: if (dev->state == XenbusStateClosed) { - pr_info(DRV_PFX "%s: prepare for reconnect\n", - dev->nodename); + pr_info("%s: prepare for reconnect\n", dev->nodename); xenbus_switch_state(dev, XenbusStateInitWait); } break; @@ -774,7 +779,7 @@ static void connect(struct backend_info *be) int err; struct xenbus_device *dev = be->dev; - DPRINTK("%s", dev->otherend); + pr_debug("%s %s\n", __func__, dev->otherend); /* Supply the information about the device the frontend needs */ again: @@ -860,7 +865,7 @@ static int connect_ring(struct backend_info *be) char protocol[64] = ""; int err; - DPRINTK("%s", dev->otherend); + pr_debug("%s %s\n", __func__, dev->otherend); err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu", &ring_ref, "event-channel", "%u", &evtchn, NULL); @@ -895,7 +900,7 @@ static int connect_ring(struct backend_info *be) be->blkif->vbd.feature_gnt_persistent = pers_grants; be->blkif->vbd.overflow_max_grants = 0; - pr_info(DRV_PFX "ring-ref %ld, event-channel %d, protocol %d (%s) %s\n", + pr_info("ring-ref %ld, event-channel %d, protocol %d (%s) %s\n", ring_ref, evtchn, be->blkif->blk_protocol, protocol, pers_grants ? "persistent grants" : ""); -- cgit v1.2.1 From c727040bdaa28cd7aa9dbc086eee7b236e0fb270 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Sat, 7 Mar 2015 01:43:41 +0300 Subject: NVMe: Fix error handling of class_create("nvme") class_create() returns ERR_PTR on failure, so IS_ERR() should be used instead of check for NULL. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Acked-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/block') diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index ef432786213b..9052553eda65 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -3163,8 +3163,10 @@ static int __init nvme_init(void) nvme_char_major = result; nvme_class = class_create(THIS_MODULE, "nvme"); - if (!nvme_class) + if (IS_ERR(nvme_class)) { + result = PTR_ERR(nvme_class); goto unregister_chrdev; + } result = pci_register_driver(&nvme_driver); if (result) -- cgit v1.2.1 From 447228023eaa8c96a48a8a459be7a992008df830 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 7 Apr 2015 15:48:26 -0600 Subject: NVMe: Remove check for null Checking fails static analysis due to additional arithmetic prior to the NULL check. Mapping doesn't return NULL here anyway, so removing the check. Reported-by: Dan Carpenter Signed-off-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 9052553eda65..973c895bd7af 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -517,8 +517,6 @@ static void nvme_dif_remap(struct request *req, return; pmap = kmap_atomic(bip->bip_vec->bv_page) + bip->bip_vec->bv_offset; - if (!pmap) - return; p = pmap; virt = bip_get_seed(bip); -- cgit v1.2.1 From 7f749d9c109223e4d1724e674e7d603082e85839 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 7 Apr 2015 15:34:18 -0600 Subject: NVMe: Add translation for block limits Adds SCSI-to-NVMe translation for VPD B0h, block limits inquiry data. Signed-off-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/block/nvme-scsi.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'drivers/block') diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c index e10196e0182d..6b736b00f63e 100644 --- a/drivers/block/nvme-scsi.c +++ b/drivers/block/nvme-scsi.c @@ -55,6 +55,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ #define VPD_SERIAL_NUMBER 0x80 #define VPD_DEVICE_IDENTIFIERS 0x83 #define VPD_EXTENDED_INQUIRY 0x86 +#define VPD_BLOCK_LIMITS 0xB0 #define VPD_BLOCK_DEV_CHARACTERISTICS 0xB1 /* CDB offsets */ @@ -132,9 +133,10 @@ static int sg_version_num = 30534; /* 2 digits for each component */ #define INQ_UNIT_SERIAL_NUMBER_PAGE 0x80 #define INQ_DEVICE_IDENTIFICATION_PAGE 0x83 #define INQ_EXTENDED_INQUIRY_DATA_PAGE 0x86 +#define INQ_BDEV_LIMITS_PAGE 0xB0 #define INQ_BDEV_CHARACTERISTICS_PAGE 0xB1 #define INQ_SERIAL_NUMBER_LENGTH 0x14 -#define INQ_NUM_SUPPORTED_VPD_PAGES 5 +#define INQ_NUM_SUPPORTED_VPD_PAGES 6 #define VERSION_SPC_4 0x06 #define ACA_UNSUPPORTED 0 #define STANDARD_INQUIRY_LENGTH 36 @@ -747,6 +749,7 @@ static int nvme_trans_supported_vpd_pages(struct nvme_ns *ns, inq_response[6] = INQ_DEVICE_IDENTIFICATION_PAGE; inq_response[7] = INQ_EXTENDED_INQUIRY_DATA_PAGE; inq_response[8] = INQ_BDEV_CHARACTERISTICS_PAGE; + inq_response[9] = INQ_BDEV_LIMITS_PAGE; xfer_len = min(alloc_len, STANDARD_INQUIRY_LENGTH); res = nvme_trans_copy_to_user(hdr, inq_response, xfer_len); @@ -938,6 +941,25 @@ static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, return res; } +static int nvme_trans_bdev_limits_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, + u8 *inq_response, int alloc_len) +{ + __be32 max_sectors = cpu_to_be32(queue_max_hw_sectors(ns->queue)); + __be32 max_discard = cpu_to_be32(ns->queue->limits.max_discard_sectors); + __be32 discard_desc_count = cpu_to_be32(0x100); + + memset(inq_response, 0, STANDARD_INQUIRY_LENGTH); + inq_response[1] = VPD_BLOCK_LIMITS; + inq_response[3] = 0x3c; /* Page Length */ + memcpy(&inq_response[8], &max_sectors, sizeof(u32)); + memcpy(&inq_response[20], &max_discard, sizeof(u32)); + + if (max_discard) + memcpy(&inq_response[24], &discard_desc_count, sizeof(u32)); + + return nvme_trans_copy_to_user(hdr, inq_response, 0x3c); +} + static int nvme_trans_bdev_char_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, int alloc_len) { @@ -2268,6 +2290,10 @@ static int nvme_trans_inquiry(struct nvme_ns *ns, struct sg_io_hdr *hdr, case VPD_EXTENDED_INQUIRY: res = nvme_trans_ext_inq_page(ns, hdr, alloc_len); break; + case VPD_BLOCK_LIMITS: + res = nvme_trans_bdev_limits_page(ns, hdr, inq_response, + alloc_len); + break; case VPD_BLOCK_DEV_CHARACTERISTICS: res = nvme_trans_bdev_char_page(ns, hdr, alloc_len); break; -- cgit v1.2.1 From a67a95134ffddd0ca4527c77e86375c3deb2938f Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 7 Apr 2015 16:57:19 -0600 Subject: NVMe: Meta data handling through submit io ioctl This adds support for the extended metadata formats through the submit IO ioctl, and simplifies the rest when using a separate metadata format. Signed-off-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 123 ++++++++++++++++++---------------------------- 1 file changed, 49 insertions(+), 74 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 973c895bd7af..e919de48ff25 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1745,25 +1745,31 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) struct nvme_dev *dev = ns->dev; struct nvme_user_io io; struct nvme_command c; - unsigned length, meta_len; - int status, i; - struct nvme_iod *iod, *meta_iod = NULL; - dma_addr_t meta_dma_addr; - void *meta, *uninitialized_var(meta_mem); + unsigned length, meta_len, prp_len; + int status, write; + struct nvme_iod *iod; + dma_addr_t meta_dma = 0; + void *meta = NULL; if (copy_from_user(&io, uio, sizeof(io))) return -EFAULT; length = (io.nblocks + 1) << ns->lba_shift; meta_len = (io.nblocks + 1) * ns->ms; - if (meta_len && ((io.metadata & 3) || !io.metadata)) + if (meta_len && ((io.metadata & 3) || !io.metadata) && !ns->ext) return -EINVAL; + else if (meta_len && ns->ext) { + length += meta_len; + meta_len = 0; + } + + write = io.opcode & 1; switch (io.opcode) { case nvme_cmd_write: case nvme_cmd_read: case nvme_cmd_compare: - iod = nvme_map_user_pages(dev, io.opcode & 1, io.addr, length); + iod = nvme_map_user_pages(dev, write, io.addr, length); break; default: return -EINVAL; @@ -1772,6 +1778,27 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) if (IS_ERR(iod)) return PTR_ERR(iod); + prp_len = nvme_setup_prps(dev, iod, length, GFP_KERNEL); + if (length != prp_len) { + status = -ENOMEM; + goto unmap; + } + if (meta_len) { + meta = dma_alloc_coherent(&dev->pci_dev->dev, meta_len, + &meta_dma, GFP_KERNEL); + if (!meta) { + status = -ENOMEM; + goto unmap; + } + if (write) { + if (copy_from_user(meta, (void __user *)io.metadata, + meta_len)) { + status = -EFAULT; + goto unmap; + } + } + } + memset(&c, 0, sizeof(c)); c.rw.opcode = io.opcode; c.rw.flags = io.flags; @@ -1783,75 +1810,21 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) c.rw.reftag = cpu_to_le32(io.reftag); c.rw.apptag = cpu_to_le16(io.apptag); c.rw.appmask = cpu_to_le16(io.appmask); - - if (meta_len) { - meta_iod = nvme_map_user_pages(dev, io.opcode & 1, io.metadata, - meta_len); - if (IS_ERR(meta_iod)) { - status = PTR_ERR(meta_iod); - meta_iod = NULL; - goto unmap; - } - - meta_mem = dma_alloc_coherent(&dev->pci_dev->dev, meta_len, - &meta_dma_addr, GFP_KERNEL); - if (!meta_mem) { - status = -ENOMEM; - goto unmap; - } - - if (io.opcode & 1) { - int meta_offset = 0; - - for (i = 0; i < meta_iod->nents; i++) { - meta = kmap_atomic(sg_page(&meta_iod->sg[i])) + - meta_iod->sg[i].offset; - memcpy(meta_mem + meta_offset, meta, - meta_iod->sg[i].length); - kunmap_atomic(meta); - meta_offset += meta_iod->sg[i].length; - } - } - - c.rw.metadata = cpu_to_le64(meta_dma_addr); - } - - length = nvme_setup_prps(dev, iod, length, GFP_KERNEL); c.rw.prp1 = cpu_to_le64(sg_dma_address(iod->sg)); c.rw.prp2 = cpu_to_le64(iod->first_dma); - - if (length != (io.nblocks + 1) << ns->lba_shift) - status = -ENOMEM; - else - status = nvme_submit_io_cmd(dev, ns, &c, NULL); - - if (meta_len) { - if (status == NVME_SC_SUCCESS && !(io.opcode & 1)) { - int meta_offset = 0; - - for (i = 0; i < meta_iod->nents; i++) { - meta = kmap_atomic(sg_page(&meta_iod->sg[i])) + - meta_iod->sg[i].offset; - memcpy(meta, meta_mem + meta_offset, - meta_iod->sg[i].length); - kunmap_atomic(meta); - meta_offset += meta_iod->sg[i].length; - } - } - - dma_free_coherent(&dev->pci_dev->dev, meta_len, meta_mem, - meta_dma_addr); - } - + c.rw.metadata = cpu_to_le64(meta_dma); + status = nvme_submit_io_cmd(dev, ns, &c, NULL); unmap: - nvme_unmap_user_pages(dev, io.opcode & 1, iod); + nvme_unmap_user_pages(dev, write, iod); nvme_free_iod(dev, iod); - - if (meta_iod) { - nvme_unmap_user_pages(dev, io.opcode & 1, meta_iod); - nvme_free_iod(dev, meta_iod); + if (meta) { + if (status == NVME_SC_SUCCESS && !write) { + if (copy_to_user((void __user *)io.metadata, meta, + meta_len)) + status = -EFAULT; + } + dma_free_coherent(&dev->pci_dev->dev, meta_len, meta, meta_dma); } - return status; } @@ -2014,7 +1987,8 @@ static int nvme_revalidate_disk(struct gendisk *disk) struct nvme_dev *dev = ns->dev; struct nvme_id_ns *id; dma_addr_t dma_addr; - int lbaf, pi_type, old_ms; + u8 lbaf, pi_type; + u16 old_ms; unsigned short bs; id = dma_alloc_coherent(&dev->pci_dev->dev, 4096, &dma_addr, @@ -2035,6 +2009,7 @@ static int nvme_revalidate_disk(struct gendisk *disk) lbaf = id->flbas & NVME_NS_FLBAS_LBA_MASK; ns->lba_shift = id->lbaf[lbaf].ds; ns->ms = le16_to_cpu(id->lbaf[lbaf].ms); + ns->ext = ns->ms && (id->flbas & NVME_NS_FLBAS_META_EXT); /* * If identify namespace failed, use default 512 byte block size so @@ -2051,14 +2026,14 @@ static int nvme_revalidate_disk(struct gendisk *disk) if (blk_get_integrity(disk) && (ns->pi_type != pi_type || ns->ms != old_ms || bs != queue_logical_block_size(disk->queue) || - (ns->ms && id->flbas & NVME_NS_FLBAS_META_EXT))) + (ns->ms && ns->ext))) blk_integrity_unregister(disk); ns->pi_type = pi_type; blk_queue_logical_block_size(ns->queue, bs); if (ns->ms && !blk_get_integrity(disk) && (disk->flags & GENHD_FL_UP) && - !(id->flbas & NVME_NS_FLBAS_META_EXT)) + !ns->ext) nvme_init_integrity(ns); if (id->ncap == 0 || (ns->ms && !blk_get_integrity(disk))) -- cgit v1.2.1