diff options
author | Andy Grover <agrover@redhat.com> | 2012-04-03 18:51:29 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-04-14 20:40:39 -0400 |
commit | bfb79eac2026b411df9e253a9c350039b4b04bb7 (patch) | |
tree | 84b492b7d4c06c1083007b05fbcdae1bbb1f551f /drivers/target/iscsi | |
parent | 11e319ed95dc0e8f0fa4cad88b33152e9203b262 (diff) |
target/iscsi: Go back to core allocating data buffer for cmd
We originally changed iscsi to allocate its own buffers just as an
intermediate step to clean up some core buffer allocation mechanisms. Now
we can put it back.
Also had to change allocate_iovecs to use data_length instead of
t_data_nents because iovecs are now allocated before the data buffer, thus
t_data_nents is not yet initialized.
Signed-off-by: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/iscsi')
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 77 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_core.h | 3 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 6 |
3 files changed, 6 insertions, 80 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index e9cc08774732..e39947105ab1 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -687,9 +687,7 @@ int iscsit_add_reject_from_cmd( | |||
687 | 687 | ||
688 | /* | 688 | /* |
689 | * Map some portion of the allocated scatterlist to an iovec, suitable for | 689 | * Map some portion of the allocated scatterlist to an iovec, suitable for |
690 | * kernel sockets to copy data in/out. This handles both pages and slab-allocated | 690 | * kernel sockets to copy data in/out. |
691 | * buffers, since we have been tricky and mapped t_mem_sg to the buffer in | ||
692 | * either case (see iscsit_alloc_buffs) | ||
693 | */ | 691 | */ |
694 | static int iscsit_map_iovec( | 692 | static int iscsit_map_iovec( |
695 | struct iscsi_cmd *cmd, | 693 | struct iscsi_cmd *cmd, |
@@ -702,10 +700,9 @@ static int iscsit_map_iovec( | |||
702 | unsigned int page_off; | 700 | unsigned int page_off; |
703 | 701 | ||
704 | /* | 702 | /* |
705 | * We have a private mapping of the allocated pages in t_mem_sg. | 703 | * We know each entry in t_data_sg contains a page. |
706 | * At this point, we also know each contains a page. | ||
707 | */ | 704 | */ |
708 | sg = &cmd->t_mem_sg[data_offset / PAGE_SIZE]; | 705 | sg = &cmd->se_cmd.t_data_sg[data_offset / PAGE_SIZE]; |
709 | page_off = (data_offset % PAGE_SIZE); | 706 | page_off = (data_offset % PAGE_SIZE); |
710 | 707 | ||
711 | cmd->first_data_sg = sg; | 708 | cmd->first_data_sg = sg; |
@@ -763,8 +760,7 @@ static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) | |||
763 | 760 | ||
764 | static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd) | 761 | static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd) |
765 | { | 762 | { |
766 | u32 iov_count = (cmd->se_cmd.t_data_nents == 0) ? 1 : | 763 | u32 iov_count = min(1UL, DIV_ROUND_UP(cmd->se_cmd.data_length, PAGE_SIZE)); |
767 | cmd->se_cmd.t_data_nents; | ||
768 | 764 | ||
769 | iov_count += ISCSI_IOV_DATA_BUFFER; | 765 | iov_count += ISCSI_IOV_DATA_BUFFER; |
770 | 766 | ||
@@ -778,64 +774,6 @@ static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd) | |||
778 | return 0; | 774 | return 0; |
779 | } | 775 | } |
780 | 776 | ||
781 | static int iscsit_alloc_buffs(struct iscsi_cmd *cmd) | ||
782 | { | ||
783 | struct scatterlist *sgl; | ||
784 | u32 length = cmd->se_cmd.data_length; | ||
785 | int nents = DIV_ROUND_UP(length, PAGE_SIZE); | ||
786 | int i = 0, j = 0, ret; | ||
787 | /* | ||
788 | * If no SCSI payload is present, allocate the default iovecs used for | ||
789 | * iSCSI PDU Header | ||
790 | */ | ||
791 | if (!length) | ||
792 | return iscsit_allocate_iovecs(cmd); | ||
793 | |||
794 | sgl = kzalloc(sizeof(*sgl) * nents, GFP_KERNEL); | ||
795 | if (!sgl) | ||
796 | return -ENOMEM; | ||
797 | |||
798 | sg_init_table(sgl, nents); | ||
799 | |||
800 | while (length) { | ||
801 | int buf_size = min_t(int, length, PAGE_SIZE); | ||
802 | struct page *page; | ||
803 | |||
804 | page = alloc_page(GFP_KERNEL | __GFP_ZERO); | ||
805 | if (!page) | ||
806 | goto page_alloc_failed; | ||
807 | |||
808 | sg_set_page(&sgl[i], page, buf_size, 0); | ||
809 | |||
810 | length -= buf_size; | ||
811 | i++; | ||
812 | } | ||
813 | |||
814 | cmd->t_mem_sg = sgl; | ||
815 | cmd->t_mem_sg_nents = nents; | ||
816 | |||
817 | /* BIDI ops not supported */ | ||
818 | |||
819 | /* Tell the core about our preallocated memory */ | ||
820 | transport_generic_map_mem_to_cmd(&cmd->se_cmd, sgl, nents, NULL, 0); | ||
821 | /* | ||
822 | * Allocate iovecs for SCSI payload after transport_generic_map_mem_to_cmd | ||
823 | * so that cmd->se_cmd.t_tasks_se_num has been set. | ||
824 | */ | ||
825 | ret = iscsit_allocate_iovecs(cmd); | ||
826 | if (ret < 0) | ||
827 | return -ENOMEM; | ||
828 | |||
829 | return 0; | ||
830 | |||
831 | page_alloc_failed: | ||
832 | while (j < i) | ||
833 | __free_page(sg_page(&sgl[j++])); | ||
834 | |||
835 | kfree(sgl); | ||
836 | return -ENOMEM; | ||
837 | } | ||
838 | |||
839 | static int iscsit_handle_scsi_cmd( | 777 | static int iscsit_handle_scsi_cmd( |
840 | struct iscsi_conn *conn, | 778 | struct iscsi_conn *conn, |
841 | unsigned char *buf) | 779 | unsigned char *buf) |
@@ -1075,11 +1013,8 @@ attach_cmd: | |||
1075 | * Active/NonOptimized primary access state.. | 1013 | * Active/NonOptimized primary access state.. |
1076 | */ | 1014 | */ |
1077 | core_alua_check_nonop_delay(&cmd->se_cmd); | 1015 | core_alua_check_nonop_delay(&cmd->se_cmd); |
1078 | /* | 1016 | |
1079 | * Allocate and setup SGL used with transport_generic_map_mem_to_cmd(). | 1017 | ret = iscsit_allocate_iovecs(cmd); |
1080 | * also call iscsit_allocate_iovecs() | ||
1081 | */ | ||
1082 | ret = iscsit_alloc_buffs(cmd); | ||
1083 | if (ret < 0) | 1018 | if (ret < 0) |
1084 | return iscsit_add_reject_from_cmd( | 1019 | return iscsit_add_reject_from_cmd( |
1085 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1020 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 94c736e3a640..1c70144cdaf1 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h | |||
@@ -468,9 +468,6 @@ struct iscsi_cmd { | |||
468 | #define ISCSI_SENSE_BUFFER_LEN (TRANSPORT_SENSE_BUFFER + 2) | 468 | #define ISCSI_SENSE_BUFFER_LEN (TRANSPORT_SENSE_BUFFER + 2) |
469 | unsigned char sense_buffer[ISCSI_SENSE_BUFFER_LEN]; | 469 | unsigned char sense_buffer[ISCSI_SENSE_BUFFER_LEN]; |
470 | 470 | ||
471 | struct scatterlist *t_mem_sg; | ||
472 | u32 t_mem_sg_nents; | ||
473 | |||
474 | u32 padding; | 471 | u32 padding; |
475 | u8 pad_bytes[4]; | 472 | u8 pad_bytes[4]; |
476 | 473 | ||
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 9cd9f30c0237..b42cdeb153df 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
@@ -645,7 +645,6 @@ void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) | |||
645 | void iscsit_release_cmd(struct iscsi_cmd *cmd) | 645 | void iscsit_release_cmd(struct iscsi_cmd *cmd) |
646 | { | 646 | { |
647 | struct iscsi_conn *conn = cmd->conn; | 647 | struct iscsi_conn *conn = cmd->conn; |
648 | int i; | ||
649 | 648 | ||
650 | iscsit_free_r2ts_from_list(cmd); | 649 | iscsit_free_r2ts_from_list(cmd); |
651 | iscsit_free_all_datain_reqs(cmd); | 650 | iscsit_free_all_datain_reqs(cmd); |
@@ -656,11 +655,6 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd) | |||
656 | kfree(cmd->tmr_req); | 655 | kfree(cmd->tmr_req); |
657 | kfree(cmd->iov_data); | 656 | kfree(cmd->iov_data); |
658 | 657 | ||
659 | for (i = 0; i < cmd->t_mem_sg_nents; i++) | ||
660 | __free_page(sg_page(&cmd->t_mem_sg[i])); | ||
661 | |||
662 | kfree(cmd->t_mem_sg); | ||
663 | |||
664 | if (conn) { | 658 | if (conn) { |
665 | iscsit_remove_cmd_from_immediate_queue(cmd, conn); | 659 | iscsit_remove_cmd_from_immediate_queue(cmd, conn); |
666 | iscsit_remove_cmd_from_response_queue(cmd, conn); | 660 | iscsit_remove_cmd_from_response_queue(cmd, conn); |