Pull SCSI fixes from James Bottomley: "Three fixes: the two fnic ones are a revert and a refix, which is why the diffstat is a bit big. The target one also extracts a function to add a check for configuration and so looks bigger than it is" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: fnic: Move fnic_fnic_flush_tx() to a work queue scsi: Revert "scsi: fcoe: Fix potential deadlock on &fip->ctlr_lock" scsi: target: Fix unmap setup during configuration
Unified · Split
| @@ -319,17 +319,16 @@ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip) · 318 unmodified lines | ||
| 319 | 319 | { |
| 320 | 320 | struct fcoe_fcf *sel; |
| 321 | 321 | struct fcoe_fcf *fcf; |
| 322 | − unsigned long flags; | |
| 323 | 322 | |
| 324 | 323 | mutex_lock(&fip->ctlr_mutex); |
| 325 | − spin_lock_irqsave(&fip->ctlr_lock, flags); | |
| 324 | + spin_lock_bh(&fip->ctlr_lock); | |
| 326 | 325 | |
| 327 | 326 | kfree_skb(fip->flogi_req); |
| 328 | 327 | fip->flogi_req = NULL; |
| 329 | 328 | list_for_each_entry(fcf, &fip->fcfs, list) |
| 330 | 329 | fcf->flogi_sent = 0; |
| 331 | 330 | |
| 332 | − spin_unlock_irqrestore(&fip->ctlr_lock, flags); | |
| 331 | + spin_unlock_bh(&fip->ctlr_lock); | |
| 333 | 332 | sel = fip->sel_fcf; |
| 334 | 333 | |
| 335 | 334 | if (sel && ether_addr_equal(sel->fcf_mac, fip->dest_addr)) |
| @@ -700,7 +699,6 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, · 364 unmodified lines | ||
| 700 | 699 | { |
| 701 | 700 | struct fc_frame *fp; |
| 702 | 701 | struct fc_frame_header *fh; |
| 703 | − unsigned long flags; | |
| 704 | 702 | u16 old_xid; |
| 705 | 703 | u8 op; |
| 706 | 704 | u8 mac[ETH_ALEN]; |
| @@ -734,11 +732,11 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, · 27 unmodified lines | ||
| 734 | 732 | op = FIP_DT_FLOGI; |
| 735 | 733 | if (fip->mode == FIP_MODE_VN2VN) |
| 736 | 734 | break; |
| 737 | − spin_lock_irqsave(&fip->ctlr_lock, flags); | |
| 735 | + spin_lock_bh(&fip->ctlr_lock); | |
| 738 | 736 | kfree_skb(fip->flogi_req); |
| 739 | 737 | fip->flogi_req = skb; |
| 740 | 738 | fip->flogi_req_send = 1; |
| 741 | − spin_unlock_irqrestore(&fip->ctlr_lock, flags); | |
| 739 | + spin_unlock_bh(&fip->ctlr_lock); | |
| 742 | 740 | schedule_work(&fip->timer_work); |
| 743 | 741 | return -EINPROGRESS; |
| 744 | 742 | case ELS_FDISC: |
| @@ -1707,11 +1705,10 @@ static int fcoe_ctlr_flogi_send_locked(struct fcoe_ctlr *fip) · 962 unmodified lines | ||
| 1707 | 1705 | static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip) |
| 1708 | 1706 | { |
| 1709 | 1707 | struct fcoe_fcf *fcf; |
| 1710 | − unsigned long flags; | |
| 1711 | 1708 | int error; |
| 1712 | 1709 | |
| 1713 | 1710 | mutex_lock(&fip->ctlr_mutex); |
| 1714 | − spin_lock_irqsave(&fip->ctlr_lock, flags); | |
| 1711 | + spin_lock_bh(&fip->ctlr_lock); | |
| 1715 | 1712 | LIBFCOE_FIP_DBG(fip, "re-sending FLOGI - reselect\n"); |
| 1716 | 1713 | fcf = fcoe_ctlr_select(fip); |
| 1717 | 1714 | if (!fcf || fcf->flogi_sent) { |
| @@ -1722,7 +1719,7 @@ static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip) · 4 unmodified lines | ||
| 1722 | 1719 | fcoe_ctlr_solicit(fip, NULL); |
| 1723 | 1720 | error = fcoe_ctlr_flogi_send_locked(fip); |
| 1724 | 1721 | } |
| 1725 | − spin_unlock_irqrestore(&fip->ctlr_lock, flags); | |
| 1722 | + spin_unlock_bh(&fip->ctlr_lock); | |
| 1726 | 1723 | mutex_unlock(&fip->ctlr_mutex); |
| 1727 | 1724 | return error; |
| 1728 | 1725 | } |
| @@ -1739,9 +1736,8 @@ static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip) · 10 unmodified lines | ||
| 1739 | 1736 | static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip) |
| 1740 | 1737 | { |
| 1741 | 1738 | struct fcoe_fcf *fcf; |
| 1742 | − unsigned long flags; | |
| 1743 | 1739 | |
| 1744 | − spin_lock_irqsave(&fip->ctlr_lock, flags); | |
| 1740 | + spin_lock_bh(&fip->ctlr_lock); | |
| 1745 | 1741 | fcf = fip->sel_fcf; |
| 1746 | 1742 | if (!fcf || !fip->flogi_req_send) |
| 1747 | 1743 | goto unlock; |
| @@ -1768,7 +1764,7 @@ static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip) · 20 unmodified lines | ||
| 1768 | 1764 | } else /* XXX */ |
| 1769 | 1765 | LIBFCOE_FIP_DBG(fip, "No FCF selected - defer send\n"); |
| 1770 | 1766 | unlock: |
| 1771 | − spin_unlock_irqrestore(&fip->ctlr_lock, flags); | |
| 1767 | + spin_unlock_bh(&fip->ctlr_lock); | |
| 1772 | 1768 | } |
| 1773 | 1769 | |
| 1774 | 1770 | /** |
| @@ -305,6 +305,7 @@ struct fnic { · 304 unmodified lines | ||
| 305 | 305 | unsigned int copy_wq_base; |
| 306 | 306 | struct work_struct link_work; |
| 307 | 307 | struct work_struct frame_work; |
| 308 | + struct work_struct flush_work; | |
| 308 | 309 | struct sk_buff_head frame_queue; |
| 309 | 310 | struct sk_buff_head tx_queue; |
| 310 | 311 | |
| @@ -363,7 +364,7 @@ void fnic_handle_event(struct work_struct *work); · 52 unmodified lines | ||
| 363 | 364 | int fnic_rq_cmpl_handler(struct fnic *fnic, int); |
| 364 | 365 | int fnic_alloc_rq_frame(struct vnic_rq *rq); |
| 365 | 366 | void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf); |
| 366 | −void fnic_flush_tx(struct fnic *); | |
| 367 | +void fnic_flush_tx(struct work_struct *work); | |
| 367 | 368 | void fnic_eth_send(struct fcoe_ctlr *, struct sk_buff *skb); |
| 368 | 369 | void fnic_set_port_id(struct fc_lport *, u32, struct fc_frame *); |
| 369 | 370 | void fnic_update_mac(struct fc_lport *, u8 *new); |
| @@ -1182,7 +1182,7 @@ int fnic_send(struct fc_lport *lp, struct fc_frame *fp) · 1181 unmodified lines | ||
| 1182 | 1182 | |
| 1183 | 1183 | /** |
| 1184 | 1184 | * fnic_flush_tx() - send queued frames. |
| 1185 | − * @fnic: fnic device | |
| 1185 | + * @work: pointer to work element | |
| 1186 | 1186 | * |
| 1187 | 1187 | * Send frames that were waiting to go out in FC or Ethernet mode. |
| 1188 | 1188 | * Whenever changing modes we purge queued frames, so these frames should |
| @@ -1190,8 +1190,9 @@ int fnic_send(struct fc_lport *lp, struct fc_frame *fp) · 1 unmodified line | ||
| 1190 | 1190 | * |
| 1191 | 1191 | * Called without fnic_lock held. |
| 1192 | 1192 | */ |
| 1193 | −void fnic_flush_tx(struct fnic *fnic) | |
| 1193 | +void fnic_flush_tx(struct work_struct *work) | |
| 1194 | 1194 | { |
| 1195 | + struct fnic *fnic = container_of(work, struct fnic, flush_work); | |
| 1195 | 1196 | struct sk_buff *skb; |
| 1196 | 1197 | struct fc_frame *fp; |
| 1197 | 1198 | |
| @@ -830,6 +830,7 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 829 unmodified lines | ||
| 830 | 830 | spin_lock_init(&fnic->vlans_lock); |
| 831 | 831 | INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame); |
| 832 | 832 | INIT_WORK(&fnic->event_work, fnic_handle_event); |
| 833 | + INIT_WORK(&fnic->flush_work, fnic_flush_tx); | |
| 833 | 834 | skb_queue_head_init(&fnic->fip_frame_queue); |
| 834 | 835 | INIT_LIST_HEAD(&fnic->evlist); |
| 835 | 836 | INIT_LIST_HEAD(&fnic->vlans); |
| @@ -680,7 +680,7 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic, · 679 unmodified lines | ||
| 680 | 680 | |
| 681 | 681 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); |
| 682 | 682 | |
| 683 | − fnic_flush_tx(fnic); | |
| 683 | + queue_work(fnic_event_queue, &fnic->flush_work); | |
| 684 | 684 | |
| 685 | 685 | reset_cmpl_handler_end: |
| 686 | 686 | fnic_clear_state_flags(fnic, FNIC_FLAGS_FWRESET); |
| @@ -736,7 +736,7 @@ static int fnic_fcpio_flogi_reg_cmpl_handler(struct fnic *fnic, · 49 unmodified lines | ||
| 736 | 736 | } |
| 737 | 737 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); |
| 738 | 738 | |
| 739 | − fnic_flush_tx(fnic); | |
| 739 | + queue_work(fnic_event_queue, &fnic->flush_work); | |
| 740 | 740 | queue_work(fnic_event_queue, &fnic->frame_work); |
| 741 | 741 | } else { |
| 742 | 742 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); |
| @@ -759,6 +759,29 @@ static ssize_t emulate_tas_store(struct config_item *item, · 758 unmodified lines | ||
| 759 | 759 | return count; |
| 760 | 760 | } |
| 761 | 761 | |
| 762 | +static int target_try_configure_unmap(struct se_device *dev, | |
| 763 | + const char *config_opt) | |
| 764 | +{ | |
| 765 | + if (!dev->transport->configure_unmap) { | |
| 766 | + pr_err("Generic Block Discard not supported\n"); | |
| 767 | + return -ENOSYS; | |
| 768 | + } | |
| 769 | + | |
| 770 | + if (!target_dev_configured(dev)) { | |
| 771 | + pr_err("Generic Block Discard setup for %s requires device to be configured\n", | |
| 772 | + config_opt); | |
| 773 | + return -ENODEV; | |
| 774 | + } | |
| 775 | + | |
| 776 | + if (!dev->transport->configure_unmap(dev)) { | |
| 777 | + pr_err("Generic Block Discard setup for %s failed\n", | |
| 778 | + config_opt); | |
| 779 | + return -ENOSYS; | |
| 780 | + } | |
| 781 | + | |
| 782 | + return 0; | |
| 783 | +} | |
| 784 | + | |
| 762 | 785 | static ssize_t emulate_tpu_store(struct config_item *item, |
| 763 | 786 | const char *page, size_t count) |
| 764 | 787 | { |
| @@ -776,11 +799,9 @@ static ssize_t emulate_tpu_store(struct config_item *item, · 11 unmodified lines | ||
| 776 | 799 | * Discard supported is detected iblock_create_virtdevice(). |
| 777 | 800 | */ |
| 778 | 801 | if (flag && !da->max_unmap_block_desc_count) { |
| 779 | − if (!dev->transport->configure_unmap || | |
| 780 | − !dev->transport->configure_unmap(dev)) { | |
| 781 | − pr_err("Generic Block Discard not supported\n"); | |
| 782 | − return -ENOSYS; | |
| 783 | − } | |
| 802 | + ret = target_try_configure_unmap(dev, "emulate_tpu"); | |
| 803 | + if (ret) | |
| 804 | + return ret; | |
| 784 | 805 | } |
| 785 | 806 | |
| 786 | 807 | da->emulate_tpu = flag; |
| @@ -806,11 +827,9 @@ static ssize_t emulate_tpws_store(struct config_item *item, · 19 unmodified lines | ||
| 806 | 827 | * Discard supported is detected iblock_create_virtdevice(). |
| 807 | 828 | */ |
| 808 | 829 | if (flag && !da->max_unmap_block_desc_count) { |
| 809 | − if (!dev->transport->configure_unmap || | |
| 810 | − !dev->transport->configure_unmap(dev)) { | |
| 811 | − pr_err("Generic Block Discard not supported\n"); | |
| 812 | − return -ENOSYS; | |
| 813 | − } | |
| 830 | + ret = target_try_configure_unmap(dev, "emulate_tpws"); | |
| 831 | + if (ret) | |
| 832 | + return ret; | |
| 814 | 833 | } |
| 815 | 834 | |
| 816 | 835 | da->emulate_tpws = flag; |
| @@ -1022,12 +1041,9 @@ static ssize_t unmap_zeroes_data_store(struct config_item *item, · 205 unmodified lines | ||
| 1022 | 1041 | * Discard supported is detected iblock_configure_device(). |
| 1023 | 1042 | */ |
| 1024 | 1043 | if (flag && !da->max_unmap_block_desc_count) { |
| 1025 | − if (!dev->transport->configure_unmap || | |
| 1026 | − !dev->transport->configure_unmap(dev)) { | |
| 1027 | − pr_err("dev[%p]: Thin Provisioning LBPRZ will not be set because max_unmap_block_desc_count is zero\n", | |
| 1028 | − da->da_dev); | |
| 1029 | − return -ENOSYS; | |
| 1030 | − } | |
| 1044 | + ret = target_try_configure_unmap(dev, "unmap_zeroes_data"); | |
| 1045 | + if (ret) | |
| 1046 | + return ret; | |
| 1031 | 1047 | } |
| 1032 | 1048 | da->unmap_zeroes_data = flag; |
| 1033 | 1049 | pr_debug("dev[%p]: SE Device Thin Provisioning LBPRZ bit: %d\n", |