diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-24 13:22:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-24 13:22:09 -0400 |
commit | c6668726d2c2c581e6c417448c472c994d026f5f (patch) | |
tree | ccbc5a73b9dfe09a065cb5d8627aa2297e730ec0 /drivers/target/iscsi | |
parent | 06b45f2aa703837163496f5db6a53575665cc6b4 (diff) | |
parent | 68d4cef3bab3fb9bb0dbac690ba35a96cb5a16d9 (diff) |
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target updates from Nicholas Bellinger:
"Lots of activity in target land the last months.
The highlights include:
- Convert fabric drivers tree-wide to target_register_template() (hch
+ bart)
- iser-target hardening fixes + v1.0 improvements (sagi)
- Convert iscsi_thread_set usage to kthread.h + kill
iscsi_target_tq.c (sagi + nab)
- Add support for T10-PI WRITE_STRIP + READ_INSERT operation (mkp +
sagi + nab)
- DIF fixes for CONFIG_DEBUG_SG=y + UNMAP file emulation (akinobu +
sagi + mkp)
- Extended TCMU ABI v2 for future BIDI + DIF support (andy + ilias)
- Fix COMPARE_AND_WRITE handling for NO_ALLLOC drivers (hch + nab)
Thanks to everyone who contributed this round with new features,
bug-reports, fixes, cleanups and improvements.
Looking forward, it's currently shaping up to be a busy v4.2 as well"
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (69 commits)
target: Put TCMU under a new config option
target: Version 2 of TCMU ABI
target: fix tcm_mod_builder.py
target/file: Fix UNMAP with DIF protection support
target/file: Fix SG table for prot_buf initialization
target/file: Fix BUG() when CONFIG_DEBUG_SG=y and DIF protection enabled
target: Make core_tmr_abort_task() skip TMFs
target/sbc: Update sbc_dif_generate pr_debug output
target/sbc: Make internal DIF emulation honor ->prot_checks
target/sbc: Return INVALID_CDB_FIELD if DIF + sess_prot_type disabled
target: Ensure sess_prot_type is saved across session restart
target/rd: Don't pass incomplete scatterlist entries to sbc_dif_verify_*
target: Remove the unused flag SCF_ACK_KREF
target: Fix two sparse warnings
target: Fix COMPARE_AND_WRITE with SG_TO_MEM_NOALLOC handling
target: simplify the target template registration API
target: simplify target_xcopy_init_pt_lun
target: remove the unused SCF_CMD_XCOPY_PASSTHROUGH flag
target/rd: reduce code duplication in rd_execute_rw()
tcm_loop: fixup tpgt string to integer conversion
...
Diffstat (limited to 'drivers/target/iscsi')
-rw-r--r-- | drivers/target/iscsi/Makefile | 1 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 131 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target.h | 2 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_configfs.c | 208 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_configfs.h | 7 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_erl0.c | 14 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_login.c | 60 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_tpg.c | 25 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_tpg.h | 1 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_tq.c | 495 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_tq.h | 84 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 1 |
12 files changed, 234 insertions, 795 deletions
diff --git a/drivers/target/iscsi/Makefile b/drivers/target/iscsi/Makefile index 13a92403fe3e..0f43be9c3453 100644 --- a/drivers/target/iscsi/Makefile +++ b/drivers/target/iscsi/Makefile | |||
@@ -1,6 +1,5 @@ | |||
1 | iscsi_target_mod-y += iscsi_target_parameters.o \ | 1 | iscsi_target_mod-y += iscsi_target_parameters.o \ |
2 | iscsi_target_seq_pdu_list.o \ | 2 | iscsi_target_seq_pdu_list.o \ |
3 | iscsi_target_tq.o \ | ||
4 | iscsi_target_auth.o \ | 3 | iscsi_target_auth.o \ |
5 | iscsi_target_datain_values.o \ | 4 | iscsi_target_datain_values.o \ |
6 | iscsi_target_device.o \ | 5 | iscsi_target_device.o \ |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 77d64251af40..34871a628b11 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -33,8 +33,6 @@ | |||
33 | #include <target/iscsi/iscsi_target_core.h> | 33 | #include <target/iscsi/iscsi_target_core.h> |
34 | #include "iscsi_target_parameters.h" | 34 | #include "iscsi_target_parameters.h" |
35 | #include "iscsi_target_seq_pdu_list.h" | 35 | #include "iscsi_target_seq_pdu_list.h" |
36 | #include "iscsi_target_tq.h" | ||
37 | #include "iscsi_target_configfs.h" | ||
38 | #include "iscsi_target_datain_values.h" | 36 | #include "iscsi_target_datain_values.h" |
39 | #include "iscsi_target_erl0.h" | 37 | #include "iscsi_target_erl0.h" |
40 | #include "iscsi_target_erl1.h" | 38 | #include "iscsi_target_erl1.h" |
@@ -537,7 +535,7 @@ static struct iscsit_transport iscsi_target_transport = { | |||
537 | 535 | ||
538 | static int __init iscsi_target_init_module(void) | 536 | static int __init iscsi_target_init_module(void) |
539 | { | 537 | { |
540 | int ret = 0; | 538 | int ret = 0, size; |
541 | 539 | ||
542 | pr_debug("iSCSI-Target "ISCSIT_VERSION"\n"); | 540 | pr_debug("iSCSI-Target "ISCSIT_VERSION"\n"); |
543 | 541 | ||
@@ -546,24 +544,21 @@ static int __init iscsi_target_init_module(void) | |||
546 | pr_err("Unable to allocate memory for iscsit_global\n"); | 544 | pr_err("Unable to allocate memory for iscsit_global\n"); |
547 | return -1; | 545 | return -1; |
548 | } | 546 | } |
547 | spin_lock_init(&iscsit_global->ts_bitmap_lock); | ||
549 | mutex_init(&auth_id_lock); | 548 | mutex_init(&auth_id_lock); |
550 | spin_lock_init(&sess_idr_lock); | 549 | spin_lock_init(&sess_idr_lock); |
551 | idr_init(&tiqn_idr); | 550 | idr_init(&tiqn_idr); |
552 | idr_init(&sess_idr); | 551 | idr_init(&sess_idr); |
553 | 552 | ||
554 | ret = iscsi_target_register_configfs(); | 553 | ret = target_register_template(&iscsi_ops); |
555 | if (ret < 0) | 554 | if (ret) |
556 | goto out; | 555 | goto out; |
557 | 556 | ||
558 | ret = iscsi_thread_set_init(); | 557 | size = BITS_TO_LONGS(ISCSIT_BITMAP_BITS) * sizeof(long); |
559 | if (ret < 0) | 558 | iscsit_global->ts_bitmap = vzalloc(size); |
559 | if (!iscsit_global->ts_bitmap) { | ||
560 | pr_err("Unable to allocate iscsit_global->ts_bitmap\n"); | ||
560 | goto configfs_out; | 561 | goto configfs_out; |
561 | |||
562 | if (iscsi_allocate_thread_sets(TARGET_THREAD_SET_COUNT) != | ||
563 | TARGET_THREAD_SET_COUNT) { | ||
564 | pr_err("iscsi_allocate_thread_sets() returned" | ||
565 | " unexpected value!\n"); | ||
566 | goto ts_out1; | ||
567 | } | 562 | } |
568 | 563 | ||
569 | lio_qr_cache = kmem_cache_create("lio_qr_cache", | 564 | lio_qr_cache = kmem_cache_create("lio_qr_cache", |
@@ -572,7 +567,7 @@ static int __init iscsi_target_init_module(void) | |||
572 | if (!lio_qr_cache) { | 567 | if (!lio_qr_cache) { |
573 | pr_err("nable to kmem_cache_create() for" | 568 | pr_err("nable to kmem_cache_create() for" |
574 | " lio_qr_cache\n"); | 569 | " lio_qr_cache\n"); |
575 | goto ts_out2; | 570 | goto bitmap_out; |
576 | } | 571 | } |
577 | 572 | ||
578 | lio_dr_cache = kmem_cache_create("lio_dr_cache", | 573 | lio_dr_cache = kmem_cache_create("lio_dr_cache", |
@@ -617,12 +612,13 @@ dr_out: | |||
617 | kmem_cache_destroy(lio_dr_cache); | 612 | kmem_cache_destroy(lio_dr_cache); |
618 | qr_out: | 613 | qr_out: |
619 | kmem_cache_destroy(lio_qr_cache); | 614 | kmem_cache_destroy(lio_qr_cache); |
620 | ts_out2: | 615 | bitmap_out: |
621 | iscsi_deallocate_thread_sets(); | 616 | vfree(iscsit_global->ts_bitmap); |
622 | ts_out1: | ||
623 | iscsi_thread_set_free(); | ||
624 | configfs_out: | 617 | configfs_out: |
625 | iscsi_target_deregister_configfs(); | 618 | /* XXX: this probably wants it to be it's own unwind step.. */ |
619 | if (iscsit_global->discovery_tpg) | ||
620 | iscsit_tpg_disable_portal_group(iscsit_global->discovery_tpg, 1); | ||
621 | target_unregister_template(&iscsi_ops); | ||
626 | out: | 622 | out: |
627 | kfree(iscsit_global); | 623 | kfree(iscsit_global); |
628 | return -ENOMEM; | 624 | return -ENOMEM; |
@@ -630,8 +626,6 @@ out: | |||
630 | 626 | ||
631 | static void __exit iscsi_target_cleanup_module(void) | 627 | static void __exit iscsi_target_cleanup_module(void) |
632 | { | 628 | { |
633 | iscsi_deallocate_thread_sets(); | ||
634 | iscsi_thread_set_free(); | ||
635 | iscsit_release_discovery_tpg(); | 629 | iscsit_release_discovery_tpg(); |
636 | iscsit_unregister_transport(&iscsi_target_transport); | 630 | iscsit_unregister_transport(&iscsi_target_transport); |
637 | kmem_cache_destroy(lio_qr_cache); | 631 | kmem_cache_destroy(lio_qr_cache); |
@@ -639,8 +633,15 @@ static void __exit iscsi_target_cleanup_module(void) | |||
639 | kmem_cache_destroy(lio_ooo_cache); | 633 | kmem_cache_destroy(lio_ooo_cache); |
640 | kmem_cache_destroy(lio_r2t_cache); | 634 | kmem_cache_destroy(lio_r2t_cache); |
641 | 635 | ||
642 | iscsi_target_deregister_configfs(); | 636 | /* |
637 | * Shutdown discovery sessions and disable discovery TPG | ||
638 | */ | ||
639 | if (iscsit_global->discovery_tpg) | ||
640 | iscsit_tpg_disable_portal_group(iscsit_global->discovery_tpg, 1); | ||
643 | 641 | ||
642 | target_unregister_template(&iscsi_ops); | ||
643 | |||
644 | vfree(iscsit_global->ts_bitmap); | ||
644 | kfree(iscsit_global); | 645 | kfree(iscsit_global); |
645 | } | 646 | } |
646 | 647 | ||
@@ -990,7 +991,7 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
990 | /* | 991 | /* |
991 | * Initialize struct se_cmd descriptor from target_core_mod infrastructure | 992 | * Initialize struct se_cmd descriptor from target_core_mod infrastructure |
992 | */ | 993 | */ |
993 | transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops, | 994 | transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops, |
994 | conn->sess->se_sess, be32_to_cpu(hdr->data_length), | 995 | conn->sess->se_sess, be32_to_cpu(hdr->data_length), |
995 | cmd->data_direction, sam_task_attr, | 996 | cmd->data_direction, sam_task_attr, |
996 | cmd->sense_buffer + 2); | 997 | cmd->sense_buffer + 2); |
@@ -1805,8 +1806,7 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1805 | u8 tcm_function; | 1806 | u8 tcm_function; |
1806 | int ret; | 1807 | int ret; |
1807 | 1808 | ||
1808 | transport_init_se_cmd(&cmd->se_cmd, | 1809 | transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops, |
1809 | &lio_target_fabric_configfs->tf_ops, | ||
1810 | conn->sess->se_sess, 0, DMA_NONE, | 1810 | conn->sess->se_sess, 0, DMA_NONE, |
1811 | TCM_SIMPLE_TAG, cmd->sense_buffer + 2); | 1811 | TCM_SIMPLE_TAG, cmd->sense_buffer + 2); |
1812 | 1812 | ||
@@ -2155,7 +2155,6 @@ reject: | |||
2155 | cmd->text_in_ptr = NULL; | 2155 | cmd->text_in_ptr = NULL; |
2156 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf); | 2156 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf); |
2157 | } | 2157 | } |
2158 | EXPORT_SYMBOL(iscsit_handle_text_cmd); | ||
2159 | 2158 | ||
2160 | int iscsit_logout_closesession(struct iscsi_cmd *cmd, struct iscsi_conn *conn) | 2159 | int iscsit_logout_closesession(struct iscsi_cmd *cmd, struct iscsi_conn *conn) |
2161 | { | 2160 | { |
@@ -3715,17 +3714,16 @@ static int iscsit_send_reject( | |||
3715 | 3714 | ||
3716 | void iscsit_thread_get_cpumask(struct iscsi_conn *conn) | 3715 | void iscsit_thread_get_cpumask(struct iscsi_conn *conn) |
3717 | { | 3716 | { |
3718 | struct iscsi_thread_set *ts = conn->thread_set; | ||
3719 | int ord, cpu; | 3717 | int ord, cpu; |
3720 | /* | 3718 | /* |
3721 | * thread_id is assigned from iscsit_global->ts_bitmap from | 3719 | * bitmap_id is assigned from iscsit_global->ts_bitmap from |
3722 | * within iscsi_thread_set.c:iscsi_allocate_thread_sets() | 3720 | * within iscsit_start_kthreads() |
3723 | * | 3721 | * |
3724 | * Here we use thread_id to determine which CPU that this | 3722 | * Here we use bitmap_id to determine which CPU that this |
3725 | * iSCSI connection's iscsi_thread_set will be scheduled to | 3723 | * iSCSI connection's RX/TX threads will be scheduled to |
3726 | * execute upon. | 3724 | * execute upon. |
3727 | */ | 3725 | */ |
3728 | ord = ts->thread_id % cpumask_weight(cpu_online_mask); | 3726 | ord = conn->bitmap_id % cpumask_weight(cpu_online_mask); |
3729 | for_each_online_cpu(cpu) { | 3727 | for_each_online_cpu(cpu) { |
3730 | if (ord-- == 0) { | 3728 | if (ord-- == 0) { |
3731 | cpumask_set_cpu(cpu, conn->conn_cpumask); | 3729 | cpumask_set_cpu(cpu, conn->conn_cpumask); |
@@ -3914,7 +3912,7 @@ check_rsp_state: | |||
3914 | switch (state) { | 3912 | switch (state) { |
3915 | case ISTATE_SEND_LOGOUTRSP: | 3913 | case ISTATE_SEND_LOGOUTRSP: |
3916 | if (!iscsit_logout_post_handler(cmd, conn)) | 3914 | if (!iscsit_logout_post_handler(cmd, conn)) |
3917 | goto restart; | 3915 | return -ECONNRESET; |
3918 | /* fall through */ | 3916 | /* fall through */ |
3919 | case ISTATE_SEND_STATUS: | 3917 | case ISTATE_SEND_STATUS: |
3920 | case ISTATE_SEND_ASYNCMSG: | 3918 | case ISTATE_SEND_ASYNCMSG: |
@@ -3942,8 +3940,6 @@ check_rsp_state: | |||
3942 | 3940 | ||
3943 | err: | 3941 | err: |
3944 | return -1; | 3942 | return -1; |
3945 | restart: | ||
3946 | return -EAGAIN; | ||
3947 | } | 3943 | } |
3948 | 3944 | ||
3949 | static int iscsit_handle_response_queue(struct iscsi_conn *conn) | 3945 | static int iscsit_handle_response_queue(struct iscsi_conn *conn) |
@@ -3970,21 +3966,13 @@ static int iscsit_handle_response_queue(struct iscsi_conn *conn) | |||
3970 | int iscsi_target_tx_thread(void *arg) | 3966 | int iscsi_target_tx_thread(void *arg) |
3971 | { | 3967 | { |
3972 | int ret = 0; | 3968 | int ret = 0; |
3973 | struct iscsi_conn *conn; | 3969 | struct iscsi_conn *conn = arg; |
3974 | struct iscsi_thread_set *ts = arg; | ||
3975 | /* | 3970 | /* |
3976 | * Allow ourselves to be interrupted by SIGINT so that a | 3971 | * Allow ourselves to be interrupted by SIGINT so that a |
3977 | * connection recovery / failure event can be triggered externally. | 3972 | * connection recovery / failure event can be triggered externally. |
3978 | */ | 3973 | */ |
3979 | allow_signal(SIGINT); | 3974 | allow_signal(SIGINT); |
3980 | 3975 | ||
3981 | restart: | ||
3982 | conn = iscsi_tx_thread_pre_handler(ts); | ||
3983 | if (!conn) | ||
3984 | goto out; | ||
3985 | |||
3986 | ret = 0; | ||
3987 | |||
3988 | while (!kthread_should_stop()) { | 3976 | while (!kthread_should_stop()) { |
3989 | /* | 3977 | /* |
3990 | * Ensure that both TX and RX per connection kthreads | 3978 | * Ensure that both TX and RX per connection kthreads |
@@ -3993,11 +3981,9 @@ restart: | |||
3993 | iscsit_thread_check_cpumask(conn, current, 1); | 3981 | iscsit_thread_check_cpumask(conn, current, 1); |
3994 | 3982 | ||
3995 | wait_event_interruptible(conn->queues_wq, | 3983 | wait_event_interruptible(conn->queues_wq, |
3996 | !iscsit_conn_all_queues_empty(conn) || | 3984 | !iscsit_conn_all_queues_empty(conn)); |
3997 | ts->status == ISCSI_THREAD_SET_RESET); | ||
3998 | 3985 | ||
3999 | if ((ts->status == ISCSI_THREAD_SET_RESET) || | 3986 | if (signal_pending(current)) |
4000 | signal_pending(current)) | ||
4001 | goto transport_err; | 3987 | goto transport_err; |
4002 | 3988 | ||
4003 | get_immediate: | 3989 | get_immediate: |
@@ -4008,15 +3994,14 @@ get_immediate: | |||
4008 | ret = iscsit_handle_response_queue(conn); | 3994 | ret = iscsit_handle_response_queue(conn); |
4009 | if (ret == 1) | 3995 | if (ret == 1) |
4010 | goto get_immediate; | 3996 | goto get_immediate; |
4011 | else if (ret == -EAGAIN) | 3997 | else if (ret == -ECONNRESET) |
4012 | goto restart; | 3998 | goto out; |
4013 | else if (ret < 0) | 3999 | else if (ret < 0) |
4014 | goto transport_err; | 4000 | goto transport_err; |
4015 | } | 4001 | } |
4016 | 4002 | ||
4017 | transport_err: | 4003 | transport_err: |
4018 | iscsit_take_action_for_connection_exit(conn); | 4004 | iscsit_take_action_for_connection_exit(conn); |
4019 | goto restart; | ||
4020 | out: | 4005 | out: |
4021 | return 0; | 4006 | return 0; |
4022 | } | 4007 | } |
@@ -4111,8 +4096,7 @@ int iscsi_target_rx_thread(void *arg) | |||
4111 | int ret; | 4096 | int ret; |
4112 | u8 buffer[ISCSI_HDR_LEN], opcode; | 4097 | u8 buffer[ISCSI_HDR_LEN], opcode; |
4113 | u32 checksum = 0, digest = 0; | 4098 | u32 checksum = 0, digest = 0; |
4114 | struct iscsi_conn *conn = NULL; | 4099 | struct iscsi_conn *conn = arg; |
4115 | struct iscsi_thread_set *ts = arg; | ||
4116 | struct kvec iov; | 4100 | struct kvec iov; |
4117 | /* | 4101 | /* |
4118 | * Allow ourselves to be interrupted by SIGINT so that a | 4102 | * Allow ourselves to be interrupted by SIGINT so that a |
@@ -4120,11 +4104,6 @@ int iscsi_target_rx_thread(void *arg) | |||
4120 | */ | 4104 | */ |
4121 | allow_signal(SIGINT); | 4105 | allow_signal(SIGINT); |
4122 | 4106 | ||
4123 | restart: | ||
4124 | conn = iscsi_rx_thread_pre_handler(ts); | ||
4125 | if (!conn) | ||
4126 | goto out; | ||
4127 | |||
4128 | if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) { | 4107 | if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) { |
4129 | struct completion comp; | 4108 | struct completion comp; |
4130 | int rc; | 4109 | int rc; |
@@ -4134,7 +4113,7 @@ restart: | |||
4134 | if (rc < 0) | 4113 | if (rc < 0) |
4135 | goto transport_err; | 4114 | goto transport_err; |
4136 | 4115 | ||
4137 | goto out; | 4116 | goto transport_err; |
4138 | } | 4117 | } |
4139 | 4118 | ||
4140 | while (!kthread_should_stop()) { | 4119 | while (!kthread_should_stop()) { |
@@ -4210,8 +4189,6 @@ transport_err: | |||
4210 | if (!signal_pending(current)) | 4189 | if (!signal_pending(current)) |
4211 | atomic_set(&conn->transport_failed, 1); | 4190 | atomic_set(&conn->transport_failed, 1); |
4212 | iscsit_take_action_for_connection_exit(conn); | 4191 | iscsit_take_action_for_connection_exit(conn); |
4213 | goto restart; | ||
4214 | out: | ||
4215 | return 0; | 4192 | return 0; |
4216 | } | 4193 | } |
4217 | 4194 | ||
@@ -4273,7 +4250,24 @@ int iscsit_close_connection( | |||
4273 | if (conn->conn_transport->transport_type == ISCSI_TCP) | 4250 | if (conn->conn_transport->transport_type == ISCSI_TCP) |
4274 | complete(&conn->conn_logout_comp); | 4251 | complete(&conn->conn_logout_comp); |
4275 | 4252 | ||
4276 | iscsi_release_thread_set(conn); | 4253 | if (!strcmp(current->comm, ISCSI_RX_THREAD_NAME)) { |
4254 | if (conn->tx_thread && | ||
4255 | cmpxchg(&conn->tx_thread_active, true, false)) { | ||
4256 | send_sig(SIGINT, conn->tx_thread, 1); | ||
4257 | kthread_stop(conn->tx_thread); | ||
4258 | } | ||
4259 | } else if (!strcmp(current->comm, ISCSI_TX_THREAD_NAME)) { | ||
4260 | if (conn->rx_thread && | ||
4261 | cmpxchg(&conn->rx_thread_active, true, false)) { | ||
4262 | send_sig(SIGINT, conn->rx_thread, 1); | ||
4263 | kthread_stop(conn->rx_thread); | ||
4264 | } | ||
4265 | } | ||
4266 | |||
4267 | spin_lock(&iscsit_global->ts_bitmap_lock); | ||
4268 | bitmap_release_region(iscsit_global->ts_bitmap, conn->bitmap_id, | ||
4269 | get_order(1)); | ||
4270 | spin_unlock(&iscsit_global->ts_bitmap_lock); | ||
4277 | 4271 | ||
4278 | iscsit_stop_timers_for_cmds(conn); | 4272 | iscsit_stop_timers_for_cmds(conn); |
4279 | iscsit_stop_nopin_response_timer(conn); | 4273 | iscsit_stop_nopin_response_timer(conn); |
@@ -4383,8 +4377,6 @@ int iscsit_close_connection( | |||
4383 | 4377 | ||
4384 | iscsit_put_transport(conn->conn_transport); | 4378 | iscsit_put_transport(conn->conn_transport); |
4385 | 4379 | ||
4386 | conn->thread_set = NULL; | ||
4387 | |||
4388 | pr_debug("Moving to TARG_CONN_STATE_FREE.\n"); | 4380 | pr_debug("Moving to TARG_CONN_STATE_FREE.\n"); |
4389 | conn->conn_state = TARG_CONN_STATE_FREE; | 4381 | conn->conn_state = TARG_CONN_STATE_FREE; |
4390 | kfree(conn); | 4382 | kfree(conn); |
@@ -4551,15 +4543,13 @@ static void iscsit_logout_post_handler_closesession( | |||
4551 | struct iscsi_conn *conn) | 4543 | struct iscsi_conn *conn) |
4552 | { | 4544 | { |
4553 | struct iscsi_session *sess = conn->sess; | 4545 | struct iscsi_session *sess = conn->sess; |
4554 | 4546 | int sleep = cmpxchg(&conn->tx_thread_active, true, false); | |
4555 | iscsi_set_thread_clear(conn, ISCSI_CLEAR_TX_THREAD); | ||
4556 | iscsi_set_thread_set_signal(conn, ISCSI_SIGNAL_TX_THREAD); | ||
4557 | 4547 | ||
4558 | atomic_set(&conn->conn_logout_remove, 0); | 4548 | atomic_set(&conn->conn_logout_remove, 0); |
4559 | complete(&conn->conn_logout_comp); | 4549 | complete(&conn->conn_logout_comp); |
4560 | 4550 | ||
4561 | iscsit_dec_conn_usage_count(conn); | 4551 | iscsit_dec_conn_usage_count(conn); |
4562 | iscsit_stop_session(sess, 1, 1); | 4552 | iscsit_stop_session(sess, sleep, sleep); |
4563 | iscsit_dec_session_usage_count(sess); | 4553 | iscsit_dec_session_usage_count(sess); |
4564 | target_put_session(sess->se_sess); | 4554 | target_put_session(sess->se_sess); |
4565 | } | 4555 | } |
@@ -4567,13 +4557,12 @@ static void iscsit_logout_post_handler_closesession( | |||
4567 | static void iscsit_logout_post_handler_samecid( | 4557 | static void iscsit_logout_post_handler_samecid( |
4568 | struct iscsi_conn *conn) | 4558 | struct iscsi_conn *conn) |
4569 | { | 4559 | { |
4570 | iscsi_set_thread_clear(conn, ISCSI_CLEAR_TX_THREAD); | 4560 | int sleep = cmpxchg(&conn->tx_thread_active, true, false); |
4571 | iscsi_set_thread_set_signal(conn, ISCSI_SIGNAL_TX_THREAD); | ||
4572 | 4561 | ||
4573 | atomic_set(&conn->conn_logout_remove, 0); | 4562 | atomic_set(&conn->conn_logout_remove, 0); |
4574 | complete(&conn->conn_logout_comp); | 4563 | complete(&conn->conn_logout_comp); |
4575 | 4564 | ||
4576 | iscsit_cause_connection_reinstatement(conn, 1); | 4565 | iscsit_cause_connection_reinstatement(conn, sleep); |
4577 | iscsit_dec_conn_usage_count(conn); | 4566 | iscsit_dec_conn_usage_count(conn); |
4578 | } | 4567 | } |
4579 | 4568 | ||
diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h index e936d56fb523..7d0f9c00d9c2 100644 --- a/drivers/target/iscsi/iscsi_target.h +++ b/drivers/target/iscsi/iscsi_target.h | |||
@@ -35,7 +35,7 @@ extern void iscsit_stop_session(struct iscsi_session *, int, int); | |||
35 | extern int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *, int); | 35 | extern int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *, int); |
36 | 36 | ||
37 | extern struct iscsit_global *iscsit_global; | 37 | extern struct iscsit_global *iscsit_global; |
38 | extern struct target_fabric_configfs *lio_target_fabric_configfs; | 38 | extern const struct target_core_fabric_ops iscsi_ops; |
39 | 39 | ||
40 | extern struct kmem_cache *lio_dr_cache; | 40 | extern struct kmem_cache *lio_dr_cache; |
41 | extern struct kmem_cache *lio_ooo_cache; | 41 | extern struct kmem_cache *lio_ooo_cache; |
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 48384b675e62..469fce44ebad 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c | |||
@@ -37,9 +37,6 @@ | |||
37 | #include "iscsi_target_util.h" | 37 | #include "iscsi_target_util.h" |
38 | #include "iscsi_target.h" | 38 | #include "iscsi_target.h" |
39 | #include <target/iscsi/iscsi_target_stat.h> | 39 | #include <target/iscsi/iscsi_target_stat.h> |
40 | #include "iscsi_target_configfs.h" | ||
41 | |||
42 | struct target_fabric_configfs *lio_target_fabric_configfs; | ||
43 | 40 | ||
44 | struct lio_target_configfs_attribute { | 41 | struct lio_target_configfs_attribute { |
45 | struct configfs_attribute attr; | 42 | struct configfs_attribute attr; |
@@ -1052,6 +1049,11 @@ TPG_ATTR(default_erl, S_IRUGO | S_IWUSR); | |||
1052 | */ | 1049 | */ |
1053 | DEF_TPG_ATTRIB(t10_pi); | 1050 | DEF_TPG_ATTRIB(t10_pi); |
1054 | TPG_ATTR(t10_pi, S_IRUGO | S_IWUSR); | 1051 | TPG_ATTR(t10_pi, S_IRUGO | S_IWUSR); |
1052 | /* | ||
1053 | * Define iscsi_tpg_attrib_s_fabric_prot_type | ||
1054 | */ | ||
1055 | DEF_TPG_ATTRIB(fabric_prot_type); | ||
1056 | TPG_ATTR(fabric_prot_type, S_IRUGO | S_IWUSR); | ||
1055 | 1057 | ||
1056 | static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = { | 1058 | static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = { |
1057 | &iscsi_tpg_attrib_authentication.attr, | 1059 | &iscsi_tpg_attrib_authentication.attr, |
@@ -1065,6 +1067,7 @@ static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = { | |||
1065 | &iscsi_tpg_attrib_demo_mode_discovery.attr, | 1067 | &iscsi_tpg_attrib_demo_mode_discovery.attr, |
1066 | &iscsi_tpg_attrib_default_erl.attr, | 1068 | &iscsi_tpg_attrib_default_erl.attr, |
1067 | &iscsi_tpg_attrib_t10_pi.attr, | 1069 | &iscsi_tpg_attrib_t10_pi.attr, |
1070 | &iscsi_tpg_attrib_fabric_prot_type.attr, | ||
1068 | NULL, | 1071 | NULL, |
1069 | }; | 1072 | }; |
1070 | 1073 | ||
@@ -1410,8 +1413,18 @@ out: | |||
1410 | 1413 | ||
1411 | TF_TPG_BASE_ATTR(lio_target, enable, S_IRUGO | S_IWUSR); | 1414 | TF_TPG_BASE_ATTR(lio_target, enable, S_IRUGO | S_IWUSR); |
1412 | 1415 | ||
1416 | static ssize_t lio_target_tpg_show_dynamic_sessions( | ||
1417 | struct se_portal_group *se_tpg, | ||
1418 | char *page) | ||
1419 | { | ||
1420 | return target_show_dynamic_sessions(se_tpg, page); | ||
1421 | } | ||
1422 | |||
1423 | TF_TPG_BASE_ATTR_RO(lio_target, dynamic_sessions); | ||
1424 | |||
1413 | static struct configfs_attribute *lio_target_tpg_attrs[] = { | 1425 | static struct configfs_attribute *lio_target_tpg_attrs[] = { |
1414 | &lio_target_tpg_enable.attr, | 1426 | &lio_target_tpg_enable.attr, |
1427 | &lio_target_tpg_dynamic_sessions.attr, | ||
1415 | NULL, | 1428 | NULL, |
1416 | }; | 1429 | }; |
1417 | 1430 | ||
@@ -1450,10 +1463,8 @@ static struct se_portal_group *lio_target_tiqn_addtpg( | |||
1450 | if (!tpg) | 1463 | if (!tpg) |
1451 | return NULL; | 1464 | return NULL; |
1452 | 1465 | ||
1453 | ret = core_tpg_register( | 1466 | ret = core_tpg_register(&iscsi_ops, wwn, &tpg->tpg_se_tpg, |
1454 | &lio_target_fabric_configfs->tf_ops, | 1467 | tpg, TRANSPORT_TPG_TYPE_NORMAL); |
1455 | wwn, &tpg->tpg_se_tpg, tpg, | ||
1456 | TRANSPORT_TPG_TYPE_NORMAL); | ||
1457 | if (ret < 0) | 1468 | if (ret < 0) |
1458 | return NULL; | 1469 | return NULL; |
1459 | 1470 | ||
@@ -1872,6 +1883,20 @@ static int lio_tpg_check_prod_mode_write_protect( | |||
1872 | return tpg->tpg_attrib.prod_mode_write_protect; | 1883 | return tpg->tpg_attrib.prod_mode_write_protect; |
1873 | } | 1884 | } |
1874 | 1885 | ||
1886 | static int lio_tpg_check_prot_fabric_only( | ||
1887 | struct se_portal_group *se_tpg) | ||
1888 | { | ||
1889 | struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr; | ||
1890 | /* | ||
1891 | * Only report fabric_prot_type if t10_pi has also been enabled | ||
1892 | * for incoming ib_isert sessions. | ||
1893 | */ | ||
1894 | if (!tpg->tpg_attrib.t10_pi) | ||
1895 | return 0; | ||
1896 | |||
1897 | return tpg->tpg_attrib.fabric_prot_type; | ||
1898 | } | ||
1899 | |||
1875 | static void lio_tpg_release_fabric_acl( | 1900 | static void lio_tpg_release_fabric_acl( |
1876 | struct se_portal_group *se_tpg, | 1901 | struct se_portal_group *se_tpg, |
1877 | struct se_node_acl *se_acl) | 1902 | struct se_node_acl *se_acl) |
@@ -1953,115 +1978,60 @@ static void lio_release_cmd(struct se_cmd *se_cmd) | |||
1953 | iscsit_release_cmd(cmd); | 1978 | iscsit_release_cmd(cmd); |
1954 | } | 1979 | } |
1955 | 1980 | ||
1956 | /* End functions for target_core_fabric_ops */ | 1981 | const struct target_core_fabric_ops iscsi_ops = { |
1957 | 1982 | .module = THIS_MODULE, | |
1958 | int iscsi_target_register_configfs(void) | 1983 | .name = "iscsi", |
1959 | { | 1984 | .get_fabric_name = iscsi_get_fabric_name, |
1960 | struct target_fabric_configfs *fabric; | 1985 | .get_fabric_proto_ident = iscsi_get_fabric_proto_ident, |
1961 | int ret; | 1986 | .tpg_get_wwn = lio_tpg_get_endpoint_wwn, |
1962 | 1987 | .tpg_get_tag = lio_tpg_get_tag, | |
1963 | lio_target_fabric_configfs = NULL; | 1988 | .tpg_get_default_depth = lio_tpg_get_default_depth, |
1964 | fabric = target_fabric_configfs_init(THIS_MODULE, "iscsi"); | 1989 | .tpg_get_pr_transport_id = iscsi_get_pr_transport_id, |
1965 | if (IS_ERR(fabric)) { | 1990 | .tpg_get_pr_transport_id_len = iscsi_get_pr_transport_id_len, |
1966 | pr_err("target_fabric_configfs_init() for" | 1991 | .tpg_parse_pr_out_transport_id = iscsi_parse_pr_out_transport_id, |
1967 | " LIO-Target failed!\n"); | 1992 | .tpg_check_demo_mode = lio_tpg_check_demo_mode, |
1968 | return PTR_ERR(fabric); | 1993 | .tpg_check_demo_mode_cache = lio_tpg_check_demo_mode_cache, |
1969 | } | 1994 | .tpg_check_demo_mode_write_protect = |
1970 | /* | 1995 | lio_tpg_check_demo_mode_write_protect, |
1971 | * Setup the fabric API of function pointers used by target_core_mod.. | 1996 | .tpg_check_prod_mode_write_protect = |
1972 | */ | 1997 | lio_tpg_check_prod_mode_write_protect, |
1973 | fabric->tf_ops.get_fabric_name = &iscsi_get_fabric_name; | 1998 | .tpg_check_prot_fabric_only = &lio_tpg_check_prot_fabric_only, |
1974 | fabric->tf_ops.get_fabric_proto_ident = &iscsi_get_fabric_proto_ident; | 1999 | .tpg_alloc_fabric_acl = lio_tpg_alloc_fabric_acl, |
1975 | fabric->tf_ops.tpg_get_wwn = &lio_tpg_get_endpoint_wwn; | 2000 | .tpg_release_fabric_acl = lio_tpg_release_fabric_acl, |
1976 | fabric->tf_ops.tpg_get_tag = &lio_tpg_get_tag; | 2001 | .tpg_get_inst_index = lio_tpg_get_inst_index, |
1977 | fabric->tf_ops.tpg_get_default_depth = &lio_tpg_get_default_depth; | 2002 | .check_stop_free = lio_check_stop_free, |
1978 | fabric->tf_ops.tpg_get_pr_transport_id = &iscsi_get_pr_transport_id; | 2003 | .release_cmd = lio_release_cmd, |
1979 | fabric->tf_ops.tpg_get_pr_transport_id_len = | 2004 | .shutdown_session = lio_tpg_shutdown_session, |
1980 | &iscsi_get_pr_transport_id_len; | 2005 | .close_session = lio_tpg_close_session, |
1981 | fabric->tf_ops.tpg_parse_pr_out_transport_id = | 2006 | .sess_get_index = lio_sess_get_index, |
1982 | &iscsi_parse_pr_out_transport_id; | 2007 | .sess_get_initiator_sid = lio_sess_get_initiator_sid, |
1983 | fabric->tf_ops.tpg_check_demo_mode = &lio_tpg_check_demo_mode; | 2008 | .write_pending = lio_write_pending, |
1984 | fabric->tf_ops.tpg_check_demo_mode_cache = | 2009 | .write_pending_status = lio_write_pending_status, |
1985 | &lio_tpg_check_demo_mode_cache; | 2010 | .set_default_node_attributes = lio_set_default_node_attributes, |
1986 | fabric->tf_ops.tpg_check_demo_mode_write_protect = | 2011 | .get_task_tag = iscsi_get_task_tag, |
1987 | &lio_tpg_check_demo_mode_write_protect; | 2012 | .get_cmd_state = iscsi_get_cmd_state, |
1988 | fabric->tf_ops.tpg_check_prod_mode_write_protect = | 2013 | .queue_data_in = lio_queue_data_in, |
1989 | &lio_tpg_check_prod_mode_write_protect; | 2014 | .queue_status = lio_queue_status, |
1990 | fabric->tf_ops.tpg_alloc_fabric_acl = &lio_tpg_alloc_fabric_acl; | 2015 | .queue_tm_rsp = lio_queue_tm_rsp, |
1991 | fabric->tf_ops.tpg_release_fabric_acl = &lio_tpg_release_fabric_acl; | 2016 | .aborted_task = lio_aborted_task, |
1992 | fabric->tf_ops.tpg_get_inst_index = &lio_tpg_get_inst_index; | 2017 | .fabric_make_wwn = lio_target_call_coreaddtiqn, |
1993 | fabric->tf_ops.check_stop_free = &lio_check_stop_free, | 2018 | .fabric_drop_wwn = lio_target_call_coredeltiqn, |
1994 | fabric->tf_ops.release_cmd = &lio_release_cmd; | 2019 | .fabric_make_tpg = lio_target_tiqn_addtpg, |
1995 | fabric->tf_ops.shutdown_session = &lio_tpg_shutdown_session; | 2020 | .fabric_drop_tpg = lio_target_tiqn_deltpg, |
1996 | fabric->tf_ops.close_session = &lio_tpg_close_session; | 2021 | .fabric_make_np = lio_target_call_addnptotpg, |
1997 | fabric->tf_ops.sess_get_index = &lio_sess_get_index; | 2022 | .fabric_drop_np = lio_target_call_delnpfromtpg, |
1998 | fabric->tf_ops.sess_get_initiator_sid = &lio_sess_get_initiator_sid; | 2023 | .fabric_make_nodeacl = lio_target_make_nodeacl, |
1999 | fabric->tf_ops.write_pending = &lio_write_pending; | 2024 | .fabric_drop_nodeacl = lio_target_drop_nodeacl, |
2000 | fabric->tf_ops.write_pending_status = &lio_write_pending_status; | 2025 | |
2001 | fabric->tf_ops.set_default_node_attributes = | 2026 | .tfc_discovery_attrs = lio_target_discovery_auth_attrs, |
2002 | &lio_set_default_node_attributes; | 2027 | .tfc_wwn_attrs = lio_target_wwn_attrs, |
2003 | fabric->tf_ops.get_task_tag = &iscsi_get_task_tag; | 2028 | .tfc_tpg_base_attrs = lio_target_tpg_attrs, |
2004 | fabric->tf_ops.get_cmd_state = &iscsi_get_cmd_state; | 2029 | .tfc_tpg_attrib_attrs = lio_target_tpg_attrib_attrs, |
2005 | fabric->tf_ops.queue_data_in = &lio_queue_data_in; | 2030 | .tfc_tpg_auth_attrs = lio_target_tpg_auth_attrs, |
2006 | fabric->tf_ops.queue_status = &lio_queue_status; | 2031 | .tfc_tpg_param_attrs = lio_target_tpg_param_attrs, |
2007 | fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp; | 2032 | .tfc_tpg_np_base_attrs = lio_target_portal_attrs, |
2008 | fabric->tf_ops.aborted_task = &lio_aborted_task; | 2033 | .tfc_tpg_nacl_base_attrs = lio_target_initiator_attrs, |
2009 | /* | 2034 | .tfc_tpg_nacl_attrib_attrs = lio_target_nacl_attrib_attrs, |
2010 | * Setup function pointers for generic logic in target_core_fabric_configfs.c | 2035 | .tfc_tpg_nacl_auth_attrs = lio_target_nacl_auth_attrs, |
2011 | */ | 2036 | .tfc_tpg_nacl_param_attrs = lio_target_nacl_param_attrs, |
2012 | fabric->tf_ops.fabric_make_wwn = &lio_target_call_coreaddtiqn; | 2037 | }; |
2013 | fabric->tf_ops.fabric_drop_wwn = &lio_target_call_coredeltiqn; | ||
2014 | fabric->tf_ops.fabric_make_tpg = &lio_target_tiqn_addtpg; | ||
2015 | fabric->tf_ops.fabric_drop_tpg = &lio_target_tiqn_deltpg; | ||
2016 | fabric->tf_ops.fabric_post_link = NULL; | ||
2017 | fabric->tf_ops.fabric_pre_unlink = NULL; | ||
2018 | fabric->tf_ops.fabric_make_np = &lio_target_call_addnptotpg; | ||
2019 | fabric->tf_ops.fabric_drop_np = &lio_target_call_delnpfromtpg; | ||
2020 | fabric->tf_ops.fabric_make_nodeacl = &lio_target_make_nodeacl; | ||
2021 | fabric->tf_ops.fabric_drop_nodeacl = &lio_target_drop_nodeacl; | ||
2022 | /* | ||
2023 | * Setup default attribute lists for various fabric->tf_cit_tmpl | ||
2024 | * sturct config_item_type's | ||
2025 | */ | ||
2026 | fabric->tf_cit_tmpl.tfc_discovery_cit.ct_attrs = lio_target_discovery_auth_attrs; | ||
2027 | fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = lio_target_wwn_attrs; | ||
2028 | fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = lio_target_tpg_attrs; | ||
2029 | fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = lio_target_tpg_attrib_attrs; | ||
2030 | fabric->tf_cit_tmpl.tfc_tpg_auth_cit.ct_attrs = lio_target_tpg_auth_attrs; | ||
2031 | fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = lio_target_tpg_param_attrs; | ||
2032 | fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = lio_target_portal_attrs; | ||
2033 | fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = lio_target_initiator_attrs; | ||
2034 | fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = lio_target_nacl_attrib_attrs; | ||
2035 | fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = lio_target_nacl_auth_attrs; | ||
2036 | fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = lio_target_nacl_param_attrs; | ||
2037 | |||
2038 | ret = target_fabric_configfs_register(fabric); | ||
2039 | if (ret < 0) { | ||
2040 | pr_err("target_fabric_configfs_register() for" | ||
2041 | " LIO-Target failed!\n"); | ||
2042 | target_fabric_configfs_free(fabric); | ||
2043 | return ret; | ||
2044 | } | ||
2045 | |||
2046 | lio_target_fabric_configfs = fabric; | ||
2047 | pr_debug("LIO_TARGET[0] - Set fabric ->" | ||
2048 | " lio_target_fabric_configfs\n"); | ||
2049 | return 0; | ||
2050 | } | ||
2051 | |||
2052 | |||
2053 | void iscsi_target_deregister_configfs(void) | ||
2054 | { | ||
2055 | if (!lio_target_fabric_configfs) | ||
2056 | return; | ||
2057 | /* | ||
2058 | * Shutdown discovery sessions and disable discovery TPG | ||
2059 | */ | ||
2060 | if (iscsit_global->discovery_tpg) | ||
2061 | iscsit_tpg_disable_portal_group(iscsit_global->discovery_tpg, 1); | ||
2062 | |||
2063 | target_fabric_configfs_deregister(lio_target_fabric_configfs); | ||
2064 | lio_target_fabric_configfs = NULL; | ||
2065 | pr_debug("LIO_TARGET[0] - Cleared" | ||
2066 | " lio_target_fabric_configfs\n"); | ||
2067 | } | ||
diff --git a/drivers/target/iscsi/iscsi_target_configfs.h b/drivers/target/iscsi/iscsi_target_configfs.h deleted file mode 100644 index 8cd5a63c4edc..000000000000 --- a/drivers/target/iscsi/iscsi_target_configfs.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | #ifndef ISCSI_TARGET_CONFIGFS_H | ||
2 | #define ISCSI_TARGET_CONFIGFS_H | ||
3 | |||
4 | extern int iscsi_target_register_configfs(void); | ||
5 | extern void iscsi_target_deregister_configfs(void); | ||
6 | |||
7 | #endif /* ISCSI_TARGET_CONFIGFS_H */ | ||
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index bdd8731a4daa..959a14c9dd5d 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include <target/iscsi/iscsi_target_core.h> | 24 | #include <target/iscsi/iscsi_target_core.h> |
25 | #include "iscsi_target_seq_pdu_list.h" | 25 | #include "iscsi_target_seq_pdu_list.h" |
26 | #include "iscsi_target_tq.h" | ||
27 | #include "iscsi_target_erl0.h" | 26 | #include "iscsi_target_erl0.h" |
28 | #include "iscsi_target_erl1.h" | 27 | #include "iscsi_target_erl1.h" |
29 | #include "iscsi_target_erl2.h" | 28 | #include "iscsi_target_erl2.h" |
@@ -860,7 +859,10 @@ void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *conn) | |||
860 | } | 859 | } |
861 | spin_unlock_bh(&conn->state_lock); | 860 | spin_unlock_bh(&conn->state_lock); |
862 | 861 | ||
863 | iscsi_thread_set_force_reinstatement(conn); | 862 | if (conn->tx_thread && conn->tx_thread_active) |
863 | send_sig(SIGINT, conn->tx_thread, 1); | ||
864 | if (conn->rx_thread && conn->rx_thread_active) | ||
865 | send_sig(SIGINT, conn->rx_thread, 1); | ||
864 | 866 | ||
865 | sleep: | 867 | sleep: |
866 | wait_for_completion(&conn->conn_wait_rcfr_comp); | 868 | wait_for_completion(&conn->conn_wait_rcfr_comp); |
@@ -885,10 +887,10 @@ void iscsit_cause_connection_reinstatement(struct iscsi_conn *conn, int sleep) | |||
885 | return; | 887 | return; |
886 | } | 888 | } |
887 | 889 | ||
888 | if (iscsi_thread_set_force_reinstatement(conn) < 0) { | 890 | if (conn->tx_thread && conn->tx_thread_active) |
889 | spin_unlock_bh(&conn->state_lock); | 891 | send_sig(SIGINT, conn->tx_thread, 1); |
890 | return; | 892 | if (conn->rx_thread && conn->rx_thread_active) |
891 | } | 893 | send_sig(SIGINT, conn->rx_thread, 1); |
892 | 894 | ||
893 | atomic_set(&conn->connection_reinstatement, 1); | 895 | atomic_set(&conn->connection_reinstatement, 1); |
894 | if (!sleep) { | 896 | if (!sleep) { |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 153fb66ac1b8..8ce94ff744e6 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | #include <target/iscsi/iscsi_target_core.h> | 27 | #include <target/iscsi/iscsi_target_core.h> |
28 | #include <target/iscsi/iscsi_target_stat.h> | 28 | #include <target/iscsi/iscsi_target_stat.h> |
29 | #include "iscsi_target_tq.h" | ||
30 | #include "iscsi_target_device.h" | 29 | #include "iscsi_target_device.h" |
31 | #include "iscsi_target_nego.h" | 30 | #include "iscsi_target_nego.h" |
32 | #include "iscsi_target_erl0.h" | 31 | #include "iscsi_target_erl0.h" |
@@ -699,6 +698,51 @@ static void iscsi_post_login_start_timers(struct iscsi_conn *conn) | |||
699 | iscsit_start_nopin_timer(conn); | 698 | iscsit_start_nopin_timer(conn); |
700 | } | 699 | } |
701 | 700 | ||
701 | static int iscsit_start_kthreads(struct iscsi_conn *conn) | ||
702 | { | ||
703 | int ret = 0; | ||
704 | |||
705 | spin_lock(&iscsit_global->ts_bitmap_lock); | ||
706 | conn->bitmap_id = bitmap_find_free_region(iscsit_global->ts_bitmap, | ||
707 | ISCSIT_BITMAP_BITS, get_order(1)); | ||
708 | spin_unlock(&iscsit_global->ts_bitmap_lock); | ||
709 | |||
710 | if (conn->bitmap_id < 0) { | ||
711 | pr_err("bitmap_find_free_region() failed for" | ||
712 | " iscsit_start_kthreads()\n"); | ||
713 | return -ENOMEM; | ||
714 | } | ||
715 | |||
716 | conn->tx_thread = kthread_run(iscsi_target_tx_thread, conn, | ||
717 | "%s", ISCSI_TX_THREAD_NAME); | ||
718 | if (IS_ERR(conn->tx_thread)) { | ||
719 | pr_err("Unable to start iscsi_target_tx_thread\n"); | ||
720 | ret = PTR_ERR(conn->tx_thread); | ||
721 | goto out_bitmap; | ||
722 | } | ||
723 | conn->tx_thread_active = true; | ||
724 | |||
725 | conn->rx_thread = kthread_run(iscsi_target_rx_thread, conn, | ||
726 | "%s", ISCSI_RX_THREAD_NAME); | ||
727 | if (IS_ERR(conn->rx_thread)) { | ||
728 | pr_err("Unable to start iscsi_target_rx_thread\n"); | ||
729 | ret = PTR_ERR(conn->rx_thread); | ||
730 | goto out_tx; | ||
731 | } | ||
732 | conn->rx_thread_active = true; | ||
733 | |||
734 | return 0; | ||
735 | out_tx: | ||
736 | kthread_stop(conn->tx_thread); | ||
737 | conn->tx_thread_active = false; | ||
738 | out_bitmap: | ||
739 | spin_lock(&iscsit_global->ts_bitmap_lock); | ||
740 | bitmap_release_region(iscsit_global->ts_bitmap, conn->bitmap_id, | ||
741 | get_order(1)); | ||
742 | spin_unlock(&iscsit_global->ts_bitmap_lock); | ||
743 | return ret; | ||
744 | } | ||
745 | |||
702 | int iscsi_post_login_handler( | 746 | int iscsi_post_login_handler( |
703 | struct iscsi_np *np, | 747 | struct iscsi_np *np, |
704 | struct iscsi_conn *conn, | 748 | struct iscsi_conn *conn, |
@@ -709,7 +753,7 @@ int iscsi_post_login_handler( | |||
709 | struct se_session *se_sess = sess->se_sess; | 753 | struct se_session *se_sess = sess->se_sess; |
710 | struct iscsi_portal_group *tpg = sess->tpg; | 754 | struct iscsi_portal_group *tpg = sess->tpg; |
711 | struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; | 755 | struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; |
712 | struct iscsi_thread_set *ts; | 756 | int rc; |
713 | 757 | ||
714 | iscsit_inc_conn_usage_count(conn); | 758 | iscsit_inc_conn_usage_count(conn); |
715 | 759 | ||
@@ -724,7 +768,6 @@ int iscsi_post_login_handler( | |||
724 | /* | 768 | /* |
725 | * SCSI Initiator -> SCSI Target Port Mapping | 769 | * SCSI Initiator -> SCSI Target Port Mapping |
726 | */ | 770 | */ |
727 | ts = iscsi_get_thread_set(); | ||
728 | if (!zero_tsih) { | 771 | if (!zero_tsih) { |
729 | iscsi_set_session_parameters(sess->sess_ops, | 772 | iscsi_set_session_parameters(sess->sess_ops, |
730 | conn->param_list, 0); | 773 | conn->param_list, 0); |
@@ -751,9 +794,11 @@ int iscsi_post_login_handler( | |||
751 | sess->sess_ops->InitiatorName); | 794 | sess->sess_ops->InitiatorName); |
752 | spin_unlock_bh(&sess->conn_lock); | 795 | spin_unlock_bh(&sess->conn_lock); |
753 | 796 | ||
754 | iscsi_post_login_start_timers(conn); | 797 | rc = iscsit_start_kthreads(conn); |
798 | if (rc) | ||
799 | return rc; | ||
755 | 800 | ||
756 | iscsi_activate_thread_set(conn, ts); | 801 | iscsi_post_login_start_timers(conn); |
757 | /* | 802 | /* |
758 | * Determine CPU mask to ensure connection's RX and TX kthreads | 803 | * Determine CPU mask to ensure connection's RX and TX kthreads |
759 | * are scheduled on the same CPU. | 804 | * are scheduled on the same CPU. |
@@ -810,8 +855,11 @@ int iscsi_post_login_handler( | |||
810 | " iSCSI Target Portal Group: %hu\n", tpg->nsessions, tpg->tpgt); | 855 | " iSCSI Target Portal Group: %hu\n", tpg->nsessions, tpg->tpgt); |
811 | spin_unlock_bh(&se_tpg->session_lock); | 856 | spin_unlock_bh(&se_tpg->session_lock); |
812 | 857 | ||
858 | rc = iscsit_start_kthreads(conn); | ||
859 | if (rc) | ||
860 | return rc; | ||
861 | |||
813 | iscsi_post_login_start_timers(conn); | 862 | iscsi_post_login_start_timers(conn); |
814 | iscsi_activate_thread_set(conn, ts); | ||
815 | /* | 863 | /* |
816 | * Determine CPU mask to ensure connection's RX and TX kthreads | 864 | * Determine CPU mask to ensure connection's RX and TX kthreads |
817 | * are scheduled on the same CPU. | 865 | * are scheduled on the same CPU. |
diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index bdd127c0e3ae..e8a240818353 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c | |||
@@ -68,10 +68,8 @@ int iscsit_load_discovery_tpg(void) | |||
68 | return -1; | 68 | return -1; |
69 | } | 69 | } |
70 | 70 | ||
71 | ret = core_tpg_register( | 71 | ret = core_tpg_register(&iscsi_ops, NULL, &tpg->tpg_se_tpg, |
72 | &lio_target_fabric_configfs->tf_ops, | 72 | tpg, TRANSPORT_TPG_TYPE_DISCOVERY); |
73 | NULL, &tpg->tpg_se_tpg, tpg, | ||
74 | TRANSPORT_TPG_TYPE_DISCOVERY); | ||
75 | if (ret < 0) { | 73 | if (ret < 0) { |
76 | kfree(tpg); | 74 | kfree(tpg); |
77 | return -1; | 75 | return -1; |
@@ -228,6 +226,7 @@ static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg) | |||
228 | a->demo_mode_discovery = TA_DEMO_MODE_DISCOVERY; | 226 | a->demo_mode_discovery = TA_DEMO_MODE_DISCOVERY; |
229 | a->default_erl = TA_DEFAULT_ERL; | 227 | a->default_erl = TA_DEFAULT_ERL; |
230 | a->t10_pi = TA_DEFAULT_T10_PI; | 228 | a->t10_pi = TA_DEFAULT_T10_PI; |
229 | a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE; | ||
231 | } | 230 | } |
232 | 231 | ||
233 | int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg) | 232 | int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg) |
@@ -878,3 +877,21 @@ int iscsit_ta_t10_pi( | |||
878 | 877 | ||
879 | return 0; | 878 | return 0; |
880 | } | 879 | } |
880 | |||
881 | int iscsit_ta_fabric_prot_type( | ||
882 | struct iscsi_portal_group *tpg, | ||
883 | u32 prot_type) | ||
884 | { | ||
885 | struct iscsi_tpg_attrib *a = &tpg->tpg_attrib; | ||
886 | |||
887 | if ((prot_type != 0) && (prot_type != 1) && (prot_type != 3)) { | ||
888 | pr_err("Illegal value for fabric_prot_type: %u\n", prot_type); | ||
889 | return -EINVAL; | ||
890 | } | ||
891 | |||
892 | a->fabric_prot_type = prot_type; | ||
893 | pr_debug("iSCSI_TPG[%hu] - T10 Fabric Protection Type: %u\n", | ||
894 | tpg->tpgt, prot_type); | ||
895 | |||
896 | return 0; | ||
897 | } | ||
diff --git a/drivers/target/iscsi/iscsi_target_tpg.h b/drivers/target/iscsi/iscsi_target_tpg.h index e7265337bc43..95ff5bdecd71 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.h +++ b/drivers/target/iscsi/iscsi_target_tpg.h | |||
@@ -39,5 +39,6 @@ extern int iscsit_ta_prod_mode_write_protect(struct iscsi_portal_group *, u32); | |||
39 | extern int iscsit_ta_demo_mode_discovery(struct iscsi_portal_group *, u32); | 39 | extern int iscsit_ta_demo_mode_discovery(struct iscsi_portal_group *, u32); |
40 | extern int iscsit_ta_default_erl(struct iscsi_portal_group *, u32); | 40 | extern int iscsit_ta_default_erl(struct iscsi_portal_group *, u32); |
41 | extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32); | 41 | extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32); |
42 | extern int iscsit_ta_fabric_prot_type(struct iscsi_portal_group *, u32); | ||
42 | 43 | ||
43 | #endif /* ISCSI_TARGET_TPG_H */ | 44 | #endif /* ISCSI_TARGET_TPG_H */ |
diff --git a/drivers/target/iscsi/iscsi_target_tq.c b/drivers/target/iscsi/iscsi_target_tq.c deleted file mode 100644 index 26aa50996473..000000000000 --- a/drivers/target/iscsi/iscsi_target_tq.c +++ /dev/null | |||
@@ -1,495 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * This file contains the iSCSI Login Thread and Thread Queue functions. | ||
3 | * | ||
4 | * (c) Copyright 2007-2013 Datera, Inc. | ||
5 | * | ||
6 | * Author: Nicholas A. Bellinger <nab@linux-iscsi.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | ******************************************************************************/ | ||
18 | |||
19 | #include <linux/kthread.h> | ||
20 | #include <linux/list.h> | ||
21 | #include <linux/bitmap.h> | ||
22 | |||
23 | #include <target/iscsi/iscsi_target_core.h> | ||
24 | #include "iscsi_target_tq.h" | ||
25 | #include "iscsi_target.h" | ||
26 | |||
27 | static LIST_HEAD(inactive_ts_list); | ||
28 | static DEFINE_SPINLOCK(inactive_ts_lock); | ||
29 | static DEFINE_SPINLOCK(ts_bitmap_lock); | ||
30 | |||
31 | static void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts) | ||
32 | { | ||
33 | if (!list_empty(&ts->ts_list)) { | ||
34 | WARN_ON(1); | ||
35 | return; | ||
36 | } | ||
37 | spin_lock(&inactive_ts_lock); | ||
38 | list_add_tail(&ts->ts_list, &inactive_ts_list); | ||
39 | iscsit_global->inactive_ts++; | ||
40 | spin_unlock(&inactive_ts_lock); | ||
41 | } | ||
42 | |||
43 | static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void) | ||
44 | { | ||
45 | struct iscsi_thread_set *ts; | ||
46 | |||
47 | spin_lock(&inactive_ts_lock); | ||
48 | if (list_empty(&inactive_ts_list)) { | ||
49 | spin_unlock(&inactive_ts_lock); | ||
50 | return NULL; | ||
51 | } | ||
52 | |||
53 | ts = list_first_entry(&inactive_ts_list, struct iscsi_thread_set, ts_list); | ||
54 | |||
55 | list_del_init(&ts->ts_list); | ||
56 | iscsit_global->inactive_ts--; | ||
57 | spin_unlock(&inactive_ts_lock); | ||
58 | |||
59 | return ts; | ||
60 | } | ||
61 | |||
62 | int iscsi_allocate_thread_sets(u32 thread_pair_count) | ||
63 | { | ||
64 | int allocated_thread_pair_count = 0, i, thread_id; | ||
65 | struct iscsi_thread_set *ts = NULL; | ||
66 | |||
67 | for (i = 0; i < thread_pair_count; i++) { | ||
68 | ts = kzalloc(sizeof(struct iscsi_thread_set), GFP_KERNEL); | ||
69 | if (!ts) { | ||
70 | pr_err("Unable to allocate memory for" | ||
71 | " thread set.\n"); | ||
72 | return allocated_thread_pair_count; | ||
73 | } | ||
74 | /* | ||
75 | * Locate the next available regision in the thread_set_bitmap | ||
76 | */ | ||
77 | spin_lock(&ts_bitmap_lock); | ||
78 | thread_id = bitmap_find_free_region(iscsit_global->ts_bitmap, | ||
79 | iscsit_global->ts_bitmap_count, get_order(1)); | ||
80 | spin_unlock(&ts_bitmap_lock); | ||
81 | if (thread_id < 0) { | ||
82 | pr_err("bitmap_find_free_region() failed for" | ||
83 | " thread_set_bitmap\n"); | ||
84 | kfree(ts); | ||
85 | return allocated_thread_pair_count; | ||
86 | } | ||
87 | |||
88 | ts->thread_id = thread_id; | ||
89 | ts->status = ISCSI_THREAD_SET_FREE; | ||
90 | INIT_LIST_HEAD(&ts->ts_list); | ||
91 | spin_lock_init(&ts->ts_state_lock); | ||
92 | init_completion(&ts->rx_restart_comp); | ||
93 | init_completion(&ts->tx_restart_comp); | ||
94 | init_completion(&ts->rx_start_comp); | ||
95 | init_completion(&ts->tx_start_comp); | ||
96 | sema_init(&ts->ts_activate_sem, 0); | ||
97 | |||
98 | ts->create_threads = 1; | ||
99 | ts->tx_thread = kthread_run(iscsi_target_tx_thread, ts, "%s", | ||
100 | ISCSI_TX_THREAD_NAME); | ||
101 | if (IS_ERR(ts->tx_thread)) { | ||
102 | dump_stack(); | ||
103 | pr_err("Unable to start iscsi_target_tx_thread\n"); | ||
104 | break; | ||
105 | } | ||
106 | |||
107 | ts->rx_thread = kthread_run(iscsi_target_rx_thread, ts, "%s", | ||
108 | ISCSI_RX_THREAD_NAME); | ||
109 | if (IS_ERR(ts->rx_thread)) { | ||
110 | kthread_stop(ts->tx_thread); | ||
111 | pr_err("Unable to start iscsi_target_rx_thread\n"); | ||
112 | break; | ||
113 | } | ||
114 | ts->create_threads = 0; | ||
115 | |||
116 | iscsi_add_ts_to_inactive_list(ts); | ||
117 | allocated_thread_pair_count++; | ||
118 | } | ||
119 | |||
120 | pr_debug("Spawned %d thread set(s) (%d total threads).\n", | ||
121 | allocated_thread_pair_count, allocated_thread_pair_count * 2); | ||
122 | return allocated_thread_pair_count; | ||
123 | } | ||
124 | |||
125 | static void iscsi_deallocate_thread_one(struct iscsi_thread_set *ts) | ||
126 | { | ||
127 | spin_lock_bh(&ts->ts_state_lock); | ||
128 | ts->status = ISCSI_THREAD_SET_DIE; | ||
129 | |||
130 | if (ts->rx_thread) { | ||
131 | complete(&ts->rx_start_comp); | ||
132 | spin_unlock_bh(&ts->ts_state_lock); | ||
133 | kthread_stop(ts->rx_thread); | ||
134 | spin_lock_bh(&ts->ts_state_lock); | ||
135 | } | ||
136 | if (ts->tx_thread) { | ||
137 | complete(&ts->tx_start_comp); | ||
138 | spin_unlock_bh(&ts->ts_state_lock); | ||
139 | kthread_stop(ts->tx_thread); | ||
140 | spin_lock_bh(&ts->ts_state_lock); | ||
141 | } | ||
142 | spin_unlock_bh(&ts->ts_state_lock); | ||
143 | /* | ||
144 | * Release this thread_id in the thread_set_bitmap | ||
145 | */ | ||
146 | spin_lock(&ts_bitmap_lock); | ||
147 | bitmap_release_region(iscsit_global->ts_bitmap, | ||
148 | ts->thread_id, get_order(1)); | ||
149 | spin_unlock(&ts_bitmap_lock); | ||
150 | |||
151 | kfree(ts); | ||
152 | } | ||
153 | |||
154 | void iscsi_deallocate_thread_sets(void) | ||
155 | { | ||
156 | struct iscsi_thread_set *ts = NULL; | ||
157 | u32 released_count = 0; | ||
158 | |||
159 | while ((ts = iscsi_get_ts_from_inactive_list())) { | ||
160 | |||
161 | iscsi_deallocate_thread_one(ts); | ||
162 | released_count++; | ||
163 | } | ||
164 | |||
165 | if (released_count) | ||
166 | pr_debug("Stopped %d thread set(s) (%d total threads)." | ||
167 | "\n", released_count, released_count * 2); | ||
168 | } | ||
169 | |||
170 | static void iscsi_deallocate_extra_thread_sets(void) | ||
171 | { | ||
172 | u32 orig_count, released_count = 0; | ||
173 | struct iscsi_thread_set *ts = NULL; | ||
174 | |||
175 | orig_count = TARGET_THREAD_SET_COUNT; | ||
176 | |||
177 | while ((iscsit_global->inactive_ts + 1) > orig_count) { | ||
178 | ts = iscsi_get_ts_from_inactive_list(); | ||
179 | if (!ts) | ||
180 | break; | ||
181 | |||
182 | iscsi_deallocate_thread_one(ts); | ||
183 | released_count++; | ||
184 | } | ||
185 | |||
186 | if (released_count) | ||
187 | pr_debug("Stopped %d thread set(s) (%d total threads)." | ||
188 | "\n", released_count, released_count * 2); | ||
189 | } | ||
190 | |||
191 | void iscsi_activate_thread_set(struct iscsi_conn *conn, struct iscsi_thread_set *ts) | ||
192 | { | ||
193 | spin_lock_bh(&ts->ts_state_lock); | ||
194 | conn->thread_set = ts; | ||
195 | ts->conn = conn; | ||
196 | ts->status = ISCSI_THREAD_SET_ACTIVE; | ||
197 | spin_unlock_bh(&ts->ts_state_lock); | ||
198 | |||
199 | complete(&ts->rx_start_comp); | ||
200 | complete(&ts->tx_start_comp); | ||
201 | |||
202 | down(&ts->ts_activate_sem); | ||
203 | } | ||
204 | |||
205 | struct iscsi_thread_set *iscsi_get_thread_set(void) | ||
206 | { | ||
207 | struct iscsi_thread_set *ts; | ||
208 | |||
209 | get_set: | ||
210 | ts = iscsi_get_ts_from_inactive_list(); | ||
211 | if (!ts) { | ||
212 | iscsi_allocate_thread_sets(1); | ||
213 | goto get_set; | ||
214 | } | ||
215 | |||
216 | ts->delay_inactive = 1; | ||
217 | ts->signal_sent = 0; | ||
218 | ts->thread_count = 2; | ||
219 | init_completion(&ts->rx_restart_comp); | ||
220 | init_completion(&ts->tx_restart_comp); | ||
221 | sema_init(&ts->ts_activate_sem, 0); | ||
222 | |||
223 | return ts; | ||
224 | } | ||
225 | |||
226 | void iscsi_set_thread_clear(struct iscsi_conn *conn, u8 thread_clear) | ||
227 | { | ||
228 | struct iscsi_thread_set *ts = NULL; | ||
229 | |||
230 | if (!conn->thread_set) { | ||
231 | pr_err("struct iscsi_conn->thread_set is NULL\n"); | ||
232 | return; | ||
233 | } | ||
234 | ts = conn->thread_set; | ||
235 | |||
236 | spin_lock_bh(&ts->ts_state_lock); | ||
237 | ts->thread_clear &= ~thread_clear; | ||
238 | |||
239 | if ((thread_clear & ISCSI_CLEAR_RX_THREAD) && | ||
240 | (ts->blocked_threads & ISCSI_BLOCK_RX_THREAD)) | ||
241 | complete(&ts->rx_restart_comp); | ||
242 | else if ((thread_clear & ISCSI_CLEAR_TX_THREAD) && | ||
243 | (ts->blocked_threads & ISCSI_BLOCK_TX_THREAD)) | ||
244 | complete(&ts->tx_restart_comp); | ||
245 | spin_unlock_bh(&ts->ts_state_lock); | ||
246 | } | ||
247 | |||
248 | void iscsi_set_thread_set_signal(struct iscsi_conn *conn, u8 signal_sent) | ||
249 | { | ||
250 | struct iscsi_thread_set *ts = NULL; | ||
251 | |||
252 | if (!conn->thread_set) { | ||
253 | pr_err("struct iscsi_conn->thread_set is NULL\n"); | ||
254 | return; | ||
255 | } | ||
256 | ts = conn->thread_set; | ||
257 | |||
258 | spin_lock_bh(&ts->ts_state_lock); | ||
259 | ts->signal_sent |= signal_sent; | ||
260 | spin_unlock_bh(&ts->ts_state_lock); | ||
261 | } | ||
262 | |||
263 | int iscsi_release_thread_set(struct iscsi_conn *conn) | ||
264 | { | ||
265 | int thread_called = 0; | ||
266 | struct iscsi_thread_set *ts = NULL; | ||
267 | |||
268 | if (!conn || !conn->thread_set) { | ||
269 | pr_err("connection or thread set pointer is NULL\n"); | ||
270 | BUG(); | ||
271 | } | ||
272 | ts = conn->thread_set; | ||
273 | |||
274 | spin_lock_bh(&ts->ts_state_lock); | ||
275 | ts->status = ISCSI_THREAD_SET_RESET; | ||
276 | |||
277 | if (!strncmp(current->comm, ISCSI_RX_THREAD_NAME, | ||
278 | strlen(ISCSI_RX_THREAD_NAME))) | ||
279 | thread_called = ISCSI_RX_THREAD; | ||
280 | else if (!strncmp(current->comm, ISCSI_TX_THREAD_NAME, | ||
281 | strlen(ISCSI_TX_THREAD_NAME))) | ||
282 | thread_called = ISCSI_TX_THREAD; | ||
283 | |||
284 | if (ts->rx_thread && (thread_called == ISCSI_TX_THREAD) && | ||
285 | (ts->thread_clear & ISCSI_CLEAR_RX_THREAD)) { | ||
286 | |||
287 | if (!(ts->signal_sent & ISCSI_SIGNAL_RX_THREAD)) { | ||
288 | send_sig(SIGINT, ts->rx_thread, 1); | ||
289 | ts->signal_sent |= ISCSI_SIGNAL_RX_THREAD; | ||
290 | } | ||
291 | ts->blocked_threads |= ISCSI_BLOCK_RX_THREAD; | ||
292 | spin_unlock_bh(&ts->ts_state_lock); | ||
293 | wait_for_completion(&ts->rx_restart_comp); | ||
294 | spin_lock_bh(&ts->ts_state_lock); | ||
295 | ts->blocked_threads &= ~ISCSI_BLOCK_RX_THREAD; | ||
296 | } | ||
297 | if (ts->tx_thread && (thread_called == ISCSI_RX_THREAD) && | ||
298 | (ts->thread_clear & ISCSI_CLEAR_TX_THREAD)) { | ||
299 | |||
300 | if (!(ts->signal_sent & ISCSI_SIGNAL_TX_THREAD)) { | ||
301 | send_sig(SIGINT, ts->tx_thread, 1); | ||
302 | ts->signal_sent |= ISCSI_SIGNAL_TX_THREAD; | ||
303 | } | ||
304 | ts->blocked_threads |= ISCSI_BLOCK_TX_THREAD; | ||
305 | spin_unlock_bh(&ts->ts_state_lock); | ||
306 | wait_for_completion(&ts->tx_restart_comp); | ||
307 | spin_lock_bh(&ts->ts_state_lock); | ||
308 | ts->blocked_threads &= ~ISCSI_BLOCK_TX_THREAD; | ||
309 | } | ||
310 | |||
311 | ts->conn = NULL; | ||
312 | ts->status = ISCSI_THREAD_SET_FREE; | ||
313 | spin_unlock_bh(&ts->ts_state_lock); | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | int iscsi_thread_set_force_reinstatement(struct iscsi_conn *conn) | ||
319 | { | ||
320 | struct iscsi_thread_set *ts; | ||
321 | |||
322 | if (!conn->thread_set) | ||
323 | return -1; | ||
324 | ts = conn->thread_set; | ||
325 | |||
326 | spin_lock_bh(&ts->ts_state_lock); | ||
327 | if (ts->status != ISCSI_THREAD_SET_ACTIVE) { | ||
328 | spin_unlock_bh(&ts->ts_state_lock); | ||
329 | return -1; | ||
330 | } | ||
331 | |||
332 | if (ts->tx_thread && (!(ts->signal_sent & ISCSI_SIGNAL_TX_THREAD))) { | ||
333 | send_sig(SIGINT, ts->tx_thread, 1); | ||
334 | ts->signal_sent |= ISCSI_SIGNAL_TX_THREAD; | ||
335 | } | ||
336 | if (ts->rx_thread && (!(ts->signal_sent & ISCSI_SIGNAL_RX_THREAD))) { | ||
337 | send_sig(SIGINT, ts->rx_thread, 1); | ||
338 | ts->signal_sent |= ISCSI_SIGNAL_RX_THREAD; | ||
339 | } | ||
340 | spin_unlock_bh(&ts->ts_state_lock); | ||
341 | |||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static void iscsi_check_to_add_additional_sets(void) | ||
346 | { | ||
347 | int thread_sets_add; | ||
348 | |||
349 | spin_lock(&inactive_ts_lock); | ||
350 | thread_sets_add = iscsit_global->inactive_ts; | ||
351 | spin_unlock(&inactive_ts_lock); | ||
352 | if (thread_sets_add == 1) | ||
353 | iscsi_allocate_thread_sets(1); | ||
354 | } | ||
355 | |||
356 | static int iscsi_signal_thread_pre_handler(struct iscsi_thread_set *ts) | ||
357 | { | ||
358 | spin_lock_bh(&ts->ts_state_lock); | ||
359 | if (ts->status == ISCSI_THREAD_SET_DIE || kthread_should_stop() || | ||
360 | signal_pending(current)) { | ||
361 | spin_unlock_bh(&ts->ts_state_lock); | ||
362 | return -1; | ||
363 | } | ||
364 | spin_unlock_bh(&ts->ts_state_lock); | ||
365 | |||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | struct iscsi_conn *iscsi_rx_thread_pre_handler(struct iscsi_thread_set *ts) | ||
370 | { | ||
371 | int ret; | ||
372 | |||
373 | spin_lock_bh(&ts->ts_state_lock); | ||
374 | if (ts->create_threads) { | ||
375 | spin_unlock_bh(&ts->ts_state_lock); | ||
376 | goto sleep; | ||
377 | } | ||
378 | |||
379 | if (ts->status != ISCSI_THREAD_SET_DIE) | ||
380 | flush_signals(current); | ||
381 | |||
382 | if (ts->delay_inactive && (--ts->thread_count == 0)) { | ||
383 | spin_unlock_bh(&ts->ts_state_lock); | ||
384 | |||
385 | if (!iscsit_global->in_shutdown) | ||
386 | iscsi_deallocate_extra_thread_sets(); | ||
387 | |||
388 | iscsi_add_ts_to_inactive_list(ts); | ||
389 | spin_lock_bh(&ts->ts_state_lock); | ||
390 | } | ||
391 | |||
392 | if ((ts->status == ISCSI_THREAD_SET_RESET) && | ||
393 | (ts->thread_clear & ISCSI_CLEAR_RX_THREAD)) | ||
394 | complete(&ts->rx_restart_comp); | ||
395 | |||
396 | ts->thread_clear &= ~ISCSI_CLEAR_RX_THREAD; | ||
397 | spin_unlock_bh(&ts->ts_state_lock); | ||
398 | sleep: | ||
399 | ret = wait_for_completion_interruptible(&ts->rx_start_comp); | ||
400 | if (ret != 0) | ||
401 | return NULL; | ||
402 | |||
403 | if (iscsi_signal_thread_pre_handler(ts) < 0) | ||
404 | return NULL; | ||
405 | |||
406 | iscsi_check_to_add_additional_sets(); | ||
407 | |||
408 | spin_lock_bh(&ts->ts_state_lock); | ||
409 | if (!ts->conn) { | ||
410 | pr_err("struct iscsi_thread_set->conn is NULL for" | ||
411 | " RX thread_id: %s/%d\n", current->comm, current->pid); | ||
412 | spin_unlock_bh(&ts->ts_state_lock); | ||
413 | return NULL; | ||
414 | } | ||
415 | ts->thread_clear |= ISCSI_CLEAR_RX_THREAD; | ||
416 | spin_unlock_bh(&ts->ts_state_lock); | ||
417 | |||
418 | up(&ts->ts_activate_sem); | ||
419 | |||
420 | return ts->conn; | ||
421 | } | ||
422 | |||
423 | struct iscsi_conn *iscsi_tx_thread_pre_handler(struct iscsi_thread_set *ts) | ||
424 | { | ||
425 | int ret; | ||
426 | |||
427 | spin_lock_bh(&ts->ts_state_lock); | ||
428 | if (ts->create_threads) { | ||
429 | spin_unlock_bh(&ts->ts_state_lock); | ||
430 | goto sleep; | ||
431 | } | ||
432 | |||
433 | if (ts->status != ISCSI_THREAD_SET_DIE) | ||
434 | flush_signals(current); | ||
435 | |||
436 | if (ts->delay_inactive && (--ts->thread_count == 0)) { | ||
437 | spin_unlock_bh(&ts->ts_state_lock); | ||
438 | |||
439 | if (!iscsit_global->in_shutdown) | ||
440 | iscsi_deallocate_extra_thread_sets(); | ||
441 | |||
442 | iscsi_add_ts_to_inactive_list(ts); | ||
443 | spin_lock_bh(&ts->ts_state_lock); | ||
444 | } | ||
445 | if ((ts->status == ISCSI_THREAD_SET_RESET) && | ||
446 | (ts->thread_clear & ISCSI_CLEAR_TX_THREAD)) | ||
447 | complete(&ts->tx_restart_comp); | ||
448 | |||
449 | ts->thread_clear &= ~ISCSI_CLEAR_TX_THREAD; | ||
450 | spin_unlock_bh(&ts->ts_state_lock); | ||
451 | sleep: | ||
452 | ret = wait_for_completion_interruptible(&ts->tx_start_comp); | ||
453 | if (ret != 0) | ||
454 | return NULL; | ||
455 | |||
456 | if (iscsi_signal_thread_pre_handler(ts) < 0) | ||
457 | return NULL; | ||
458 | |||
459 | iscsi_check_to_add_additional_sets(); | ||
460 | |||
461 | spin_lock_bh(&ts->ts_state_lock); | ||
462 | if (!ts->conn) { | ||
463 | pr_err("struct iscsi_thread_set->conn is NULL for" | ||
464 | " TX thread_id: %s/%d\n", current->comm, current->pid); | ||
465 | spin_unlock_bh(&ts->ts_state_lock); | ||
466 | return NULL; | ||
467 | } | ||
468 | ts->thread_clear |= ISCSI_CLEAR_TX_THREAD; | ||
469 | spin_unlock_bh(&ts->ts_state_lock); | ||
470 | |||
471 | up(&ts->ts_activate_sem); | ||
472 | |||
473 | return ts->conn; | ||
474 | } | ||
475 | |||
476 | int iscsi_thread_set_init(void) | ||
477 | { | ||
478 | int size; | ||
479 | |||
480 | iscsit_global->ts_bitmap_count = ISCSI_TS_BITMAP_BITS; | ||
481 | |||
482 | size = BITS_TO_LONGS(iscsit_global->ts_bitmap_count) * sizeof(long); | ||
483 | iscsit_global->ts_bitmap = kzalloc(size, GFP_KERNEL); | ||
484 | if (!iscsit_global->ts_bitmap) { | ||
485 | pr_err("Unable to allocate iscsit_global->ts_bitmap\n"); | ||
486 | return -ENOMEM; | ||
487 | } | ||
488 | |||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | void iscsi_thread_set_free(void) | ||
493 | { | ||
494 | kfree(iscsit_global->ts_bitmap); | ||
495 | } | ||
diff --git a/drivers/target/iscsi/iscsi_target_tq.h b/drivers/target/iscsi/iscsi_target_tq.h deleted file mode 100644 index cc1eede5ab3a..000000000000 --- a/drivers/target/iscsi/iscsi_target_tq.h +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | #ifndef ISCSI_THREAD_QUEUE_H | ||
2 | #define ISCSI_THREAD_QUEUE_H | ||
3 | |||
4 | /* | ||
5 | * Defines for thread sets. | ||
6 | */ | ||
7 | extern int iscsi_thread_set_force_reinstatement(struct iscsi_conn *); | ||
8 | extern int iscsi_allocate_thread_sets(u32); | ||
9 | extern void iscsi_deallocate_thread_sets(void); | ||
10 | extern void iscsi_activate_thread_set(struct iscsi_conn *, struct iscsi_thread_set *); | ||
11 | extern struct iscsi_thread_set *iscsi_get_thread_set(void); | ||
12 | extern void iscsi_set_thread_clear(struct iscsi_conn *, u8); | ||
13 | extern void iscsi_set_thread_set_signal(struct iscsi_conn *, u8); | ||
14 | extern int iscsi_release_thread_set(struct iscsi_conn *); | ||
15 | extern struct iscsi_conn *iscsi_rx_thread_pre_handler(struct iscsi_thread_set *); | ||
16 | extern struct iscsi_conn *iscsi_tx_thread_pre_handler(struct iscsi_thread_set *); | ||
17 | extern int iscsi_thread_set_init(void); | ||
18 | extern void iscsi_thread_set_free(void); | ||
19 | |||
20 | extern int iscsi_target_tx_thread(void *); | ||
21 | extern int iscsi_target_rx_thread(void *); | ||
22 | |||
23 | #define TARGET_THREAD_SET_COUNT 4 | ||
24 | |||
25 | #define ISCSI_RX_THREAD 1 | ||
26 | #define ISCSI_TX_THREAD 2 | ||
27 | #define ISCSI_RX_THREAD_NAME "iscsi_trx" | ||
28 | #define ISCSI_TX_THREAD_NAME "iscsi_ttx" | ||
29 | #define ISCSI_BLOCK_RX_THREAD 0x1 | ||
30 | #define ISCSI_BLOCK_TX_THREAD 0x2 | ||
31 | #define ISCSI_CLEAR_RX_THREAD 0x1 | ||
32 | #define ISCSI_CLEAR_TX_THREAD 0x2 | ||
33 | #define ISCSI_SIGNAL_RX_THREAD 0x1 | ||
34 | #define ISCSI_SIGNAL_TX_THREAD 0x2 | ||
35 | |||
36 | /* struct iscsi_thread_set->status */ | ||
37 | #define ISCSI_THREAD_SET_FREE 1 | ||
38 | #define ISCSI_THREAD_SET_ACTIVE 2 | ||
39 | #define ISCSI_THREAD_SET_DIE 3 | ||
40 | #define ISCSI_THREAD_SET_RESET 4 | ||
41 | #define ISCSI_THREAD_SET_DEALLOCATE_THREADS 5 | ||
42 | |||
43 | /* By default allow a maximum of 32K iSCSI connections */ | ||
44 | #define ISCSI_TS_BITMAP_BITS 32768 | ||
45 | |||
46 | struct iscsi_thread_set { | ||
47 | /* flags used for blocking and restarting sets */ | ||
48 | int blocked_threads; | ||
49 | /* flag for creating threads */ | ||
50 | int create_threads; | ||
51 | /* flag for delaying readding to inactive list */ | ||
52 | int delay_inactive; | ||
53 | /* status for thread set */ | ||
54 | int status; | ||
55 | /* which threads have had signals sent */ | ||
56 | int signal_sent; | ||
57 | /* flag for which threads exited first */ | ||
58 | int thread_clear; | ||
59 | /* Active threads in the thread set */ | ||
60 | int thread_count; | ||
61 | /* Unique thread ID */ | ||
62 | u32 thread_id; | ||
63 | /* pointer to connection if set is active */ | ||
64 | struct iscsi_conn *conn; | ||
65 | /* used for controlling ts state accesses */ | ||
66 | spinlock_t ts_state_lock; | ||
67 | /* used for restarting thread queue */ | ||
68 | struct completion rx_restart_comp; | ||
69 | /* used for restarting thread queue */ | ||
70 | struct completion tx_restart_comp; | ||
71 | /* used for normal unused blocking */ | ||
72 | struct completion rx_start_comp; | ||
73 | /* used for normal unused blocking */ | ||
74 | struct completion tx_start_comp; | ||
75 | /* OS descriptor for rx thread */ | ||
76 | struct task_struct *rx_thread; | ||
77 | /* OS descriptor for tx thread */ | ||
78 | struct task_struct *tx_thread; | ||
79 | /* struct iscsi_thread_set in list list head*/ | ||
80 | struct list_head ts_list; | ||
81 | struct semaphore ts_activate_sem; | ||
82 | }; | ||
83 | |||
84 | #endif /*** ISCSI_THREAD_QUEUE_H ***/ | ||
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 390df8ed72b2..b18edda3e8af 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include "iscsi_target_erl1.h" | 33 | #include "iscsi_target_erl1.h" |
34 | #include "iscsi_target_erl2.h" | 34 | #include "iscsi_target_erl2.h" |
35 | #include "iscsi_target_tpg.h" | 35 | #include "iscsi_target_tpg.h" |
36 | #include "iscsi_target_tq.h" | ||
37 | #include "iscsi_target_util.h" | 36 | #include "iscsi_target_util.h" |
38 | #include "iscsi_target.h" | 37 | #include "iscsi_target.h" |
39 | 38 | ||