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 tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fixes from James Bottomley:
"13 fixes, all in drivers.

The most extensive changes are in the iscsi series (affecting drivers
qedi, cxgbi and bnx2i), the next most is scsi_debug, but that's just a
simple revert and then minor updates to pm80xx"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
scsi: iscsi: MAINTAINERS: Add Mike Christie as co-maintainer
scsi: qedi: Fix failed disconnect handling
scsi: iscsi: Fix NOP handling during conn recovery
scsi: iscsi: Merge suspend fields
scsi: iscsi: Fix unbound endpoint error handling
scsi: iscsi: Fix conn cleanup and stop race during iscsid restart
scsi: iscsi: Fix endpoint reuse regression
scsi: iscsi: Release endpoint ID when its freed
scsi: iscsi: Fix offload conn cleanup when iscsid restarts
scsi: iscsi: Move iscsi_ep_disconnect()
scsi: pm80xx: Enable upper inbound, outbound queues
scsi: pm80xx: Mask and unmask upper interrupt vectors 32-63
Revert "scsi: scsi_debug: Address races following module load"

+280 -311
+1
MAINTAINERS
··· 10371 10371 ISCSI 10372 10372 M: Lee Duncan <lduncan@suse.com> 10373 10373 M: Chris Leech <cleech@redhat.com> 10374 + M: Mike Christie <michael.christie@oracle.com> 10374 10375 L: open-iscsi@googlegroups.com 10375 10376 L: linux-scsi@vger.kernel.org 10376 10377 S: Maintained
+1 -1
drivers/scsi/bnx2i/bnx2i_hwi.c
··· 1977 1977 if (nopin->cq_req_sn != qp->cqe_exp_seq_sn) 1978 1978 break; 1979 1979 1980 - if (unlikely(test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx))) { 1980 + if (unlikely(test_bit(ISCSI_CONN_FLAG_SUSPEND_RX, &conn->flags))) { 1981 1981 if (nopin->op_code == ISCSI_OP_NOOP_IN && 1982 1982 nopin->itt == (u16) RESERVED_ITT) { 1983 1983 printk(KERN_ALERT "bnx2i: Unsolicited "
+1 -1
drivers/scsi/bnx2i/bnx2i_iscsi.c
··· 1721 1721 struct iscsi_conn *conn = ep->conn->cls_conn->dd_data; 1722 1722 1723 1723 /* Must suspend all rx queue activity for this ep */ 1724 - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); 1724 + set_bit(ISCSI_CONN_FLAG_SUSPEND_RX, &conn->flags); 1725 1725 } 1726 1726 /* CONN_DISCONNECT timeout may or may not be an issue depending 1727 1727 * on what transcribed in TCP layer, different targets behave
+3 -3
drivers/scsi/cxgbi/libcxgbi.c
··· 1634 1634 log_debug(1 << CXGBI_DBG_PDU_RX, 1635 1635 "csk 0x%p, conn 0x%p.\n", csk, conn); 1636 1636 1637 - if (unlikely(!conn || conn->suspend_rx)) { 1637 + if (unlikely(!conn || test_bit(ISCSI_CONN_FLAG_SUSPEND_RX, &conn->flags))) { 1638 1638 log_debug(1 << CXGBI_DBG_PDU_RX, 1639 - "csk 0x%p, conn 0x%p, id %d, suspend_rx %lu!\n", 1639 + "csk 0x%p, conn 0x%p, id %d, conn flags 0x%lx!\n", 1640 1640 csk, conn, conn ? conn->id : 0xFF, 1641 - conn ? conn->suspend_rx : 0xFF); 1641 + conn ? conn->flags : 0xFF); 1642 1642 return; 1643 1643 } 1644 1644
+16 -11
drivers/scsi/libiscsi.c
··· 678 678 struct iscsi_task *task; 679 679 itt_t itt; 680 680 681 - if (session->state == ISCSI_STATE_TERMINATE) 681 + if (session->state == ISCSI_STATE_TERMINATE || 682 + !test_bit(ISCSI_CONN_FLAG_BOUND, &conn->flags)) 682 683 return NULL; 683 684 684 685 if (opcode == ISCSI_OP_LOGIN || opcode == ISCSI_OP_TEXT) { ··· 1393 1392 if (conn->stop_stage == 0) 1394 1393 session->state = ISCSI_STATE_FAILED; 1395 1394 1396 - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); 1397 - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); 1395 + set_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags); 1396 + set_bit(ISCSI_CONN_FLAG_SUSPEND_RX, &conn->flags); 1398 1397 return true; 1399 1398 } 1400 1399 ··· 1455 1454 * Do this after dropping the extra ref because if this was a requeue 1456 1455 * it's removed from that list and cleanup_queued_task would miss it. 1457 1456 */ 1458 - if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) { 1457 + if (test_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags)) { 1459 1458 /* 1460 1459 * Save the task and ref in case we weren't cleaning up this 1461 1460 * task and get woken up again. ··· 1533 1532 int rc = 0; 1534 1533 1535 1534 spin_lock_bh(&conn->session->frwd_lock); 1536 - if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) { 1535 + if (test_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags)) { 1537 1536 ISCSI_DBG_SESSION(conn->session, "Tx suspended!\n"); 1538 1537 spin_unlock_bh(&conn->session->frwd_lock); 1539 1538 return -ENODATA; ··· 1747 1746 goto fault; 1748 1747 } 1749 1748 1750 - if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) { 1749 + if (test_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags)) { 1751 1750 reason = FAILURE_SESSION_IN_RECOVERY; 1752 1751 sc->result = DID_REQUEUE << 16; 1753 1752 goto fault; ··· 1936 1935 void iscsi_suspend_queue(struct iscsi_conn *conn) 1937 1936 { 1938 1937 spin_lock_bh(&conn->session->frwd_lock); 1939 - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); 1938 + set_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags); 1940 1939 spin_unlock_bh(&conn->session->frwd_lock); 1941 1940 } 1942 1941 EXPORT_SYMBOL_GPL(iscsi_suspend_queue); ··· 1954 1953 struct Scsi_Host *shost = conn->session->host; 1955 1954 struct iscsi_host *ihost = shost_priv(shost); 1956 1955 1957 - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); 1956 + set_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags); 1958 1957 if (ihost->workq) 1959 1958 flush_workqueue(ihost->workq); 1960 1959 } ··· 1962 1961 1963 1962 static void iscsi_start_tx(struct iscsi_conn *conn) 1964 1963 { 1965 - clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); 1964 + clear_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags); 1966 1965 iscsi_conn_queue_work(conn); 1967 1966 } 1968 1967 ··· 2215 2214 iscsi_suspend_tx(conn); 2216 2215 2217 2216 spin_lock_bh(&session->frwd_lock); 2217 + clear_bit(ISCSI_CONN_FLAG_BOUND, &conn->flags); 2218 + 2218 2219 if (!is_active) { 2219 2220 /* 2220 2221 * if logout timed out before userspace could even send a PDU ··· 3320 3317 spin_lock_bh(&session->frwd_lock); 3321 3318 if (is_leading) 3322 3319 session->leadconn = conn; 3320 + 3321 + set_bit(ISCSI_CONN_FLAG_BOUND, &conn->flags); 3323 3322 spin_unlock_bh(&session->frwd_lock); 3324 3323 3325 3324 /* ··· 3334 3329 /* 3335 3330 * Unblock xmitworker(), Login Phase will pass through. 3336 3331 */ 3337 - clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); 3338 - clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); 3332 + clear_bit(ISCSI_CONN_FLAG_SUSPEND_RX, &conn->flags); 3333 + clear_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags); 3339 3334 return 0; 3340 3335 } 3341 3336 EXPORT_SYMBOL_GPL(iscsi_conn_bind);
+1 -1
drivers/scsi/libiscsi_tcp.c
··· 927 927 */ 928 928 conn->last_recv = jiffies; 929 929 930 - if (unlikely(conn->suspend_rx)) { 930 + if (unlikely(test_bit(ISCSI_CONN_FLAG_SUSPEND_RX, &conn->flags))) { 931 931 ISCSI_DBG_TCP(conn, "Rx suspended!\n"); 932 932 *status = ISCSI_TCP_SUSPENDED; 933 933 return 0;
+24 -9
drivers/scsi/pm8001/pm80xx_hwi.c
··· 766 766 pm8001_ha->main_cfg_tbl.pm80xx_tbl.pcs_event_log_severity = 0x01; 767 767 pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_interrupt = 0x01; 768 768 769 + /* Enable higher IQs and OQs, 32 to 63, bit 16 */ 770 + if (pm8001_ha->max_q_num > 32) 771 + pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_interrupt |= 772 + 1 << 16; 769 773 /* Disable end to end CRC checking */ 770 774 pm8001_ha->main_cfg_tbl.pm80xx_tbl.crc_core_dump = (0x1 << 16); 771 775 ··· 1030 1026 gst_len_mpistate = gst_len_mpistate >> 16; 1031 1027 if (0x0000 != gst_len_mpistate) 1032 1028 return -EBUSY; 1029 + 1030 + /* 1031 + * As per controller datasheet, after successful MPI 1032 + * initialization minimum 500ms delay is required before 1033 + * issuing commands. 1034 + */ 1035 + msleep(500); 1033 1036 1034 1037 return 0; 1035 1038 } ··· 1738 1727 pm80xx_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha, u8 vec) 1739 1728 { 1740 1729 #ifdef PM8001_USE_MSIX 1741 - u32 mask; 1742 - mask = (u32)(1 << vec); 1743 - 1744 - pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_CLR, (u32)(mask & 0xFFFFFFFF)); 1730 + if (vec < 32) 1731 + pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_CLR, 1U << vec); 1732 + else 1733 + pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_CLR_U, 1734 + 1U << (vec - 32)); 1745 1735 return; 1746 1736 #endif 1747 1737 pm80xx_chip_intx_interrupt_enable(pm8001_ha); ··· 1758 1746 pm80xx_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha, u8 vec) 1759 1747 { 1760 1748 #ifdef PM8001_USE_MSIX 1761 - u32 mask; 1762 - if (vec == 0xFF) 1763 - mask = 0xFFFFFFFF; 1749 + if (vec == 0xFF) { 1750 + /* disable all vectors 0-31, 32-63 */ 1751 + pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, 0xFFFFFFFF); 1752 + pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_U, 0xFFFFFFFF); 1753 + } else if (vec < 32) 1754 + pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, 1U << vec); 1764 1755 else 1765 - mask = (u32)(1 << vec); 1766 - pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, (u32)(mask & 0xFFFFFFFF)); 1756 + pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_U, 1757 + 1U << (vec - 32)); 1767 1758 return; 1768 1759 #endif 1769 1760 pm80xx_chip_intx_interrupt_disable(pm8001_ha);
+34 -35
drivers/scsi/qedi/qedi_iscsi.c
··· 860 860 return qedi_iscsi_send_ioreq(task); 861 861 } 862 862 863 + static void qedi_offload_work(struct work_struct *work) 864 + { 865 + struct qedi_endpoint *qedi_ep = 866 + container_of(work, struct qedi_endpoint, offload_work); 867 + struct qedi_ctx *qedi; 868 + int wait_delay = 5 * HZ; 869 + int ret; 870 + 871 + qedi = qedi_ep->qedi; 872 + 873 + ret = qedi_iscsi_offload_conn(qedi_ep); 874 + if (ret) { 875 + QEDI_ERR(&qedi->dbg_ctx, 876 + "offload error: iscsi_cid=%u, qedi_ep=%p, ret=%d\n", 877 + qedi_ep->iscsi_cid, qedi_ep, ret); 878 + qedi_ep->state = EP_STATE_OFLDCONN_FAILED; 879 + return; 880 + } 881 + 882 + ret = wait_event_interruptible_timeout(qedi_ep->tcp_ofld_wait, 883 + (qedi_ep->state == 884 + EP_STATE_OFLDCONN_COMPL), 885 + wait_delay); 886 + if (ret <= 0 || qedi_ep->state != EP_STATE_OFLDCONN_COMPL) { 887 + qedi_ep->state = EP_STATE_OFLDCONN_FAILED; 888 + QEDI_ERR(&qedi->dbg_ctx, 889 + "Offload conn TIMEOUT iscsi_cid=%u, qedi_ep=%p\n", 890 + qedi_ep->iscsi_cid, qedi_ep); 891 + } 892 + } 893 + 863 894 static struct iscsi_endpoint * 864 895 qedi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, 865 896 int non_blocking) ··· 939 908 } 940 909 qedi_ep = ep->dd_data; 941 910 memset(qedi_ep, 0, sizeof(struct qedi_endpoint)); 911 + INIT_WORK(&qedi_ep->offload_work, qedi_offload_work); 942 912 qedi_ep->state = EP_STATE_IDLE; 943 913 qedi_ep->iscsi_cid = (u32)-1; 944 914 qedi_ep->qedi = qedi; ··· 1088 1056 qedi_ep = ep->dd_data; 1089 1057 qedi = qedi_ep->qedi; 1090 1058 1059 + flush_work(&qedi_ep->offload_work); 1060 + 1091 1061 if (qedi_ep->state == EP_STATE_OFLDCONN_START) 1092 1062 goto ep_exit_recover; 1093 - 1094 - if (qedi_ep->state != EP_STATE_OFLDCONN_NONE) 1095 - flush_work(&qedi_ep->offload_work); 1096 1063 1097 1064 if (qedi_ep->conn) { 1098 1065 qedi_conn = qedi_ep->conn; ··· 1266 1235 return rc; 1267 1236 } 1268 1237 1269 - static void qedi_offload_work(struct work_struct *work) 1270 - { 1271 - struct qedi_endpoint *qedi_ep = 1272 - container_of(work, struct qedi_endpoint, offload_work); 1273 - struct qedi_ctx *qedi; 1274 - int wait_delay = 5 * HZ; 1275 - int ret; 1276 - 1277 - qedi = qedi_ep->qedi; 1278 - 1279 - ret = qedi_iscsi_offload_conn(qedi_ep); 1280 - if (ret) { 1281 - QEDI_ERR(&qedi->dbg_ctx, 1282 - "offload error: iscsi_cid=%u, qedi_ep=%p, ret=%d\n", 1283 - qedi_ep->iscsi_cid, qedi_ep, ret); 1284 - qedi_ep->state = EP_STATE_OFLDCONN_FAILED; 1285 - return; 1286 - } 1287 - 1288 - ret = wait_event_interruptible_timeout(qedi_ep->tcp_ofld_wait, 1289 - (qedi_ep->state == 1290 - EP_STATE_OFLDCONN_COMPL), 1291 - wait_delay); 1292 - if ((ret <= 0) || (qedi_ep->state != EP_STATE_OFLDCONN_COMPL)) { 1293 - qedi_ep->state = EP_STATE_OFLDCONN_FAILED; 1294 - QEDI_ERR(&qedi->dbg_ctx, 1295 - "Offload conn TIMEOUT iscsi_cid=%u, qedi_ep=%p\n", 1296 - qedi_ep->iscsi_cid, qedi_ep); 1297 - } 1298 - } 1299 - 1300 1238 static int qedi_set_path(struct Scsi_Host *shost, struct iscsi_path *path_data) 1301 1239 { 1302 1240 struct qedi_ctx *qedi; ··· 1381 1381 qedi_ep->dst_addr, qedi_ep->dst_port); 1382 1382 } 1383 1383 1384 - INIT_WORK(&qedi_ep->offload_work, qedi_offload_work); 1385 1384 queue_work(qedi->offload_thread, &qedi_ep->offload_work); 1386 1385 1387 1386 ret = 0;
+51 -146
drivers/scsi/scsi_debug.c
··· 32 32 #include <linux/blkdev.h> 33 33 #include <linux/crc-t10dif.h> 34 34 #include <linux/spinlock.h> 35 - #include <linux/mutex.h> 36 35 #include <linux/interrupt.h> 37 36 #include <linux/atomic.h> 38 37 #include <linux/hrtimer.h> ··· 731 732 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 732 733 }; 733 734 734 - static atomic_t sdebug_num_hosts; 735 - static DEFINE_MUTEX(add_host_mutex); 736 - 735 + static int sdebug_num_hosts; 737 736 static int sdebug_add_host = DEF_NUM_HOST; /* in sysfs this is relative */ 738 737 static int sdebug_ato = DEF_ATO; 739 738 static int sdebug_cdb_len = DEF_CDB_LEN; ··· 778 781 static bool sdebug_random = DEF_RANDOM; 779 782 static bool sdebug_per_host_store = DEF_PER_HOST_STORE; 780 783 static bool sdebug_removable = DEF_REMOVABLE; 781 - static bool sdebug_deflect_incoming; 782 784 static bool sdebug_clustering; 783 785 static bool sdebug_host_lock = DEF_HOST_LOCK; 784 786 static bool sdebug_strict = DEF_STRICT; ··· 5118 5122 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); 5119 5123 if (sdp->host->max_cmd_len != SDEBUG_MAX_CMD_LEN) 5120 5124 sdp->host->max_cmd_len = SDEBUG_MAX_CMD_LEN; 5121 - if (smp_load_acquire(&sdebug_deflect_incoming)) { 5122 - pr_info("Exit early due to deflect_incoming\n"); 5123 - return 1; 5124 - } 5125 5125 if (devip == NULL) { 5126 5126 devip = find_build_dev_info(sdp); 5127 5127 if (devip == NULL) ··· 5203 5211 } 5204 5212 5205 5213 /* Deletes (stops) timers or work queues of all queued commands */ 5206 - static void stop_all_queued(bool done_with_no_conn) 5214 + static void stop_all_queued(void) 5207 5215 { 5208 5216 unsigned long iflags; 5209 5217 int j, k; ··· 5212 5220 struct sdebug_queued_cmd *sqcp; 5213 5221 struct sdebug_dev_info *devip; 5214 5222 struct sdebug_defer *sd_dp; 5215 - struct scsi_cmnd *scp; 5216 5223 5217 5224 for (j = 0, sqp = sdebug_q_arr; j < submit_queues; ++j, ++sqp) { 5218 5225 spin_lock_irqsave(&sqp->qc_lock, iflags); 5219 5226 for (k = 0; k < SDEBUG_CANQUEUE; ++k) { 5220 5227 if (test_bit(k, sqp->in_use_bm)) { 5221 5228 sqcp = &sqp->qc_arr[k]; 5222 - scp = sqcp->a_cmnd; 5223 - if (!scp) 5229 + if (sqcp->a_cmnd == NULL) 5224 5230 continue; 5225 5231 devip = (struct sdebug_dev_info *) 5226 5232 sqcp->a_cmnd->device->hostdata; ··· 5233 5243 l_defer_t = SDEB_DEFER_NONE; 5234 5244 spin_unlock_irqrestore(&sqp->qc_lock, iflags); 5235 5245 stop_qc_helper(sd_dp, l_defer_t); 5236 - if (done_with_no_conn && l_defer_t != SDEB_DEFER_NONE) { 5237 - scp->result = DID_NO_CONNECT << 16; 5238 - scsi_done(scp); 5239 - } 5240 5246 clear_bit(k, sqp->in_use_bm); 5241 5247 spin_lock_irqsave(&sqp->qc_lock, iflags); 5242 5248 } ··· 5375 5389 } 5376 5390 } 5377 5391 spin_unlock(&sdebug_host_list_lock); 5378 - stop_all_queued(false); 5392 + stop_all_queued(); 5379 5393 if (SDEBUG_OPT_RESET_NOISE & sdebug_opts) 5380 5394 sdev_printk(KERN_INFO, SCpnt->device, 5381 5395 "%s: %d device(s) found\n", __func__, k); ··· 5435 5449 } 5436 5450 } 5437 5451 5438 - static void sdeb_block_all_queues(void) 5452 + static void block_unblock_all_queues(bool block) 5439 5453 { 5440 5454 int j; 5441 5455 struct sdebug_queue *sqp; 5442 5456 5443 5457 for (j = 0, sqp = sdebug_q_arr; j < submit_queues; ++j, ++sqp) 5444 - atomic_set(&sqp->blocked, (int)true); 5445 - } 5446 - 5447 - static void sdeb_unblock_all_queues(void) 5448 - { 5449 - int j; 5450 - struct sdebug_queue *sqp; 5451 - 5452 - for (j = 0, sqp = sdebug_q_arr; j < submit_queues; ++j, ++sqp) 5453 - atomic_set(&sqp->blocked, (int)false); 5454 - } 5455 - 5456 - static void 5457 - sdeb_add_n_hosts(int num_hosts) 5458 - { 5459 - if (num_hosts < 1) 5460 - return; 5461 - do { 5462 - bool found; 5463 - unsigned long idx; 5464 - struct sdeb_store_info *sip; 5465 - bool want_phs = (sdebug_fake_rw == 0) && sdebug_per_host_store; 5466 - 5467 - found = false; 5468 - if (want_phs) { 5469 - xa_for_each_marked(per_store_ap, idx, sip, SDEB_XA_NOT_IN_USE) { 5470 - sdeb_most_recent_idx = (int)idx; 5471 - found = true; 5472 - break; 5473 - } 5474 - if (found) /* re-use case */ 5475 - sdebug_add_host_helper((int)idx); 5476 - else 5477 - sdebug_do_add_host(true /* make new store */); 5478 - } else { 5479 - sdebug_do_add_host(false); 5480 - } 5481 - } while (--num_hosts); 5458 + atomic_set(&sqp->blocked, (int)block); 5482 5459 } 5483 5460 5484 5461 /* Adjust (by rounding down) the sdebug_cmnd_count so abs(every_nth)-1 ··· 5454 5505 modulo = abs(sdebug_every_nth); 5455 5506 if (modulo < 2) 5456 5507 return; 5457 - sdeb_block_all_queues(); 5508 + block_unblock_all_queues(true); 5458 5509 count = atomic_read(&sdebug_cmnd_count); 5459 5510 atomic_set(&sdebug_cmnd_count, (count / modulo) * modulo); 5460 - sdeb_unblock_all_queues(); 5511 + block_unblock_all_queues(false); 5461 5512 } 5462 5513 5463 5514 static void clear_queue_stats(void) ··· 5475 5526 return (atomic_read(&sdebug_cmnd_count) % abs(sdebug_every_nth)) == 0; 5476 5527 } 5477 5528 5478 - static int process_deflect_incoming(struct scsi_cmnd *scp) 5479 - { 5480 - u8 opcode = scp->cmnd[0]; 5481 - 5482 - if (opcode == SYNCHRONIZE_CACHE || opcode == SYNCHRONIZE_CACHE_16) 5483 - return 0; 5484 - return DID_NO_CONNECT << 16; 5485 - } 5486 - 5487 5529 #define INCLUSIVE_TIMING_MAX_NS 1000000 /* 1 millisecond */ 5488 5530 5489 5531 /* Complete the processing of the thread that queued a SCSI command to this ··· 5484 5544 */ 5485 5545 static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, 5486 5546 int scsi_result, 5487 - int (*pfp)(struct scsi_cmnd *, struct sdebug_dev_info *), 5547 + int (*pfp)(struct scsi_cmnd *, 5548 + struct sdebug_dev_info *), 5488 5549 int delta_jiff, int ndelay) 5489 5550 { 5490 5551 bool new_sd_dp; ··· 5506 5565 } 5507 5566 sdp = cmnd->device; 5508 5567 5509 - if (delta_jiff == 0) { 5510 - sqp = get_queue(cmnd); 5511 - if (atomic_read(&sqp->blocked)) { 5512 - if (smp_load_acquire(&sdebug_deflect_incoming)) 5513 - return process_deflect_incoming(cmnd); 5514 - else 5515 - return SCSI_MLQUEUE_HOST_BUSY; 5516 - } 5568 + if (delta_jiff == 0) 5517 5569 goto respond_in_thread; 5518 - } 5519 5570 5520 5571 sqp = get_queue(cmnd); 5521 5572 spin_lock_irqsave(&sqp->qc_lock, iflags); 5522 5573 if (unlikely(atomic_read(&sqp->blocked))) { 5523 5574 spin_unlock_irqrestore(&sqp->qc_lock, iflags); 5524 - if (smp_load_acquire(&sdebug_deflect_incoming)) { 5525 - scsi_result = process_deflect_incoming(cmnd); 5526 - goto respond_in_thread; 5527 - } 5528 - if (sdebug_verbose) 5529 - pr_info("blocked --> SCSI_MLQUEUE_HOST_BUSY\n"); 5530 5575 return SCSI_MLQUEUE_HOST_BUSY; 5531 5576 } 5532 5577 num_in_q = atomic_read(&devip->num_in_q); ··· 5701 5774 respond_in_thread: /* call back to mid-layer using invocation thread */ 5702 5775 cmnd->result = pfp != NULL ? pfp(cmnd, devip) : 0; 5703 5776 cmnd->result &= ~SDEG_RES_IMMED_MASK; 5704 - if (cmnd->result == 0 && scsi_result != 0) { 5777 + if (cmnd->result == 0 && scsi_result != 0) 5705 5778 cmnd->result = scsi_result; 5706 - if (sdebug_verbose) 5707 - pr_info("respond_in_thread: tag=0x%x, scp->result=0x%x\n", 5708 - blk_mq_unique_tag(scsi_cmd_to_rq(cmnd)), scsi_result); 5709 - } 5710 5779 scsi_done(cmnd); 5711 5780 return 0; 5712 5781 } ··· 5987 6064 int j, k; 5988 6065 struct sdebug_queue *sqp; 5989 6066 5990 - sdeb_block_all_queues(); 6067 + block_unblock_all_queues(true); 5991 6068 for (j = 0, sqp = sdebug_q_arr; j < submit_queues; 5992 6069 ++j, ++sqp) { 5993 6070 k = find_first_bit(sqp->in_use_bm, ··· 6001 6078 sdebug_jdelay = jdelay; 6002 6079 sdebug_ndelay = 0; 6003 6080 } 6004 - sdeb_unblock_all_queues(); 6081 + block_unblock_all_queues(false); 6005 6082 } 6006 6083 return res; 6007 6084 } ··· 6027 6104 int j, k; 6028 6105 struct sdebug_queue *sqp; 6029 6106 6030 - sdeb_block_all_queues(); 6107 + block_unblock_all_queues(true); 6031 6108 for (j = 0, sqp = sdebug_q_arr; j < submit_queues; 6032 6109 ++j, ++sqp) { 6033 6110 k = find_first_bit(sqp->in_use_bm, ··· 6042 6119 sdebug_jdelay = ndelay ? JDELAY_OVERRIDDEN 6043 6120 : DEF_JDELAY; 6044 6121 } 6045 - sdeb_unblock_all_queues(); 6122 + block_unblock_all_queues(false); 6046 6123 } 6047 6124 return res; 6048 6125 } ··· 6356 6433 if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n > 0) && 6357 6434 (n <= SDEBUG_CANQUEUE) && 6358 6435 (sdebug_host_max_queue == 0)) { 6359 - sdeb_block_all_queues(); 6436 + block_unblock_all_queues(true); 6360 6437 k = 0; 6361 6438 for (j = 0, sqp = sdebug_q_arr; j < submit_queues; 6362 6439 ++j, ++sqp) { ··· 6371 6448 atomic_set(&retired_max_queue, k + 1); 6372 6449 else 6373 6450 atomic_set(&retired_max_queue, 0); 6374 - sdeb_unblock_all_queues(); 6451 + block_unblock_all_queues(false); 6375 6452 return count; 6376 6453 } 6377 6454 return -EINVAL; ··· 6460 6537 static ssize_t add_host_show(struct device_driver *ddp, char *buf) 6461 6538 { 6462 6539 /* absolute number of hosts currently active is what is shown */ 6463 - return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&sdebug_num_hosts)); 6540 + return scnprintf(buf, PAGE_SIZE, "%d\n", sdebug_num_hosts); 6464 6541 } 6465 6542 6466 - /* 6467 - * Accept positive and negative values. Hex values (only positive) may be prefixed by '0x'. 6468 - * To remove all hosts use a large negative number (e.g. -9999). The value 0 does nothing. 6469 - * Returns -EBUSY if another add_host sysfs invocation is active. 6470 - */ 6471 6543 static ssize_t add_host_store(struct device_driver *ddp, const char *buf, 6472 6544 size_t count) 6473 6545 { 6546 + bool found; 6547 + unsigned long idx; 6548 + struct sdeb_store_info *sip; 6549 + bool want_phs = (sdebug_fake_rw == 0) && sdebug_per_host_store; 6474 6550 int delta_hosts; 6475 6551 6476 - if (count == 0 || kstrtoint(buf, 0, &delta_hosts)) 6552 + if (sscanf(buf, "%d", &delta_hosts) != 1) 6477 6553 return -EINVAL; 6478 - if (sdebug_verbose) 6479 - pr_info("prior num_hosts=%d, num_to_add=%d\n", 6480 - atomic_read(&sdebug_num_hosts), delta_hosts); 6481 - if (delta_hosts == 0) 6482 - return count; 6483 - if (mutex_trylock(&add_host_mutex) == 0) 6484 - return -EBUSY; 6485 6554 if (delta_hosts > 0) { 6486 - sdeb_add_n_hosts(delta_hosts); 6487 - } else if (delta_hosts < 0) { 6488 - smp_store_release(&sdebug_deflect_incoming, true); 6489 - sdeb_block_all_queues(); 6490 - if (delta_hosts >= atomic_read(&sdebug_num_hosts)) 6491 - stop_all_queued(true); 6492 6555 do { 6493 - if (atomic_read(&sdebug_num_hosts) < 1) { 6494 - free_all_queued(); 6495 - break; 6556 + found = false; 6557 + if (want_phs) { 6558 + xa_for_each_marked(per_store_ap, idx, sip, 6559 + SDEB_XA_NOT_IN_USE) { 6560 + sdeb_most_recent_idx = (int)idx; 6561 + found = true; 6562 + break; 6563 + } 6564 + if (found) /* re-use case */ 6565 + sdebug_add_host_helper((int)idx); 6566 + else 6567 + sdebug_do_add_host(true); 6568 + } else { 6569 + sdebug_do_add_host(false); 6496 6570 } 6571 + } while (--delta_hosts); 6572 + } else if (delta_hosts < 0) { 6573 + do { 6497 6574 sdebug_do_remove_host(false); 6498 6575 } while (++delta_hosts); 6499 - sdeb_unblock_all_queues(); 6500 - smp_store_release(&sdebug_deflect_incoming, false); 6501 6576 } 6502 - mutex_unlock(&add_host_mutex); 6503 - if (sdebug_verbose) 6504 - pr_info("post num_hosts=%d\n", atomic_read(&sdebug_num_hosts)); 6505 6577 return count; 6506 6578 } 6507 6579 static DRIVER_ATTR_RW(add_host); ··· 7007 7089 sdebug_add_host = 0; 7008 7090 7009 7091 for (k = 0; k < hosts_to_add; k++) { 7010 - if (smp_load_acquire(&sdebug_deflect_incoming)) { 7011 - pr_info("exit early as sdebug_deflect_incoming is set\n"); 7012 - return 0; 7013 - } 7014 7092 if (want_store && k == 0) { 7015 7093 ret = sdebug_add_host_helper(idx); 7016 7094 if (ret < 0) { ··· 7024 7110 } 7025 7111 } 7026 7112 if (sdebug_verbose) 7027 - pr_info("built %d host(s)\n", atomic_read(&sdebug_num_hosts)); 7113 + pr_info("built %d host(s)\n", sdebug_num_hosts); 7028 7114 7029 - /* 7030 - * Even though all the hosts have been established, due to async device (LU) scanning 7031 - * by the scsi mid-level, there may still be devices (LUs) being set up. 7032 - */ 7033 7115 return 0; 7034 7116 7035 7117 bus_unreg: ··· 7041 7131 7042 7132 static void __exit scsi_debug_exit(void) 7043 7133 { 7044 - int k; 7134 + int k = sdebug_num_hosts; 7045 7135 7046 - /* Possible race with LUs still being set up; stop them asap */ 7047 - sdeb_block_all_queues(); 7048 - smp_store_release(&sdebug_deflect_incoming, true); 7049 - stop_all_queued(false); 7050 - for (k = 0; atomic_read(&sdebug_num_hosts) > 0; k++) 7136 + stop_all_queued(); 7137 + for (; k; k--) 7051 7138 sdebug_do_remove_host(true); 7052 7139 free_all_queued(); 7053 - if (sdebug_verbose) 7054 - pr_info("removed %d hosts\n", k); 7055 7140 driver_unregister(&sdebug_driverfs_driver); 7056 7141 bus_unregister(&pseudo_lld_bus); 7057 7142 root_device_unregister(pseudo_primary); ··· 7216 7311 sdbg_host->dev.bus = &pseudo_lld_bus; 7217 7312 sdbg_host->dev.parent = pseudo_primary; 7218 7313 sdbg_host->dev.release = &sdebug_release_adapter; 7219 - dev_set_name(&sdbg_host->dev, "adapter%d", atomic_read(&sdebug_num_hosts)); 7314 + dev_set_name(&sdbg_host->dev, "adapter%d", sdebug_num_hosts); 7220 7315 7221 7316 error = device_register(&sdbg_host->dev); 7222 7317 if (error) 7223 7318 goto clean; 7224 7319 7225 - atomic_inc(&sdebug_num_hosts); 7320 + ++sdebug_num_hosts; 7226 7321 return 0; 7227 7322 7228 7323 clean: ··· 7286 7381 return; 7287 7382 7288 7383 device_unregister(&sdbg_host->dev); 7289 - atomic_dec(&sdebug_num_hosts); 7384 + --sdebug_num_hosts; 7290 7385 } 7291 7386 7292 7387 static int sdebug_change_qdepth(struct scsi_device *sdev, int qdepth) ··· 7294 7389 int num_in_q = 0; 7295 7390 struct sdebug_dev_info *devip; 7296 7391 7297 - sdeb_block_all_queues(); 7392 + block_unblock_all_queues(true); 7298 7393 devip = (struct sdebug_dev_info *)sdev->hostdata; 7299 7394 if (NULL == devip) { 7300 - sdeb_unblock_all_queues(); 7395 + block_unblock_all_queues(false); 7301 7396 return -ENODEV; 7302 7397 } 7303 7398 num_in_q = atomic_read(&devip->num_in_q); ··· 7316 7411 sdev_printk(KERN_INFO, sdev, "%s: qdepth=%d, num_in_q=%d\n", 7317 7412 __func__, qdepth, num_in_q); 7318 7413 } 7319 - sdeb_unblock_all_queues(); 7414 + block_unblock_all_queues(false); 7320 7415 return sdev->queue_depth; 7321 7416 } 7322 7417
+140 -99
drivers/scsi/scsi_transport_iscsi.c
··· 86 86 struct transport_container session_cont; 87 87 }; 88 88 89 + static DEFINE_IDR(iscsi_ep_idr); 90 + static DEFINE_MUTEX(iscsi_ep_idr_mutex); 91 + 89 92 static atomic_t iscsi_session_nr; /* sysfs session id for next new session */ 90 93 91 94 static struct workqueue_struct *iscsi_conn_cleanup_workq; ··· 171 168 static void iscsi_endpoint_release(struct device *dev) 172 169 { 173 170 struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); 171 + 172 + mutex_lock(&iscsi_ep_idr_mutex); 173 + idr_remove(&iscsi_ep_idr, ep->id); 174 + mutex_unlock(&iscsi_ep_idr_mutex); 175 + 174 176 kfree(ep); 175 177 } 176 178 ··· 188 180 show_ep_handle(struct device *dev, struct device_attribute *attr, char *buf) 189 181 { 190 182 struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); 191 - return sysfs_emit(buf, "%llu\n", (unsigned long long) ep->id); 183 + return sysfs_emit(buf, "%d\n", ep->id); 192 184 } 193 185 static ISCSI_ATTR(ep, handle, S_IRUGO, show_ep_handle, NULL); 194 186 ··· 201 193 .attrs = iscsi_endpoint_attrs, 202 194 }; 203 195 204 - #define ISCSI_MAX_EPID -1 205 - 206 - static int iscsi_match_epid(struct device *dev, const void *data) 207 - { 208 - struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); 209 - const uint64_t *epid = data; 210 - 211 - return *epid == ep->id; 212 - } 213 - 214 196 struct iscsi_endpoint * 215 197 iscsi_create_endpoint(int dd_size) 216 198 { 217 - struct device *dev; 218 199 struct iscsi_endpoint *ep; 219 - uint64_t id; 220 - int err; 221 - 222 - for (id = 1; id < ISCSI_MAX_EPID; id++) { 223 - dev = class_find_device(&iscsi_endpoint_class, NULL, &id, 224 - iscsi_match_epid); 225 - if (!dev) 226 - break; 227 - else 228 - put_device(dev); 229 - } 230 - if (id == ISCSI_MAX_EPID) { 231 - printk(KERN_ERR "Too many connections. Max supported %u\n", 232 - ISCSI_MAX_EPID - 1); 233 - return NULL; 234 - } 200 + int err, id; 235 201 236 202 ep = kzalloc(sizeof(*ep) + dd_size, GFP_KERNEL); 237 203 if (!ep) 238 204 return NULL; 239 205 206 + mutex_lock(&iscsi_ep_idr_mutex); 207 + id = idr_alloc(&iscsi_ep_idr, ep, 0, -1, GFP_NOIO); 208 + if (id < 0) { 209 + mutex_unlock(&iscsi_ep_idr_mutex); 210 + printk(KERN_ERR "Could not allocate endpoint ID. Error %d.\n", 211 + id); 212 + goto free_ep; 213 + } 214 + mutex_unlock(&iscsi_ep_idr_mutex); 215 + 240 216 ep->id = id; 241 217 ep->dev.class = &iscsi_endpoint_class; 242 - dev_set_name(&ep->dev, "ep-%llu", (unsigned long long) id); 218 + dev_set_name(&ep->dev, "ep-%d", id); 243 219 err = device_register(&ep->dev); 244 220 if (err) 245 - goto free_ep; 221 + goto free_id; 246 222 247 223 err = sysfs_create_group(&ep->dev.kobj, &iscsi_endpoint_group); 248 224 if (err) ··· 240 248 device_unregister(&ep->dev); 241 249 return NULL; 242 250 251 + free_id: 252 + mutex_lock(&iscsi_ep_idr_mutex); 253 + idr_remove(&iscsi_ep_idr, id); 254 + mutex_unlock(&iscsi_ep_idr_mutex); 243 255 free_ep: 244 256 kfree(ep); 245 257 return NULL; ··· 271 275 */ 272 276 struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle) 273 277 { 274 - struct device *dev; 278 + struct iscsi_endpoint *ep; 275 279 276 - dev = class_find_device(&iscsi_endpoint_class, NULL, &handle, 277 - iscsi_match_epid); 278 - if (!dev) 279 - return NULL; 280 + mutex_lock(&iscsi_ep_idr_mutex); 281 + ep = idr_find(&iscsi_ep_idr, handle); 282 + if (!ep) 283 + goto unlock; 280 284 281 - return iscsi_dev_to_endpoint(dev); 285 + get_device(&ep->dev); 286 + unlock: 287 + mutex_unlock(&iscsi_ep_idr_mutex); 288 + return ep; 282 289 } 283 290 EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint); 284 291 ··· 2201 2202 2202 2203 switch (flag) { 2203 2204 case STOP_CONN_RECOVER: 2204 - conn->state = ISCSI_CONN_FAILED; 2205 + WRITE_ONCE(conn->state, ISCSI_CONN_FAILED); 2205 2206 break; 2206 2207 case STOP_CONN_TERM: 2207 - conn->state = ISCSI_CONN_DOWN; 2208 + WRITE_ONCE(conn->state, ISCSI_CONN_DOWN); 2208 2209 break; 2209 2210 default: 2210 2211 iscsi_cls_conn_printk(KERN_ERR, conn, "invalid stop flag %d\n", ··· 2214 2215 2215 2216 conn->transport->stop_conn(conn, flag); 2216 2217 ISCSI_DBG_TRANS_CONN(conn, "Stopping conn done.\n"); 2218 + } 2219 + 2220 + static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active) 2221 + { 2222 + struct iscsi_cls_session *session = iscsi_conn_to_session(conn); 2223 + struct iscsi_endpoint *ep; 2224 + 2225 + ISCSI_DBG_TRANS_CONN(conn, "disconnect ep.\n"); 2226 + WRITE_ONCE(conn->state, ISCSI_CONN_FAILED); 2227 + 2228 + if (!conn->ep || !session->transport->ep_disconnect) 2229 + return; 2230 + 2231 + ep = conn->ep; 2232 + conn->ep = NULL; 2233 + 2234 + session->transport->unbind_conn(conn, is_active); 2235 + session->transport->ep_disconnect(ep); 2236 + ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n"); 2237 + } 2238 + 2239 + static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn, 2240 + struct iscsi_endpoint *ep, 2241 + bool is_active) 2242 + { 2243 + /* Check if this was a conn error and the kernel took ownership */ 2244 + spin_lock_irq(&conn->lock); 2245 + if (!test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) { 2246 + spin_unlock_irq(&conn->lock); 2247 + iscsi_ep_disconnect(conn, is_active); 2248 + } else { 2249 + spin_unlock_irq(&conn->lock); 2250 + ISCSI_DBG_TRANS_CONN(conn, "flush kernel conn cleanup.\n"); 2251 + mutex_unlock(&conn->ep_mutex); 2252 + 2253 + flush_work(&conn->cleanup_work); 2254 + /* 2255 + * Userspace is now done with the EP so we can release the ref 2256 + * iscsi_cleanup_conn_work_fn took. 2257 + */ 2258 + iscsi_put_endpoint(ep); 2259 + mutex_lock(&conn->ep_mutex); 2260 + } 2217 2261 } 2218 2262 2219 2263 static int iscsi_if_stop_conn(struct iscsi_transport *transport, ··· 2280 2238 iscsi_stop_conn(conn, flag); 2281 2239 } else { 2282 2240 /* 2241 + * For offload, when iscsid is restarted it won't know about 2242 + * existing endpoints so it can't do a ep_disconnect. We clean 2243 + * it up here for userspace. 2244 + */ 2245 + mutex_lock(&conn->ep_mutex); 2246 + if (conn->ep) 2247 + iscsi_if_disconnect_bound_ep(conn, conn->ep, true); 2248 + mutex_unlock(&conn->ep_mutex); 2249 + 2250 + /* 2283 2251 * Figure out if it was the kernel or userspace initiating this. 2284 2252 */ 2253 + spin_lock_irq(&conn->lock); 2285 2254 if (!test_and_set_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) { 2255 + spin_unlock_irq(&conn->lock); 2286 2256 iscsi_stop_conn(conn, flag); 2287 2257 } else { 2258 + spin_unlock_irq(&conn->lock); 2288 2259 ISCSI_DBG_TRANS_CONN(conn, 2289 2260 "flush kernel conn cleanup.\n"); 2290 2261 flush_work(&conn->cleanup_work); ··· 2306 2251 * Only clear for recovery to avoid extra cleanup runs during 2307 2252 * termination. 2308 2253 */ 2254 + spin_lock_irq(&conn->lock); 2309 2255 clear_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags); 2256 + spin_unlock_irq(&conn->lock); 2310 2257 } 2311 2258 ISCSI_DBG_TRANS_CONN(conn, "iscsi if conn stop done.\n"); 2312 2259 return 0; 2313 - } 2314 - 2315 - static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active) 2316 - { 2317 - struct iscsi_cls_session *session = iscsi_conn_to_session(conn); 2318 - struct iscsi_endpoint *ep; 2319 - 2320 - ISCSI_DBG_TRANS_CONN(conn, "disconnect ep.\n"); 2321 - conn->state = ISCSI_CONN_FAILED; 2322 - 2323 - if (!conn->ep || !session->transport->ep_disconnect) 2324 - return; 2325 - 2326 - ep = conn->ep; 2327 - conn->ep = NULL; 2328 - 2329 - session->transport->unbind_conn(conn, is_active); 2330 - session->transport->ep_disconnect(ep); 2331 - ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n"); 2332 2260 } 2333 2261 2334 2262 static void iscsi_cleanup_conn_work_fn(struct work_struct *work) ··· 2322 2284 2323 2285 mutex_lock(&conn->ep_mutex); 2324 2286 /* 2325 - * If we are not at least bound there is nothing for us to do. Userspace 2326 - * will do a ep_disconnect call if offload is used, but will not be 2327 - * doing a stop since there is nothing to clean up, so we have to clear 2328 - * the cleanup bit here. 2287 + * Get a ref to the ep, so we don't release its ID until after 2288 + * userspace is done referencing it in iscsi_if_disconnect_bound_ep. 2329 2289 */ 2330 - if (conn->state != ISCSI_CONN_BOUND && conn->state != ISCSI_CONN_UP) { 2331 - ISCSI_DBG_TRANS_CONN(conn, "Got error while conn is already failed. Ignoring.\n"); 2332 - clear_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags); 2333 - mutex_unlock(&conn->ep_mutex); 2334 - return; 2335 - } 2336 - 2290 + if (conn->ep) 2291 + get_device(&conn->ep->dev); 2337 2292 iscsi_ep_disconnect(conn, false); 2338 2293 2339 2294 if (system_state != SYSTEM_RUNNING) { ··· 2371 2340 conn->dd_data = &conn[1]; 2372 2341 2373 2342 mutex_init(&conn->ep_mutex); 2343 + spin_lock_init(&conn->lock); 2374 2344 INIT_LIST_HEAD(&conn->conn_list); 2375 2345 INIT_WORK(&conn->cleanup_work, iscsi_cleanup_conn_work_fn); 2376 2346 conn->transport = transport; 2377 2347 conn->cid = cid; 2378 - conn->state = ISCSI_CONN_DOWN; 2348 + WRITE_ONCE(conn->state, ISCSI_CONN_DOWN); 2379 2349 2380 2350 /* this is released in the dev's release function */ 2381 2351 if (!get_device(&session->dev)) ··· 2574 2542 struct iscsi_uevent *ev; 2575 2543 struct iscsi_internal *priv; 2576 2544 int len = nlmsg_total_size(sizeof(*ev)); 2545 + unsigned long flags; 2546 + int state; 2577 2547 2578 - if (!test_and_set_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) 2579 - queue_work(iscsi_conn_cleanup_workq, &conn->cleanup_work); 2548 + spin_lock_irqsave(&conn->lock, flags); 2549 + /* 2550 + * Userspace will only do a stop call if we are at least bound. And, we 2551 + * only need to do the in kernel cleanup if in the UP state so cmds can 2552 + * be released to upper layers. If in other states just wait for 2553 + * userspace to avoid races that can leave the cleanup_work queued. 2554 + */ 2555 + state = READ_ONCE(conn->state); 2556 + switch (state) { 2557 + case ISCSI_CONN_BOUND: 2558 + case ISCSI_CONN_UP: 2559 + if (!test_and_set_bit(ISCSI_CLS_CONN_BIT_CLEANUP, 2560 + &conn->flags)) { 2561 + queue_work(iscsi_conn_cleanup_workq, 2562 + &conn->cleanup_work); 2563 + } 2564 + break; 2565 + default: 2566 + ISCSI_DBG_TRANS_CONN(conn, "Got conn error in state %d\n", 2567 + state); 2568 + break; 2569 + } 2570 + spin_unlock_irqrestore(&conn->lock, flags); 2580 2571 2581 2572 priv = iscsi_if_transport_lookup(conn->transport); 2582 2573 if (!priv) ··· 2949 2894 char *data = (char*)ev + sizeof(*ev); 2950 2895 struct iscsi_cls_conn *conn; 2951 2896 struct iscsi_cls_session *session; 2952 - int err = 0, value = 0; 2897 + int err = 0, value = 0, state; 2953 2898 2954 2899 if (ev->u.set_param.len > PAGE_SIZE) 2955 2900 return -EINVAL; ··· 2966 2911 session->recovery_tmo = value; 2967 2912 break; 2968 2913 default: 2969 - if ((conn->state == ISCSI_CONN_BOUND) || 2970 - (conn->state == ISCSI_CONN_UP)) { 2914 + state = READ_ONCE(conn->state); 2915 + if (state == ISCSI_CONN_BOUND || state == ISCSI_CONN_UP) { 2971 2916 err = transport->set_param(conn, ev->u.set_param.param, 2972 2917 data, ev->u.set_param.len); 2973 2918 } else { ··· 3039 2984 } 3040 2985 3041 2986 mutex_lock(&conn->ep_mutex); 3042 - /* Check if this was a conn error and the kernel took ownership */ 3043 - if (test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) { 3044 - ISCSI_DBG_TRANS_CONN(conn, "flush kernel conn cleanup.\n"); 3045 - mutex_unlock(&conn->ep_mutex); 3046 - 3047 - flush_work(&conn->cleanup_work); 3048 - goto put_ep; 3049 - } 3050 - 3051 - iscsi_ep_disconnect(conn, false); 2987 + iscsi_if_disconnect_bound_ep(conn, ep, false); 3052 2988 mutex_unlock(&conn->ep_mutex); 3053 2989 put_ep: 3054 2990 iscsi_put_endpoint(ep); ··· 3742 3696 return -EINVAL; 3743 3697 3744 3698 mutex_lock(&conn->ep_mutex); 3699 + spin_lock_irq(&conn->lock); 3745 3700 if (test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) { 3701 + spin_unlock_irq(&conn->lock); 3746 3702 mutex_unlock(&conn->ep_mutex); 3747 3703 ev->r.retcode = -ENOTCONN; 3748 3704 return 0; 3749 3705 } 3706 + spin_unlock_irq(&conn->lock); 3750 3707 3751 3708 switch (nlh->nlmsg_type) { 3752 3709 case ISCSI_UEVENT_BIND_CONN: 3753 - if (conn->ep) { 3754 - /* 3755 - * For offload boot support where iscsid is restarted 3756 - * during the pivot root stage, the ep will be intact 3757 - * here when the new iscsid instance starts up and 3758 - * reconnects. 3759 - */ 3760 - iscsi_ep_disconnect(conn, true); 3761 - } 3762 - 3763 3710 session = iscsi_session_lookup(ev->u.b_conn.sid); 3764 3711 if (!session) { 3765 3712 err = -EINVAL; ··· 3763 3724 ev->u.b_conn.transport_eph, 3764 3725 ev->u.b_conn.is_leading); 3765 3726 if (!ev->r.retcode) 3766 - conn->state = ISCSI_CONN_BOUND; 3727 + WRITE_ONCE(conn->state, ISCSI_CONN_BOUND); 3767 3728 3768 3729 if (ev->r.retcode || !transport->ep_connect) 3769 3730 break; ··· 3782 3743 case ISCSI_UEVENT_START_CONN: 3783 3744 ev->r.retcode = transport->start_conn(conn); 3784 3745 if (!ev->r.retcode) 3785 - conn->state = ISCSI_CONN_UP; 3746 + WRITE_ONCE(conn->state, ISCSI_CONN_UP); 3747 + 3786 3748 break; 3787 3749 case ISCSI_UEVENT_SEND_PDU: 3788 3750 pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev); ··· 4090 4050 { 4091 4051 struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev->parent); 4092 4052 const char *state = "unknown"; 4053 + int conn_state = READ_ONCE(conn->state); 4093 4054 4094 - if (conn->state >= 0 && 4095 - conn->state < ARRAY_SIZE(connection_state_names)) 4096 - state = connection_state_names[conn->state]; 4055 + if (conn_state >= 0 && 4056 + conn_state < ARRAY_SIZE(connection_state_names)) 4057 + state = connection_state_names[conn_state]; 4097 4058 4098 4059 return sysfs_emit(buf, "%s\n", state); 4099 4060 }
+5 -4
include/scsi/libiscsi.h
··· 53 53 54 54 #define ISID_SIZE 6 55 55 56 - /* Connection suspend "bit" */ 57 - #define ISCSI_SUSPEND_BIT 1 56 + /* Connection flags */ 57 + #define ISCSI_CONN_FLAG_SUSPEND_TX BIT(0) 58 + #define ISCSI_CONN_FLAG_SUSPEND_RX BIT(1) 59 + #define ISCSI_CONN_FLAG_BOUND BIT(2) 58 60 59 61 #define ISCSI_ITT_MASK 0x1fff 60 62 #define ISCSI_TOTAL_CMDS_MAX 4096 ··· 213 211 struct list_head cmdqueue; /* data-path cmd queue */ 214 212 struct list_head requeue; /* tasks needing another run */ 215 213 struct work_struct xmitwork; /* per-conn. xmit workqueue */ 216 - unsigned long suspend_tx; /* suspend Tx */ 217 - unsigned long suspend_rx; /* suspend Rx */ 214 + unsigned long flags; /* ISCSI_CONN_FLAGs */ 218 215 219 216 /* negotiated params */ 220 217 unsigned max_recv_dlength; /* initiator_max_recv_dsl*/
+3 -1
include/scsi/scsi_transport_iscsi.h
··· 211 211 struct mutex ep_mutex; 212 212 struct iscsi_endpoint *ep; 213 213 214 + /* Used when accessing flags and queueing work. */ 215 + spinlock_t lock; 214 216 unsigned long flags; 215 217 struct work_struct cleanup_work; 216 218 ··· 297 295 struct iscsi_endpoint { 298 296 void *dd_data; /* LLD private data */ 299 297 struct device dev; 300 - uint64_t id; 298 + int id; 301 299 struct iscsi_cls_conn *conn; 302 300 }; 303 301