Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:
"A few select fixes that should go into this series. Mainly for NVMe,
but also a single stable fix for nbd from Josef"

* 'for-linus' of git://git.kernel.dk/linux-block:
nbd: handle interrupted sendmsg with a sndtimeo set
nvme-rdma: Fix error status return in tagset allocation failure
nvme-rdma: Fix possible double free in reconnect flow
nvmet: synchronize sqhd update
nvme-fc: retry initial controller connections 3 times
nvme-fc: fix iowait hang

+69 -14
+11 -2
drivers/block/nbd.c
··· 386 386 return result; 387 387 } 388 388 389 + /* 390 + * Different settings for sk->sk_sndtimeo can result in different return values 391 + * if there is a signal pending when we enter sendmsg, because reasons? 392 + */ 393 + static inline int was_interrupted(int result) 394 + { 395 + return result == -ERESTARTSYS || result == -EINTR; 396 + } 397 + 389 398 /* always call with the tx_lock held */ 390 399 static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) 391 400 { ··· 467 458 result = sock_xmit(nbd, index, 1, &from, 468 459 (type == NBD_CMD_WRITE) ? MSG_MORE : 0, &sent); 469 460 if (result <= 0) { 470 - if (result == -ERESTARTSYS) { 461 + if (was_interrupted(result)) { 471 462 /* If we havne't sent anything we can just return BUSY, 472 463 * however if we have sent something we need to make 473 464 * sure we only allow this req to be sent until we are ··· 511 502 } 512 503 result = sock_xmit(nbd, index, 1, &from, flags, &sent); 513 504 if (result <= 0) { 514 - if (result == -ERESTARTSYS) { 505 + if (was_interrupted(result)) { 515 506 /* We've already sent the header, we 516 507 * have no choice but to set pending and 517 508 * return BUSY.
+33 -4
drivers/nvme/host/fc.c
··· 2545 2545 nvme_fc_abort_aen_ops(ctrl); 2546 2546 2547 2547 /* wait for all io that had to be aborted */ 2548 - spin_lock_irqsave(&ctrl->lock, flags); 2548 + spin_lock_irq(&ctrl->lock); 2549 2549 wait_event_lock_irq(ctrl->ioabort_wait, ctrl->iocnt == 0, ctrl->lock); 2550 2550 ctrl->flags &= ~FCCTRL_TERMIO; 2551 - spin_unlock_irqrestore(&ctrl->lock, flags); 2551 + spin_unlock_irq(&ctrl->lock); 2552 2552 2553 2553 nvme_fc_term_aen_ops(ctrl); 2554 2554 ··· 2734 2734 { 2735 2735 struct nvme_fc_ctrl *ctrl; 2736 2736 unsigned long flags; 2737 - int ret, idx; 2737 + int ret, idx, retry; 2738 2738 2739 2739 if (!(rport->remoteport.port_role & 2740 2740 (FC_PORT_ROLE_NVME_DISCOVERY | FC_PORT_ROLE_NVME_TARGET))) { ··· 2760 2760 ctrl->rport = rport; 2761 2761 ctrl->dev = lport->dev; 2762 2762 ctrl->cnum = idx; 2763 + init_waitqueue_head(&ctrl->ioabort_wait); 2763 2764 2764 2765 get_device(ctrl->dev); 2765 2766 kref_init(&ctrl->ref); ··· 2826 2825 list_add_tail(&ctrl->ctrl_list, &rport->ctrl_list); 2827 2826 spin_unlock_irqrestore(&rport->lock, flags); 2828 2827 2829 - ret = nvme_fc_create_association(ctrl); 2828 + /* 2829 + * It's possible that transactions used to create the association 2830 + * may fail. Examples: CreateAssociation LS or CreateIOConnection 2831 + * LS gets dropped/corrupted/fails; or a frame gets dropped or a 2832 + * command times out for one of the actions to init the controller 2833 + * (Connect, Get/Set_Property, Set_Features, etc). Many of these 2834 + * transport errors (frame drop, LS failure) inherently must kill 2835 + * the association. The transport is coded so that any command used 2836 + * to create the association (prior to a LIVE state transition 2837 + * while NEW or RECONNECTING) will fail if it completes in error or 2838 + * times out. 2839 + * 2840 + * As such: as the connect request was mostly likely due to a 2841 + * udev event that discovered the remote port, meaning there is 2842 + * not an admin or script there to restart if the connect 2843 + * request fails, retry the initial connection creation up to 2844 + * three times before giving up and declaring failure. 2845 + */ 2846 + for (retry = 0; retry < 3; retry++) { 2847 + ret = nvme_fc_create_association(ctrl); 2848 + if (!ret) 2849 + break; 2850 + } 2851 + 2830 2852 if (ret) { 2853 + /* couldn't schedule retry - fail out */ 2854 + dev_err(ctrl->ctrl.device, 2855 + "NVME-FC{%d}: Connect retry failed\n", ctrl->cnum); 2856 + 2831 2857 ctrl->ctrl.opts = NULL; 2858 + 2832 2859 /* initiate nvme ctrl ref counting teardown */ 2833 2860 nvme_uninit_ctrl(&ctrl->ctrl); 2834 2861 nvme_put_ctrl(&ctrl->ctrl);
+12 -4
drivers/nvme/host/rdma.c
··· 571 571 if (test_and_set_bit(NVME_RDMA_Q_DELETING, &queue->flags)) 572 572 return; 573 573 574 + if (nvme_rdma_queue_idx(queue) == 0) { 575 + nvme_rdma_free_qe(queue->device->dev, 576 + &queue->ctrl->async_event_sqe, 577 + sizeof(struct nvme_command), DMA_TO_DEVICE); 578 + } 579 + 574 580 nvme_rdma_destroy_queue_ib(queue); 575 581 rdma_destroy_id(queue->cm_id); 576 582 } ··· 745 739 static void nvme_rdma_destroy_admin_queue(struct nvme_rdma_ctrl *ctrl, 746 740 bool remove) 747 741 { 748 - nvme_rdma_free_qe(ctrl->queues[0].device->dev, &ctrl->async_event_sqe, 749 - sizeof(struct nvme_command), DMA_TO_DEVICE); 750 742 nvme_rdma_stop_queue(&ctrl->queues[0]); 751 743 if (remove) { 752 744 blk_cleanup_queue(ctrl->ctrl.admin_q); ··· 769 765 770 766 if (new) { 771 767 ctrl->ctrl.admin_tagset = nvme_rdma_alloc_tagset(&ctrl->ctrl, true); 772 - if (IS_ERR(ctrl->ctrl.admin_tagset)) 768 + if (IS_ERR(ctrl->ctrl.admin_tagset)) { 769 + error = PTR_ERR(ctrl->ctrl.admin_tagset); 773 770 goto out_free_queue; 771 + } 774 772 775 773 ctrl->ctrl.admin_q = blk_mq_init_queue(&ctrl->admin_tag_set); 776 774 if (IS_ERR(ctrl->ctrl.admin_q)) { ··· 852 846 853 847 if (new) { 854 848 ctrl->ctrl.tagset = nvme_rdma_alloc_tagset(&ctrl->ctrl, false); 855 - if (IS_ERR(ctrl->ctrl.tagset)) 849 + if (IS_ERR(ctrl->ctrl.tagset)) { 850 + ret = PTR_ERR(ctrl->ctrl.tagset); 856 851 goto out_free_io_queues; 852 + } 857 853 858 854 ctrl->ctrl.connect_q = blk_mq_init_queue(&ctrl->tag_set); 859 855 if (IS_ERR(ctrl->ctrl.connect_q)) {
+12 -3
drivers/nvme/target/core.c
··· 387 387 388 388 static void __nvmet_req_complete(struct nvmet_req *req, u16 status) 389 389 { 390 + u32 old_sqhd, new_sqhd; 391 + u16 sqhd; 392 + 390 393 if (status) 391 394 nvmet_set_status(req, status); 392 395 393 - if (req->sq->size) 394 - req->sq->sqhd = (req->sq->sqhd + 1) % req->sq->size; 395 - req->rsp->sq_head = cpu_to_le16(req->sq->sqhd); 396 + if (req->sq->size) { 397 + do { 398 + old_sqhd = req->sq->sqhd; 399 + new_sqhd = (old_sqhd + 1) % req->sq->size; 400 + } while (cmpxchg(&req->sq->sqhd, old_sqhd, new_sqhd) != 401 + old_sqhd); 402 + } 403 + sqhd = req->sq->sqhd & 0x0000FFFF; 404 + req->rsp->sq_head = cpu_to_le16(sqhd); 396 405 req->rsp->sq_id = cpu_to_le16(req->sq->qid); 397 406 req->rsp->command_id = req->cmd->common.command_id; 398 407
+1 -1
drivers/nvme/target/nvmet.h
··· 74 74 struct percpu_ref ref; 75 75 u16 qid; 76 76 u16 size; 77 - u16 sqhd; 77 + u32 sqhd; 78 78 struct completion free_done; 79 79 struct completion confirm_done; 80 80 };