aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/iscsi
diff options
context:
space:
mode:
authorAndy Grover <agrover@redhat.com>2012-04-03 18:51:29 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2012-04-14 20:40:39 -0400
commitbfb79eac2026b411df9e253a9c350039b4b04bb7 (patch)
tree84b492b7d4c06c1083007b05fbcdae1bbb1f551f /drivers/target/iscsi
parent11e319ed95dc0e8f0fa4cad88b33152e9203b262 (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.c77
-rw-r--r--drivers/target/iscsi/iscsi_target_core.h3
-rw-r--r--drivers/target/iscsi/iscsi_target_util.c6
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 */
694static int iscsit_map_iovec( 692static 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
764static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd) 761static 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
781static 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
831page_alloc_failed:
832 while (j < i)
833 __free_page(sg_page(&sgl[j++]));
834
835 kfree(sgl);
836 return -ENOMEM;
837}
838
839static int iscsit_handle_scsi_cmd( 777static 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)
645void iscsit_release_cmd(struct iscsi_cmd *cmd) 645void 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);