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:
"Five fixes, all in drivers.

The most extensive is the target change to fix the hang in the login
code, which involves changing timers from per login to per connection"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
scsi: stex: Fix gcc 13 warnings
scsi: qla2xxx: Fix NULL pointer dereference in target mode
scsi: target: iscsi: Prevent login threads from racing between each other
scsi: target: iscsi: Remove unused transport_timer
scsi: target: iscsi: Fix hang in the iSCSI login code

+120 -95
+1
drivers/scsi/qla2xxx/qla_def.h
··· 3796 3796 uint64_t retry_term_jiff; 3797 3797 struct qla_tgt_counters tgt_counters; 3798 3798 uint16_t cpuid; 3799 + bool cpu_mapped; 3799 3800 struct qla_fw_resources fwres ____cacheline_aligned; 3800 3801 struct qla_buf_pool buf_pool; 3801 3802 u32 cmd_cnt;
+3
drivers/scsi/qla2xxx/qla_init.c
··· 9426 9426 qpair->rsp->req = qpair->req; 9427 9427 qpair->rsp->qpair = qpair; 9428 9428 9429 + if (!qpair->cpu_mapped) 9430 + qla_cpu_update(qpair, raw_smp_processor_id()); 9431 + 9429 9432 if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { 9430 9433 if (ha->fw_attributes & BIT_4) 9431 9434 qpair->difdix_supported = 1;
+3
drivers/scsi/qla2xxx/qla_inline.h
··· 539 539 if (!ha->qp_cpu_map) 540 540 return; 541 541 mask = pci_irq_get_affinity(ha->pdev, msix->vector_base0); 542 + if (!mask) 543 + return; 542 544 qpair->cpuid = cpumask_first(mask); 543 545 for_each_cpu(cpu, mask) { 544 546 ha->qp_cpu_map[cpu] = qpair; 545 547 } 546 548 msix->cpuid = qpair->cpuid; 549 + qpair->cpu_mapped = true; 547 550 } 548 551 549 552 static inline void
+3
drivers/scsi/qla2xxx/qla_isr.c
··· 3770 3770 3771 3771 if (rsp->qpair->cpuid != smp_processor_id() || !rsp->qpair->rcv_intr) { 3772 3772 rsp->qpair->rcv_intr = 1; 3773 + 3774 + if (!rsp->qpair->cpu_mapped) 3775 + qla_cpu_update(rsp->qpair, raw_smp_processor_id()); 3773 3776 } 3774 3777 3775 3778 #define __update_rsp_in(_is_shadow_hba, _rsp, _rsp_in) \
+4
drivers/scsi/stex.c
··· 109 109 TASK_ATTRIBUTE_HEADOFQUEUE = 0x1, 110 110 TASK_ATTRIBUTE_ORDERED = 0x2, 111 111 TASK_ATTRIBUTE_ACA = 0x4, 112 + }; 112 113 114 + enum { 113 115 SS_STS_NORMAL = 0x80000000, 114 116 SS_STS_DONE = 0x40000000, 115 117 SS_STS_HANDSHAKE = 0x20000000, ··· 123 121 SS_I2H_REQUEST_RESET = 0x2000, 124 122 125 123 SS_MU_OPERATIONAL = 0x80000000, 124 + }; 126 125 126 + enum { 127 127 STEX_CDB_LENGTH = 16, 128 128 STATUS_VAR_LEN = 128, 129 129
-2
drivers/target/iscsi/iscsi_target.c
··· 364 364 init_completion(&np->np_restart_comp); 365 365 INIT_LIST_HEAD(&np->np_list); 366 366 367 - timer_setup(&np->np_login_timer, iscsi_handle_login_thread_timeout, 0); 368 - 369 367 ret = iscsi_target_setup_login_socket(np, sockaddr); 370 368 if (ret != 0) { 371 369 kfree(np);
+5 -58
drivers/target/iscsi/iscsi_target_login.c
··· 811 811 iscsit_dec_conn_usage_count(conn); 812 812 } 813 813 814 - void iscsi_handle_login_thread_timeout(struct timer_list *t) 815 - { 816 - struct iscsi_np *np = from_timer(np, t, np_login_timer); 817 - 818 - spin_lock_bh(&np->np_thread_lock); 819 - pr_err("iSCSI Login timeout on Network Portal %pISpc\n", 820 - &np->np_sockaddr); 821 - 822 - if (np->np_login_timer_flags & ISCSI_TF_STOP) { 823 - spin_unlock_bh(&np->np_thread_lock); 824 - return; 825 - } 826 - 827 - if (np->np_thread) 828 - send_sig(SIGINT, np->np_thread, 1); 829 - 830 - np->np_login_timer_flags &= ~ISCSI_TF_RUNNING; 831 - spin_unlock_bh(&np->np_thread_lock); 832 - } 833 - 834 - static void iscsi_start_login_thread_timer(struct iscsi_np *np) 835 - { 836 - /* 837 - * This used the TA_LOGIN_TIMEOUT constant because at this 838 - * point we do not have access to ISCSI_TPG_ATTRIB(tpg)->login_timeout 839 - */ 840 - spin_lock_bh(&np->np_thread_lock); 841 - np->np_login_timer_flags &= ~ISCSI_TF_STOP; 842 - np->np_login_timer_flags |= ISCSI_TF_RUNNING; 843 - mod_timer(&np->np_login_timer, jiffies + TA_LOGIN_TIMEOUT * HZ); 844 - 845 - pr_debug("Added timeout timer to iSCSI login request for" 846 - " %u seconds.\n", TA_LOGIN_TIMEOUT); 847 - spin_unlock_bh(&np->np_thread_lock); 848 - } 849 - 850 - static void iscsi_stop_login_thread_timer(struct iscsi_np *np) 851 - { 852 - spin_lock_bh(&np->np_thread_lock); 853 - if (!(np->np_login_timer_flags & ISCSI_TF_RUNNING)) { 854 - spin_unlock_bh(&np->np_thread_lock); 855 - return; 856 - } 857 - np->np_login_timer_flags |= ISCSI_TF_STOP; 858 - spin_unlock_bh(&np->np_thread_lock); 859 - 860 - del_timer_sync(&np->np_login_timer); 861 - 862 - spin_lock_bh(&np->np_thread_lock); 863 - np->np_login_timer_flags &= ~ISCSI_TF_RUNNING; 864 - spin_unlock_bh(&np->np_thread_lock); 865 - } 866 - 867 814 int iscsit_setup_np( 868 815 struct iscsi_np *np, 869 816 struct sockaddr_storage *sockaddr) ··· 1070 1123 spin_lock_init(&conn->nopin_timer_lock); 1071 1124 spin_lock_init(&conn->response_queue_lock); 1072 1125 spin_lock_init(&conn->state_lock); 1126 + spin_lock_init(&conn->login_worker_lock); 1127 + spin_lock_init(&conn->login_timer_lock); 1073 1128 1074 1129 timer_setup(&conn->nopin_response_timer, 1075 1130 iscsit_handle_nopin_response_timeout, 0); 1076 1131 timer_setup(&conn->nopin_timer, iscsit_handle_nopin_timeout, 0); 1132 + timer_setup(&conn->login_timer, iscsit_login_timeout, 0); 1077 1133 1078 1134 if (iscsit_conn_set_transport(conn, np->np_transport) < 0) 1079 1135 goto free_conn; ··· 1254 1304 goto new_sess_out; 1255 1305 } 1256 1306 1257 - iscsi_start_login_thread_timer(np); 1307 + iscsit_start_login_timer(conn, current); 1258 1308 1259 1309 pr_debug("Moving to TARG_CONN_STATE_XPT_UP.\n"); 1260 1310 conn->conn_state = TARG_CONN_STATE_XPT_UP; ··· 1367 1417 if (ret < 0) 1368 1418 goto new_sess_out; 1369 1419 1370 - iscsi_stop_login_thread_timer(np); 1371 - 1372 1420 if (ret == 1) { 1373 1421 tpg_np = conn->tpg_np; 1374 1422 ··· 1382 1434 new_sess_out: 1383 1435 new_sess = true; 1384 1436 old_sess_out: 1385 - iscsi_stop_login_thread_timer(np); 1437 + iscsit_stop_login_timer(conn); 1386 1438 tpg_np = conn->tpg_np; 1387 1439 iscsi_target_login_sess_out(conn, zero_tsih, new_sess); 1388 1440 new_sess = false; ··· 1396 1448 return 1; 1397 1449 1398 1450 exit: 1399 - iscsi_stop_login_thread_timer(np); 1400 1451 spin_lock_bh(&np->np_thread_lock); 1401 1452 np->np_thread_state = ISCSI_NP_THREAD_EXIT; 1402 1453 spin_unlock_bh(&np->np_thread_lock);
+42 -32
drivers/target/iscsi/iscsi_target_nego.c
··· 535 535 iscsi_target_login_sess_out(conn, zero_tsih, true); 536 536 } 537 537 538 - struct conn_timeout { 539 - struct timer_list timer; 540 - struct iscsit_conn *conn; 541 - }; 542 - 543 - static void iscsi_target_login_timeout(struct timer_list *t) 544 - { 545 - struct conn_timeout *timeout = from_timer(timeout, t, timer); 546 - struct iscsit_conn *conn = timeout->conn; 547 - 548 - pr_debug("Entering iscsi_target_login_timeout >>>>>>>>>>>>>>>>>>>\n"); 549 - 550 - if (conn->login_kworker) { 551 - pr_debug("Sending SIGINT to conn->login_kworker %s/%d\n", 552 - conn->login_kworker->comm, conn->login_kworker->pid); 553 - send_sig(SIGINT, conn->login_kworker, 1); 554 - } 555 - } 556 - 557 538 static void iscsi_target_do_login_rx(struct work_struct *work) 558 539 { 559 540 struct iscsit_conn *conn = container_of(work, ··· 543 562 struct iscsi_np *np = login->np; 544 563 struct iscsi_portal_group *tpg = conn->tpg; 545 564 struct iscsi_tpg_np *tpg_np = conn->tpg_np; 546 - struct conn_timeout timeout; 547 565 int rc, zero_tsih = login->zero_tsih; 548 566 bool state; 549 567 550 568 pr_debug("entering iscsi_target_do_login_rx, conn: %p, %s:%d\n", 551 569 conn, current->comm, current->pid); 570 + 571 + spin_lock(&conn->login_worker_lock); 572 + set_bit(LOGIN_FLAGS_WORKER_RUNNING, &conn->login_flags); 573 + spin_unlock(&conn->login_worker_lock); 552 574 /* 553 575 * If iscsi_target_do_login_rx() has been invoked by ->sk_data_ready() 554 576 * before initial PDU processing in iscsi_target_start_negotiation() ··· 581 597 goto err; 582 598 } 583 599 584 - conn->login_kworker = current; 585 600 allow_signal(SIGINT); 586 - 587 - timeout.conn = conn; 588 - timer_setup_on_stack(&timeout.timer, iscsi_target_login_timeout, 0); 589 - mod_timer(&timeout.timer, jiffies + TA_LOGIN_TIMEOUT * HZ); 590 - pr_debug("Starting login timer for %s/%d\n", current->comm, current->pid); 601 + rc = iscsit_set_login_timer_kworker(conn, current); 602 + if (rc < 0) { 603 + /* The login timer has already expired */ 604 + pr_debug("iscsi_target_do_login_rx, login failed\n"); 605 + goto err; 606 + } 591 607 592 608 rc = conn->conn_transport->iscsit_get_login_rx(conn, login); 593 - del_timer_sync(&timeout.timer); 594 - destroy_timer_on_stack(&timeout.timer); 595 609 flush_signals(current); 596 - conn->login_kworker = NULL; 597 610 598 611 if (rc < 0) 599 612 goto err; ··· 627 646 if (iscsi_target_sk_check_and_clear(conn, 628 647 LOGIN_FLAGS_WRITE_ACTIVE)) 629 648 goto err; 649 + 650 + /* 651 + * Set the login timer thread pointer to NULL to prevent the 652 + * login process from getting stuck if the initiator 653 + * stops sending data. 654 + */ 655 + rc = iscsit_set_login_timer_kworker(conn, NULL); 656 + if (rc < 0) 657 + goto err; 630 658 } else if (rc == 1) { 659 + iscsit_stop_login_timer(conn); 631 660 cancel_delayed_work(&conn->login_work); 632 661 iscsi_target_nego_release(conn); 633 662 iscsi_post_login_handler(np, conn, zero_tsih); ··· 647 656 648 657 err: 649 658 iscsi_target_restore_sock_callbacks(conn); 659 + iscsit_stop_login_timer(conn); 650 660 cancel_delayed_work(&conn->login_work); 651 661 iscsi_target_login_drop(conn, login); 652 662 iscsit_deaccess_np(np, tpg, tpg_np); ··· 1122 1130 iscsi_target_set_sock_callbacks(conn); 1123 1131 1124 1132 login->np = np; 1133 + conn->tpg = NULL; 1125 1134 1126 1135 login_req = (struct iscsi_login_req *) login->req; 1127 1136 payload_length = ntoh24(login_req->dlength); ··· 1190 1197 */ 1191 1198 sessiontype = strncmp(s_buf, DISCOVERY, 9); 1192 1199 if (!sessiontype) { 1193 - conn->tpg = iscsit_global->discovery_tpg; 1194 1200 if (!login->leading_connection) 1195 1201 goto get_target; 1196 1202 ··· 1206 1214 * Serialize access across the discovery struct iscsi_portal_group to 1207 1215 * process login attempt. 1208 1216 */ 1217 + conn->tpg = iscsit_global->discovery_tpg; 1209 1218 if (iscsit_access_np(np, conn->tpg) < 0) { 1210 1219 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 1211 1220 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE); 1221 + conn->tpg = NULL; 1212 1222 ret = -1; 1213 1223 goto out; 1214 1224 } ··· 1362 1368 * and perform connection cleanup now. 1363 1369 */ 1364 1370 ret = iscsi_target_do_login(conn, login); 1365 - if (!ret && iscsi_target_sk_check_and_clear(conn, LOGIN_FLAGS_INITIAL_PDU)) 1366 - ret = -1; 1371 + if (!ret) { 1372 + spin_lock(&conn->login_worker_lock); 1373 + 1374 + if (iscsi_target_sk_check_and_clear(conn, LOGIN_FLAGS_INITIAL_PDU)) 1375 + ret = -1; 1376 + else if (!test_bit(LOGIN_FLAGS_WORKER_RUNNING, &conn->login_flags)) { 1377 + if (iscsit_set_login_timer_kworker(conn, NULL) < 0) { 1378 + /* 1379 + * The timeout has expired already. 1380 + * Schedule login_work to perform the cleanup. 1381 + */ 1382 + schedule_delayed_work(&conn->login_work, 0); 1383 + } 1384 + } 1385 + 1386 + spin_unlock(&conn->login_worker_lock); 1387 + } 1367 1388 1368 1389 if (ret < 0) { 1369 1390 iscsi_target_restore_sock_callbacks(conn); 1370 1391 iscsi_remove_failed_auth_entry(conn); 1371 1392 } 1372 1393 if (ret != 0) { 1394 + iscsit_stop_login_timer(conn); 1373 1395 cancel_delayed_work_sync(&conn->login_work); 1374 1396 iscsi_target_nego_release(conn); 1375 1397 }
+51
drivers/target/iscsi/iscsi_target_util.c
··· 1040 1040 spin_unlock_bh(&conn->nopin_timer_lock); 1041 1041 } 1042 1042 1043 + void iscsit_login_timeout(struct timer_list *t) 1044 + { 1045 + struct iscsit_conn *conn = from_timer(conn, t, login_timer); 1046 + struct iscsi_login *login = conn->login; 1047 + 1048 + pr_debug("Entering iscsi_target_login_timeout >>>>>>>>>>>>>>>>>>>\n"); 1049 + 1050 + spin_lock_bh(&conn->login_timer_lock); 1051 + login->login_failed = 1; 1052 + 1053 + if (conn->login_kworker) { 1054 + pr_debug("Sending SIGINT to conn->login_kworker %s/%d\n", 1055 + conn->login_kworker->comm, conn->login_kworker->pid); 1056 + send_sig(SIGINT, conn->login_kworker, 1); 1057 + } else { 1058 + schedule_delayed_work(&conn->login_work, 0); 1059 + } 1060 + spin_unlock_bh(&conn->login_timer_lock); 1061 + } 1062 + 1063 + void iscsit_start_login_timer(struct iscsit_conn *conn, struct task_struct *kthr) 1064 + { 1065 + pr_debug("Login timer started\n"); 1066 + 1067 + conn->login_kworker = kthr; 1068 + mod_timer(&conn->login_timer, jiffies + TA_LOGIN_TIMEOUT * HZ); 1069 + } 1070 + 1071 + int iscsit_set_login_timer_kworker(struct iscsit_conn *conn, struct task_struct *kthr) 1072 + { 1073 + struct iscsi_login *login = conn->login; 1074 + int ret = 0; 1075 + 1076 + spin_lock_bh(&conn->login_timer_lock); 1077 + if (login->login_failed) { 1078 + /* The timer has already expired */ 1079 + ret = -1; 1080 + } else { 1081 + conn->login_kworker = kthr; 1082 + } 1083 + spin_unlock_bh(&conn->login_timer_lock); 1084 + 1085 + return ret; 1086 + } 1087 + 1088 + void iscsit_stop_login_timer(struct iscsit_conn *conn) 1089 + { 1090 + pr_debug("Login timer stopped\n"); 1091 + timer_delete_sync(&conn->login_timer); 1092 + } 1093 + 1043 1094 int iscsit_send_tx_data( 1044 1095 struct iscsit_cmd *cmd, 1045 1096 struct iscsit_conn *conn,
+4
drivers/target/iscsi/iscsi_target_util.h
··· 56 56 extern void __iscsit_start_nopin_timer(struct iscsit_conn *); 57 57 extern void iscsit_start_nopin_timer(struct iscsit_conn *); 58 58 extern void iscsit_stop_nopin_timer(struct iscsit_conn *); 59 + extern void iscsit_login_timeout(struct timer_list *t); 60 + extern void iscsit_start_login_timer(struct iscsit_conn *, struct task_struct *kthr); 61 + extern void iscsit_stop_login_timer(struct iscsit_conn *); 62 + extern int iscsit_set_login_timer_kworker(struct iscsit_conn *, struct task_struct *kthr); 59 63 extern int iscsit_send_tx_data(struct iscsit_cmd *, struct iscsit_conn *, int); 60 64 extern int iscsit_fe_sendpage_sg(struct iscsit_cmd *, struct iscsit_conn *); 61 65 extern int iscsit_tx_login_rsp(struct iscsit_conn *, u8, u8);
+4 -3
include/target/iscsi/iscsi_target_core.h
··· 562 562 #define LOGIN_FLAGS_READ_ACTIVE 2 563 563 #define LOGIN_FLAGS_WRITE_ACTIVE 3 564 564 #define LOGIN_FLAGS_CLOSED 4 565 + #define LOGIN_FLAGS_WORKER_RUNNING 5 565 566 unsigned long login_flags; 566 567 struct delayed_work login_work; 567 568 struct iscsi_login *login; 568 569 struct timer_list nopin_timer; 569 570 struct timer_list nopin_response_timer; 570 - struct timer_list transport_timer; 571 + struct timer_list login_timer; 571 572 struct task_struct *login_kworker; 572 573 /* Spinlock used for add/deleting cmd's from conn_cmd_list */ 573 574 spinlock_t cmd_lock; ··· 577 576 spinlock_t nopin_timer_lock; 578 577 spinlock_t response_queue_lock; 579 578 spinlock_t state_lock; 579 + spinlock_t login_timer_lock; 580 + spinlock_t login_worker_lock; 580 581 /* libcrypto RX and TX contexts for crc32c */ 581 582 struct ahash_request *conn_rx_hash; 582 583 struct ahash_request *conn_tx_hash; ··· 795 792 enum np_thread_state_table np_thread_state; 796 793 bool enabled; 797 794 atomic_t np_reset_count; 798 - enum iscsi_timer_flags_table np_login_timer_flags; 799 795 u32 np_exports; 800 796 enum np_flags_table np_flags; 801 797 spinlock_t np_thread_lock; ··· 802 800 struct socket *np_socket; 803 801 struct sockaddr_storage np_sockaddr; 804 802 struct task_struct *np_thread; 805 - struct timer_list np_login_timer; 806 803 void *np_context; 807 804 struct iscsit_transport *np_transport; 808 805 struct list_head np_list;