[ANNOUNCE] SRP: ProfitBricks publishes its SRP Initiator patches

2013-04-12 Thread Sebastian Riemer
Hello everyone,

I'm very proud to announce that we finally publish our SRP initiator
patches we've been working on for quite some time now.

In the first step we publish our way of failing IO fast as we've noticed
that the way Bart Van Assche does that in his GitHub repository doesn't
match our requirements completely.

His repo: https://github.com/bvanassche/ib_srp-backport
Our repo: https://github.com/sriemer/ib_srp

We want to fail IO fast in exactly the time we configure. With our
patches this works (or please tell us why not). We provide you with full
test descriptions and related shell scripts. Everything is done with as
little dependencies as possible.

The shell scripts can also be very useful to show how to configure and
use SRP with sysfs only. This is why I've added the scst-devel mailing
list here. We want to be as close as possible to the kernel.

We want to combine efforts here and to get valuable feedback from you
all. Evaluation, testing, criticism, comments, etc more than welcome!
Hopefully, we can get a really cool solution into the mainline together!
This would make my job as the maintainer for the ProfitBricks host
kernels a lot easier! ;-)

You'll notice: We've already adapted patches from Bart and parts of his
patches. So it is only fair to publish our patches as well. :-)

It is the same as with Bart's patches: This can't be used for
production, yet. Our patches don't have the reconnect for now. Ideas how
to implement that on top are welcome. Just send your patches directly to
me! :-)

Please further notice: There is a major bug in the upstream
multipath-tools. These read sysfs files cached which leads to IO on
offline devices. We've fixed it for us and publish the fix for you as
well. :-)

Git repo:
https://github.com/sriemer/multipath-tools

Thank you so much for your help in the past and in the future as well!
Thanks for the patience and reading this!

We'll continue publishing our SRP patches relevant for the mainline.
If you want to meet me or ProfitBricks in person, we'll have a booth on
LinuxTag in Berlin/Germany. I'll have a technical talk there about SRP:

http://www.linuxtag.org/2013/en/program/thursday-may-23-2013.html?eventid=208

Cheers,
Sebastian

-- 
Sebastian Riemer
Linux Kernel Developer - Storage

ProfitBricks GmbH • Greifswalder Str. 207 • 10405 Berlin, Germany
www.profitbricks.com • sebastian.rie...@profitbricks.com

Sitz der Gesellschaft: Berlin
Registergericht: Amtsgericht Charlottenburg, HRB 125506 B
Geschäftsführer: Andreas Gauger, Achim Weiss
--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] Ad IB_MTU_1500|9000 enums.

2013-04-12 Thread Jeff Squyres (jsquyres)
On Apr 9, 2013, at 10:44 PM, Weiny, Ira ira.we...@intel.com wrote:

 As an aside I like the use of RDMA_MTU_* for these values.  Again to 
 distinguish them from the IBTA values.  But I know that is poor form.


So what's the right way to move forward on this?  Is it this:

enum ib_mtu {
   IB_MTU_256  = 1,
   IB_MTU_512  = 2,
   IB_MTU_1024 = 3,
   IB_MTU_2048 = 4,
   IB_MTU_4096 = 5,
   RDMA_MTU_1500 = 1500,
   RDMA_MTU_9000 =  9000
};

-- 
Jeff Squyres
jsquy...@cisco.com
For corporate legal information go to: 
http://www.cisco.com/web/about/doing_business/legal/cri/

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


IPOIB-CM MTU

2013-04-12 Thread Wendy Cheng
We're working on a RHEL based system (2.6.32-279.el6.x86_64) that has
slower CPUs (vs. bigger Xeon boxes). The IB stacks are on top of OFA
1.5.4.1 and a mlx adapter (mlx4_0). It is expected that enabling CM
will boost IPOIB bandwidth (measured by Netpipe) due to larger MTU
size (65520).  Unfortunately, it does not happen. It, however, does
show 2x bandwidth gain (CM vs. datagram) on Xeon servers.

While looking around, it is noticed the MTU reported by ifconfig
command correctly shows ipoib_cm_max_mtu number but the socket buffer
sent down to ipoib_cm_send() never exceed 2048 bytes on both Xeon and
the new HW platform. Seeing TSO (driver/firmware semgntation) is off
with CM mode ... intuitively, TCP/IP on Xeon would do better with
segmentation while the (segmentation) overhead (and other specific
platform issues) could weigh down the bandwidth on the subject HW.

If the guess is right, the question here is how to make upper layer,
i.e. IP, send down a bigger (than 2048 bytes) size of fragment ?.
Any comment and/or help ? Is there any other knobs that I should turn
with cm mode (by echo connected into /sys/class/net/ib0/mode) ?

Thanks,
Wendy
--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC-v4 0/9] Add support for iSCSI Extensions for RDMA (ISER) target mode

2013-04-12 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

Hi folks,

This series is the forth RFC for iSCSI Extensions for RDMA (ISER) target
mode support planned for an upcoming v3.10 merge.  This series refactors
existing traditional iscsi-target mode logic in order for external
ib_isert.ko module code to function with areas common to traditional
TCP socket based iSCSI and RDMA verbs based ISER operation.

This includes a basic iscsit_transport API that allows different transports
to reside under the existing iscsi-target configfs control plane, using an
pre-defined network portal attribute to enable a rdma_cm listener on top
of existing ipoib portals.

At this point the code is functional and pushing sustained RDMA_WRITE +
RDMA_READ traffic using open-iscsi on top of multiple iser network portals +
multiple IB HCA ports + multiple LUNs.  Thus far we're using Mellanox IB HCAs
for initial development, and will be verfiying with RoCE capable NICs as well
in the near future.

This RFC-v4 code is available in git against v3.9-rc3 here:

  git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git 
iser_target-rfc-v4

Changes since RFC-v3 include:

- Mark isert_cq_rx_work as static (Or)
- Drop unnecessary ib_dma_sync_single_for_cpu + 
ib_dma_sync_single_for_device
  calls for isert_cmd-sense_buf_dma from isert_put_response (Or)
- Use 12288 for ISER_RX_PAD_SIZE base to save extra page per
  struct iser_rx_desc (Or + nab)
- Drop now unnecessary isert_rx_desc usage, and convert RX users to
  iser_rx_desc (Or + nab)
- Move isert_[alloc,free]_rx_descriptors() ahead of
  isert_create_device_ib_res() usage (nab)
- Mark isert_cq_[rx,tx]_callback() + prototypes as static
- Fix 'warning: 'ret' may be used uninitialized' warning for
  isert_create_device_ib_res on powerpc allmodconfig (fengguang + nab)
- Fix 'warning: 'ret' may be used uninitialized' warning for
  isert_connect_request on i386 allyesconfig (fengguang + nab)
- Fix pr_debug conversion specification in isert_rx_completion()
  (fengguang + nab)
- Drop unnecessary isert_conn-conn_cm_id != NULL check in
  isert_connect_release causing the build warning:
  variable dereferenced before check 'isert_conn-conn_cm_id'
- Fix isert_lid + isert_np leak in isert_setup_np failure path
- Add isert_conn-conn_wait_comp_err usage in isert_free_conn()
  for isert_cq_comp_err completion path
- Add isert_conn-logout_posted bit to determine decrement of
  isert_conn-post_send_buf_count from logout response completion
- Always set ISER_CONN_DOWN from isert_disconnect_work() callback
- Add request_module for ib_isert to lio_target_np_store_iser()
- Add missing iscsit_put_transport() call in 
iscsi_target_setup_login_socket()
  failure case

RFC-v4 has been rebased this afternoon into target-pending 
for-next/for-next-merge
to be picked up by monday's -next build.

Please review.

--nab

Nicholas Bellinger (9):
  target: Add export of target_get_sess_cmd symbol
  iscsi-target: Add iscsit_transport API template
  iscsi-target: Initial traditional TCP conversion to iscsit_transport
  iscsi-target: Add iser-target parameter keys + setup during login
  iscsi-target: Add per transport iscsi_cmd alloc/free
  iscsi-target: Refactor RX PDU logic + export request PDU handling
  iscsi-target: Refactor TX queue logic + export response PDU creation
  iscsi-target: Add iser network portal attribute
  iser-target: Add iSCSI Extensions for RDMA (iSER) target driver

 drivers/infiniband/Kconfig |1 +
 drivers/infiniband/Makefile|1 +
 drivers/infiniband/ulp/isert/Kconfig   |6 +
 drivers/infiniband/ulp/isert/Makefile  |2 +
 drivers/infiniband/ulp/isert/ib_isert.c| 2264 
 drivers/infiniband/ulp/isert/ib_isert.h|  138 ++
 drivers/infiniband/ulp/isert/isert_proto.h |   47 +
 drivers/target/iscsi/Makefile  |3 +-
 drivers/target/iscsi/iscsi_target.c| 1169 -
 drivers/target/iscsi/iscsi_target.h|3 +-
 drivers/target/iscsi/iscsi_target_configfs.c   |   98 +-
 drivers/target/iscsi/iscsi_target_core.h   |   26 +-
 drivers/target/iscsi/iscsi_target_device.c |7 +-
 drivers/target/iscsi/iscsi_target_erl1.c   |   13 +-
 drivers/target/iscsi/iscsi_target_login.c  |  472 --
 drivers/target/iscsi/iscsi_target_login.h  |6 +
 drivers/target/iscsi/iscsi_target_nego.c   |  182 +--
 drivers/target/iscsi/iscsi_target_nego.h   |   11 +-
 drivers/target/iscsi/iscsi_target_parameters.c |   87 +-
 drivers/target/iscsi/iscsi_target_parameters.h |   16 +-
 drivers/target/iscsi/iscsi_target_tmr.c|4 +-
 drivers/target/iscsi/iscsi_target_tpg.c|6 +-
 drivers/target/iscsi/iscsi_target_transport.c  |   55 +
 drivers/target/iscsi/iscsi_target_util.c   |   53 +-
 

[RFC-v4 8/9] iscsi-target: Add iser network portal attribute

2013-04-12 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This patch adds a new network portal attribute for iser, that lives
under existing iscsi-target configfs layout at:

   /sys/kernel/config/target/iscsi/$TARGETNAME/$TPGT/np/$PORTAL/iser

When lio_target_np_store_iser() is enabled, iscsit_tpg_add_network_portal()
will attempt to start an rdma_cma network portal for iser-target, only if
the external ib_isert module transport has been loaded.

When disabled, iscsit_tpg_del_network_portal() will cease iser login service
on the network portal, and release any external ib_isert module reference.

v4 changes:

- Add request_module for ib_isert to lio_target_np_store_iser()

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/iscsi_target_configfs.c |   79 ++
 1 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target_configfs.c 
b/drivers/target/iscsi/iscsi_target_configfs.c
index 2704daf..13e9e71 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -125,8 +125,87 @@ out:
 
 TF_NP_BASE_ATTR(lio_target, sctp, S_IRUGO | S_IWUSR);
 
+static ssize_t lio_target_np_show_iser(
+   struct se_tpg_np *se_tpg_np,
+   char *page)
+{
+   struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np,
+   struct iscsi_tpg_np, se_tpg_np);
+   struct iscsi_tpg_np *tpg_np_iser;
+   ssize_t rb;
+
+   tpg_np_iser = iscsit_tpg_locate_child_np(tpg_np, ISCSI_INFINIBAND);
+   if (tpg_np_iser)
+   rb = sprintf(page, 1\n);
+   else
+   rb = sprintf(page, 0\n);
+
+   return rb;
+}
+
+static ssize_t lio_target_np_store_iser(
+   struct se_tpg_np *se_tpg_np,
+   const char *page,
+   size_t count)
+{
+   struct iscsi_np *np;
+   struct iscsi_portal_group *tpg;
+   struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np,
+   struct iscsi_tpg_np, se_tpg_np);
+   struct iscsi_tpg_np *tpg_np_iser = NULL;
+   char *endptr;
+   u32 op;
+   int rc;
+
+   op = simple_strtoul(page, endptr, 0);
+   if ((op != 1)  (op != 0)) {
+   pr_err(Illegal value for tpg_enable: %u\n, op);
+   return -EINVAL;
+   }
+   np = tpg_np-tpg_np;
+   if (!np) {
+   pr_err(Unable to locate struct iscsi_np from
+struct iscsi_tpg_np\n);
+   return -EINVAL;
+   }
+
+   tpg = tpg_np-tpg;
+   if (iscsit_get_tpg(tpg)  0)
+   return -EINVAL;
+
+   if (op) {
+   int rc = request_module(ib_isert);
+   if (rc != 0)
+   pr_warn(Unable to request_module for ib_isert\n);
+
+   tpg_np_iser = iscsit_tpg_add_network_portal(tpg, 
np-np_sockaddr,
+   np-np_ip, tpg_np, ISCSI_INFINIBAND);
+   if (!tpg_np_iser || IS_ERR(tpg_np_iser))
+   goto out;
+   } else {
+   tpg_np_iser = iscsit_tpg_locate_child_np(tpg_np, 
ISCSI_INFINIBAND);
+   if (!tpg_np_iser)
+   goto out;
+
+   rc = iscsit_tpg_del_network_portal(tpg, tpg_np_iser);
+   if (rc  0)
+   goto out;
+   }
+
+   printk(lio_target_np_store_iser() done, op: %d\n, op);
+
+   iscsit_put_tpg(tpg);
+   return count;
+out:
+   iscsit_put_tpg(tpg);
+   return -EINVAL;
+}
+
+TF_NP_BASE_ATTR(lio_target, iser, S_IRUGO | S_IWUSR);
+
 static struct configfs_attribute *lio_target_portal_attrs[] = {
lio_target_np_sctp.attr,
+   lio_target_np_iser.attr,
NULL,
 };
 
-- 
1.7.2.5

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC-v4 1/9] target: Add export of target_get_sess_cmd symbol

2013-04-12 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

Export target_get_sess_cmd() symbol so that it can be used by
iscsi-target.

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/target_core_transport.c |4 ++--
 include/target/target_core_fabric.h|2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index 493e9e5..f8388b4 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -65,7 +65,6 @@ static void transport_complete_task_attr(struct se_cmd *cmd);
 static void transport_handle_queue_full(struct se_cmd *cmd,
struct se_device *dev);
 static int transport_generic_get_mem(struct se_cmd *cmd);
-static int target_get_sess_cmd(struct se_session *, struct se_cmd *, bool);
 static void transport_put_cmd(struct se_cmd *cmd);
 static void target_complete_ok_work(struct work_struct *work);
 
@@ -2179,7 +2178,7 @@ EXPORT_SYMBOL(transport_generic_free_cmd);
  * @se_cmd:command descriptor to add
  * @ack_kref:  Signal that fabric will perform an ack target_put_sess_cmd()
  */
-static int target_get_sess_cmd(struct se_session *se_sess, struct se_cmd 
*se_cmd,
+int target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd,
   bool ack_kref)
 {
unsigned long flags;
@@ -2208,6 +2207,7 @@ out:
spin_unlock_irqrestore(se_sess-sess_cmd_lock, flags);
return ret;
 }
+EXPORT_SYMBOL(target_get_sess_cmd);
 
 static void target_release_cmd_kref(struct kref *kref)
 {
diff --git a/include/target/target_core_fabric.h 
b/include/target/target_core_fabric.h
index aaa1ee6..ba3471b 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -120,7 +120,7 @@ booltransport_wait_for_tasks(struct se_cmd *);
 inttransport_check_aborted_status(struct se_cmd *, int);
 inttransport_send_check_condition_and_sense(struct se_cmd *,
sense_reason_t, int);
-
+inttarget_get_sess_cmd(struct se_session *, struct se_cmd *, bool);
 inttarget_put_sess_cmd(struct se_session *, struct se_cmd *);
 void   target_sess_cmd_list_set_waiting(struct se_session *);
 void   target_wait_for_sess_cmds(struct se_session *, int);
-- 
1.7.2.5

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC-v4 3/9] iscsi-target: Initial traditional TCP conversion to iscsit_transport

2013-04-12 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This patch performs the initial conversion of existing traditional iscsi
to use iscsit_transport API callers.  This includes:

- iscsi-np cleanups for iscsit_transport_type
- Add iscsi-np transport calls w/ -iscsit_setup_up() and -iscsit_free_np()
- Convert login thread process context to use -iscsit_accept_np() for
  connections with pre-allocated struct iscsi_conn
- Convert existing socket accept code to iscsit_accept_np()
- Convert login RX/TX callers to use -iscsit_get_login_rx() and
  -iscsit_put_login_tx() to exchange request/response PDUs
- Convert existing socket login RX/TX calls into iscsit_get_login_rx()
  and iscsit_put_login_tx()
- Change iscsit_close_connection() to invoke -iscsit_free_conn() +
  iscsit_put_transport() calls.
- Add iscsit_register_transport() + iscsit_unregister_transport() calls
  to module init/exit

v4 changes:

- Add missing iscsit_put_transport() call in iscsi_target_setup_login_socket()
  failure case

v2 changes:

- Update module init/exit to use register_transport() + unregister_transport()

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/iscsi_target.c|   35 ++-
 drivers/target/iscsi/iscsi_target_core.h   |   15 +-
 drivers/target/iscsi/iscsi_target_login.c  |  416 ---
 drivers/target/iscsi/iscsi_target_login.h  |6 +
 drivers/target/iscsi/iscsi_target_nego.c   |  167 +-
 drivers/target/iscsi/iscsi_target_nego.h   |   11 +-
 drivers/target/iscsi/iscsi_target_parameters.c |   12 +-
 drivers/target/iscsi/iscsi_target_tpg.c|6 +-
 drivers/target/iscsi/iscsi_target_util.c   |   27 +--
 9 files changed, 380 insertions(+), 315 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 7ea246a..8203bf3 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -49,6 +49,8 @@
 #include iscsi_target_device.h
 #include iscsi_target_stat.h
 
+#include target/iscsi/iscsi_transport.h
+
 static LIST_HEAD(g_tiqn_list);
 static LIST_HEAD(g_np_list);
 static DEFINE_SPINLOCK(tiqn_lock);
@@ -401,8 +403,7 @@ struct iscsi_np *iscsit_add_np(
spin_unlock_bh(np_lock);
 
pr_debug(CORE[0] - Added Network Portal: %s:%hu on %s\n,
-   np-np_ip, np-np_port, (np-np_network_transport == ISCSI_TCP) 
?
-   TCP : SCTP);
+   np-np_ip, np-np_port, np-np_transport-name);
 
return np;
 }
@@ -441,11 +442,10 @@ int iscsit_reset_np_thread(
return 0;
 }
 
-static int iscsit_del_np_comm(struct iscsi_np *np)
+static void iscsit_free_np(struct iscsi_np *np)
 {
if (np-np_socket)
sock_release(np-np_socket);
-   return 0;
 }
 
 int iscsit_del_np(struct iscsi_np *np)
@@ -467,20 +467,32 @@ int iscsit_del_np(struct iscsi_np *np)
send_sig(SIGINT, np-np_thread, 1);
kthread_stop(np-np_thread);
}
-   iscsit_del_np_comm(np);
+
+   np-np_transport-iscsit_free_np(np);
 
spin_lock_bh(np_lock);
list_del(np-np_list);
spin_unlock_bh(np_lock);
 
pr_debug(CORE[0] - Removed Network Portal: %s:%hu on %s\n,
-   np-np_ip, np-np_port, (np-np_network_transport == ISCSI_TCP) 
?
-   TCP : SCTP);
+   np-np_ip, np-np_port, np-np_transport-name);
 
+   iscsit_put_transport(np-np_transport);
kfree(np);
return 0;
 }
 
+static struct iscsit_transport iscsi_target_transport = {
+   .name   = iSCSI/TCP,
+   .transport_type = ISCSI_TCP,
+   .owner  = NULL,
+   .iscsit_setup_np= iscsit_setup_np,
+   .iscsit_accept_np   = iscsit_accept_np,
+   .iscsit_free_np = iscsit_free_np,
+   .iscsit_get_login_rx= iscsit_get_login_rx,
+   .iscsit_put_login_tx= iscsit_put_login_tx,
+};
+
 static int __init iscsi_target_init_module(void)
 {
int ret = 0;
@@ -557,6 +569,8 @@ static int __init iscsi_target_init_module(void)
goto ooo_out;
}
 
+   iscsit_register_transport(iscsi_target_transport);
+
if (iscsit_load_discovery_tpg()  0)
goto r2t_out;
 
@@ -587,6 +601,7 @@ static void __exit iscsi_target_cleanup_module(void)
iscsi_deallocate_thread_sets();
iscsi_thread_set_free();
iscsit_release_discovery_tpg();
+   iscsit_unregister_transport(iscsi_target_transport);
kmem_cache_destroy(lio_cmd_cache);
kmem_cache_destroy(lio_qr_cache);
kmem_cache_destroy(lio_dr_cache);
@@ -4053,6 +4068,12 @@ int iscsit_close_connection(
 
if (conn-sock)
sock_release(conn-sock);
+
+   if (conn-conn_transport-iscsit_free_conn)
+   conn-conn_transport-iscsit_free_conn(conn);
+
+   iscsit_put_transport(conn-conn_transport);
+
conn-thread_set = NULL;
 

[RFC-v4 5/9] iscsi-target: Add per transport iscsi_cmd alloc/free

2013-04-12 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This patch converts struct iscsi_cmd memory allocation + free to use
-iscsit_alloc_cmd() iscsit_transport API caller, and export
iscsit_allocate_cmd() symbols

Also add iscsi_cmd-release_cmd() to be used seperately from
iscsit_transport for connection/session shutdown.

v2 changes:

- Remove unnecessary checks in iscsit_alloc_cmd (asias)
- Drop iscsit_transport-iscsit_free_cmd() usage
- Drop iscsit_transport-iscsit_unmap_cmd() usage
- Add iscsi_cmd-release_cmd()
- Convert lio_release_cmd() to use iscsi_cmd-release_cmd()

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/iscsi_target.c  |1 +
 drivers/target/iscsi/iscsi_target_configfs.c |3 ++-
 drivers/target/iscsi/iscsi_target_core.h |1 +
 drivers/target/iscsi/iscsi_target_util.c |   25 +
 drivers/target/iscsi/iscsi_target_util.h |1 +
 5 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 8203bf3..b01a10e 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -489,6 +489,7 @@ static struct iscsit_transport iscsi_target_transport = {
.iscsit_setup_np= iscsit_setup_np,
.iscsit_accept_np   = iscsit_accept_np,
.iscsit_free_np = iscsit_free_np,
+   .iscsit_alloc_cmd   = iscsit_alloc_cmd,
.iscsit_get_login_rx= iscsit_get_login_rx,
.iscsit_put_login_tx= iscsit_put_login_tx,
 };
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c 
b/drivers/target/iscsi/iscsi_target_configfs.c
index 78d75c8..c78b824 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -1700,7 +1700,8 @@ static void lio_release_cmd(struct se_cmd *se_cmd)
 {
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
 
-   iscsit_release_cmd(cmd);
+   pr_debug(Entering lio_release_cmd for se_cmd: %p\n, se_cmd);
+   cmd-release_cmd(cmd);
 }
 
 /* End functions for target_core_fabric_ops */
diff --git a/drivers/target/iscsi/iscsi_target_core.h 
b/drivers/target/iscsi/iscsi_target_core.h
index 53400b0..60ec4b9 100644
--- a/drivers/target/iscsi/iscsi_target_core.h
+++ b/drivers/target/iscsi/iscsi_target_core.h
@@ -485,6 +485,7 @@ struct iscsi_cmd {
u32 first_data_sg_off;
u32 kmapped_nents;
sense_reason_t  sense_reason;
+   void (*release_cmd)(struct iscsi_cmd *);
 }  cacheline_aligned;
 
 struct iscsi_tmr_req {
diff --git a/drivers/target/iscsi/iscsi_target_util.c 
b/drivers/target/iscsi/iscsi_target_util.c
index 4cf1e7f..0b73f90 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -149,6 +149,18 @@ void iscsit_free_r2ts_from_list(struct iscsi_cmd *cmd)
spin_unlock_bh(cmd-r2t_lock);
 }
 
+struct iscsi_cmd *iscsit_alloc_cmd(struct iscsi_conn *conn, gfp_t gfp_mask)
+{
+   struct iscsi_cmd *cmd;
+
+   cmd = kmem_cache_zalloc(lio_cmd_cache, gfp_mask);
+   if (!cmd)
+   return NULL;
+
+   cmd-release_cmd = iscsit_release_cmd;
+   return cmd;
+}
+
 /*
  * May be called from software interrupt (timer) context for allocating
  * iSCSI NopINs.
@@ -157,13 +169,12 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn 
*conn, gfp_t gfp_mask)
 {
struct iscsi_cmd *cmd;
 
-   cmd = kmem_cache_zalloc(lio_cmd_cache, gfp_mask);
+   cmd = conn-conn_transport-iscsit_alloc_cmd(conn, gfp_mask);
if (!cmd) {
pr_err(Unable to allocate memory for struct iscsi_cmd.\n);
return NULL;
}
-
-   cmd-conn   = conn;
+   cmd-conn = conn;
INIT_LIST_HEAD(cmd-i_conn_node);
INIT_LIST_HEAD(cmd-datain_list);
INIT_LIST_HEAD(cmd-cmd_r2t_list);
@@ -176,6 +187,7 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn 
*conn, gfp_t gfp_mask)
 
return cmd;
 }
+EXPORT_SYMBOL(iscsit_allocate_cmd);
 
 struct iscsi_seq *iscsit_get_seq_holder_for_datain(
struct iscsi_cmd *cmd,
@@ -690,6 +702,11 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd)
 */
switch (cmd-iscsi_opcode) {
case ISCSI_OP_SCSI_CMD:
+   if (cmd-data_direction == DMA_TO_DEVICE)
+   iscsit_stop_dataout_timer(cmd);
+   /*
+* Fallthrough
+*/
case ISCSI_OP_SCSI_TMFUNC:
transport_generic_free_cmd(cmd-se_cmd, 1);
break;
@@ -705,7 +722,7 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd)
}
/* Fall-through */
default:
-   iscsit_release_cmd(cmd);
+   cmd-release_cmd(cmd);
break;
}
 }
diff --git a/drivers/target/iscsi/iscsi_target_util.h 

[RFC-v4 7/9] iscsi-target: Refactor TX queue logic + export response PDU creation

2013-04-12 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This patch refactors TX immediate + response queue handling to use
the new iscsit_transport API callers, and exports the necessary
traditional iscsi PDU response creation functions for iser-target
to utilize.

This includes:

- Add iscsit_build_datain_pdu() for DATAIN PDU init + convert
  iscsit_build_datain_pdu()
- Add iscsit_build_logout_rsp() for LOGOUT_RSP PDU init + convert
  iscsit_send_logout()
- Add iscsit_build_nopin_rsp() for NOPIN_RSP PDU init + convert
  iscsit_send_nopin()
- Add iscsit_build_rsp_pdu() for SCSI_RSP PDU init + convert
  iscsit_send_response()
- Add iscsit_build_task_mgt_rsp for TM_RSP PDU init + convert
  iscsit_send_task_mgt_rsp()
- Refactor immediate queue state switch into iscsit_immediate_queue()
- Convert handle_immediate_queue() to use iscsit_transport caller
- Refactor response queue state switch into iscsit_response_queue()
- Convert handle_response_queue to use iscsit_transport caller
- Export iscsit_logout_post_handler(), iscsit_increment_maxcmdsn()
  and iscsit_tmr_post_handler() for external transport module usage

v3 changes:
- Add iscsit_build_reject for REJECT PDU init + convert
  iscsit_send_reject()

v2 changes:

- Add iscsit_queue_rsp() for iscsit_transport-iscsit_queue_data_in()
  and iscsit_transport-iscsit_queue_status()
- Update lio_queue_data_in() to use -iscsit_queue_data_in()
- Update lio_queue_status() to use -iscsit_queue_status()
- Use mutex_trylock() in iscsit_increment_maxcmdsn()

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/iscsi_target.c  |  661 ++
 drivers/target/iscsi/iscsi_target_configfs.c |7 +-
 drivers/target/iscsi/iscsi_target_device.c   |7 +-
 drivers/target/iscsi/iscsi_target_tmr.c  |1 +
 4 files changed, 374 insertions(+), 302 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 19d4e08..3948aa1 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -70,8 +70,7 @@ struct kmem_cache *lio_ooo_cache;
 struct kmem_cache *lio_r2t_cache;
 
 static int iscsit_handle_immediate_data(struct iscsi_cmd *,
-   unsigned char *buf, u32);
-static int iscsit_logout_post_handler(struct iscsi_cmd *, struct iscsi_conn *);
+   struct iscsi_scsi_req *, u32);
 
 struct iscsi_tiqn *iscsit_get_tiqn_for_login(unsigned char *buf)
 {
@@ -482,6 +481,15 @@ int iscsit_del_np(struct iscsi_np *np)
return 0;
 }
 
+static int iscsit_immediate_queue(struct iscsi_conn *, struct iscsi_cmd *, 
int);
+static int iscsit_response_queue(struct iscsi_conn *, struct iscsi_cmd *, int);
+
+static int iscsit_queue_rsp(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
+{
+   iscsit_add_cmd_to_response_queue(cmd, cmd-conn, cmd-i_state);
+   return 0;
+}
+
 static struct iscsit_transport iscsi_target_transport = {
.name   = iSCSI/TCP,
.transport_type = ISCSI_TCP,
@@ -493,6 +501,10 @@ static struct iscsit_transport iscsi_target_transport = {
.iscsit_get_login_rx= iscsit_get_login_rx,
.iscsit_put_login_tx= iscsit_put_login_tx,
.iscsit_get_dataout = iscsit_build_r2ts_for_cmd,
+   .iscsit_immediate_queue = iscsit_immediate_queue,
+   .iscsit_response_queue  = iscsit_response_queue,
+   .iscsit_queue_data_in   = iscsit_queue_rsp,
+   .iscsit_queue_status= iscsit_queue_rsp,
 };
 
 static int __init iscsi_target_init_module(void)
@@ -651,14 +663,6 @@ static int iscsit_add_reject(
iscsit_add_cmd_to_response_queue(cmd, conn, cmd-i_state);
 
ret = wait_for_completion_interruptible(cmd-reject_comp);
-   /*
-* Perform the kref_put now if se_cmd has been setup by
-* iscsit_setup_scsi_cmd()
-*/
-   if (cmd-se_cmd.se_tfo != NULL) {
-   pr_debug(iscsi reject: calling target_put_sess_cmd \n);
-   target_put_sess_cmd(conn-sess-se_sess, cmd-se_cmd);
-   }
if (ret != 0)
return -1;
 
@@ -2536,18 +2540,60 @@ static void iscsit_tx_thread_wait_for_tcp(struct 
iscsi_conn *conn)
}
 }
 
-static int iscsit_send_data_in(
-   struct iscsi_cmd *cmd,
-   struct iscsi_conn *conn)
+static void
+iscsit_build_datain_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
+   struct iscsi_datain *datain, struct iscsi_data_rsp *hdr,
+   bool set_statsn)
 {
-   int iov_ret = 0, set_statsn = 0;
-   u32 iov_count = 0, tx_size = 0;
+   hdr-opcode = ISCSI_OP_SCSI_DATA_IN;
+   hdr-flags  = datain-flags;
+   if (hdr-flags  ISCSI_FLAG_DATA_STATUS) {
+   if (cmd-se_cmd.se_cmd_flags  SCF_OVERFLOW_BIT) {
+   hdr-flags |= ISCSI_FLAG_DATA_OVERFLOW;
+   hdr-residual_count = 
cpu_to_be32(cmd-se_cmd.residual_count);
+

[RFC-v4 6/9] iscsi-target: Refactor RX PDU logic + export request PDU handling

2013-04-12 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This patch refactors existing traditional iscsi RX side PDU handling
to use iscsit_transport, and exports the necessary logic for external
transport modules.

This includes:

- Refactor iscsit_handle_scsi_cmd() into PDU setup / processing
- Add updated iscsit_handle_scsi_cmd() for tradtional iscsi code
- Add iscsit_set_unsoliticed_dataout() wrapper
- Refactor iscsit_handle_data_out() into PDU check / processing
- Add updated iscsit_handle_data_out() for tradtional iscsi code
- Add iscsit_handle_nop_out() + iscsit_handle_task_mgt_cmd() to
  accept pre-allocated struct iscsi_cmd
- Add iscsit_build_r2ts_for_cmd() caller for iscsi_target_transport
  to handle ISTATE_SEND_R2T for TX immediate queue
- Refactor main traditional iscsi iscsi_target_rx_thread() PDU switch
  into iscsi_target_rx_opcode() using iscsit_allocate_cmd()
- Turn iscsi_target_rx_thread() process context into NOP for
  ib_isert side work-queue.

v3 changes:
- Add extra target_put_sess_cmd call in iscsit_add_reject_from_cmd
  after completion

v2 changes:

- Disable iscsit_ack_from_expstatsn() usage for RDMAExtentions=Yes
- Disable iscsit_allocate_datain_req() usage for RDMAExtentions=Yes
- Add target_get_sess_cmd() reference counting to
  iscsit_setup_scsi_cmd()
- Add TFO-lio_check_stop_free() fabric API caller
- Add export of iscsit_stop_dataout_timer() symbol
- Add iscsit_build_r2ts_for_cmd() for iscsit_transport-iscsit_get_dataout()
- Convert existing usage of iscsit_build_r2ts_for_cmd() to
  -iscsit_get_dataout()
- Drop RDMAExtentions=Yes specific check in iscsit_build_r2ts_for_cmd()
- Fix RDMAExtentions - RDMAExtensions typo (andy)
- Pass correct dump_payload value into iscsit_get_immediate_data()
  for iscsit_handle_scsi_cmd()

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/iscsi_target.c  |  486 --
 drivers/target/iscsi/iscsi_target.h  |3 +-
 drivers/target/iscsi/iscsi_target_configfs.c |9 +-
 drivers/target/iscsi/iscsi_target_erl1.c |   13 +-
 drivers/target/iscsi/iscsi_target_login.c|3 +-
 drivers/target/iscsi/iscsi_target_nego.c |   15 -
 drivers/target/iscsi/iscsi_target_tmr.c  |3 +-
 drivers/target/iscsi/iscsi_target_util.c |1 +
 8 files changed, 331 insertions(+), 202 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index b01a10e..19d4e08 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -492,6 +492,7 @@ static struct iscsit_transport iscsi_target_transport = {
.iscsit_alloc_cmd   = iscsit_alloc_cmd,
.iscsit_get_login_rx= iscsit_get_login_rx,
.iscsit_put_login_tx= iscsit_put_login_tx,
+   .iscsit_get_dataout = iscsit_build_r2ts_for_cmd,
 };
 
 static int __init iscsi_target_init_module(void)
@@ -650,6 +651,14 @@ static int iscsit_add_reject(
iscsit_add_cmd_to_response_queue(cmd, conn, cmd-i_state);
 
ret = wait_for_completion_interruptible(cmd-reject_comp);
+   /*
+* Perform the kref_put now if se_cmd has been setup by
+* iscsit_setup_scsi_cmd()
+*/
+   if (cmd-se_cmd.se_tfo != NULL) {
+   pr_debug(iscsi reject: calling target_put_sess_cmd \n);
+   target_put_sess_cmd(conn-sess-se_sess, cmd-se_cmd);
+   }
if (ret != 0)
return -1;
 
@@ -698,11 +707,20 @@ int iscsit_add_reject_from_cmd(
iscsit_add_cmd_to_response_queue(cmd, conn, cmd-i_state);
 
ret = wait_for_completion_interruptible(cmd-reject_comp);
+   /*
+* Perform the kref_put now if se_cmd has already been setup by
+* scsit_setup_scsi_cmd()
+*/
+   if (cmd-se_cmd.se_tfo != NULL) {
+   pr_debug(iscsi reject: calling target_put_sess_cmd \n);
+   target_put_sess_cmd(conn-sess-se_sess, cmd-se_cmd);
+   }
if (ret != 0)
return -1;
 
return (!fail_conn) ? 0 : -1;
 }
+EXPORT_SYMBOL(iscsit_add_reject_from_cmd);
 
 /*
  * Map some portion of the allocated scatterlist to an iovec, suitable for
@@ -761,6 +779,9 @@ static void iscsit_ack_from_expstatsn(struct iscsi_conn 
*conn, u32 exp_statsn)
 
conn-exp_statsn = exp_statsn;
 
+   if (conn-sess-sess_ops-RDMAExtensions)
+   return;
+
spin_lock_bh(conn-cmd_lock);
list_for_each_entry(cmd, conn-conn_cmd_list, i_conn_node) {
spin_lock(cmd-istate_lock);
@@ -793,12 +814,10 @@ static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd)
return 0;
 }
 
-static int iscsit_handle_scsi_cmd(
-   struct iscsi_conn *conn,
-   unsigned char *buf)
+int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
+ unsigned char *buf)
 {
-   int data_direction, payload_length, cmdsn_ret = 0, immed_ret;
-   struct iscsi_cmd *cmd = NULL;
+   int 

[RFC-v4 4/9] iscsi-target: Add iser-target parameter keys + setup during login

2013-04-12 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This patch adds RDMAExtensions, InitiatorRecvDataSegmentLength and
TargetRecvDataSegmentLength parameters keys necessary for iser-target
login to occur.

This includes setting the necessary parameters during login path
code within iscsi_login_zero_tsih_s2(), and currently PAGE_SIZE
aligning the target's advertised MRDSL for immediate data and
unsolicited data-out incoming payloads.

v3 changes:
- Add iscsi_post_login_start_timers FIXME for ISER

v2 changes:

- Fix RDMAExtentions - RDMAExtensions typo (andy)
- Drop unnecessary '== true' conditional checks for type bool

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/iscsi_target_core.h   |   10 +++
 drivers/target/iscsi/iscsi_target_login.c  |   77 
 drivers/target/iscsi/iscsi_target_parameters.c |   75 +--
 drivers/target/iscsi/iscsi_target_parameters.h |   16 +-
 4 files changed, 161 insertions(+), 17 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target_core.h 
b/drivers/target/iscsi/iscsi_target_core.h
index 2587677..53400b0 100644
--- a/drivers/target/iscsi/iscsi_target_core.h
+++ b/drivers/target/iscsi/iscsi_target_core.h
@@ -244,6 +244,11 @@ struct iscsi_conn_ops {
u8  IFMarker;   /* [0,1] == [No,Yes] */
u32 OFMarkInt;  /* [1..65535] */
u32 IFMarkInt;  /* [1..65535] */
+   /*
+* iSER specific connection parameters
+*/
+   u32 InitiatorRecvDataSegmentLength; /* [512..2**24-1] */
+   u32 TargetRecvDataSegmentLength;/* [512..2**24-1] */
 };
 
 struct iscsi_sess_ops {
@@ -265,6 +270,10 @@ struct iscsi_sess_ops {
u8  DataSequenceInOrder;/* [0,1] == [No,Yes] */
u8  ErrorRecoveryLevel; /* [0..2] */
u8  SessionType;/* [0,1] == [Normal,Discovery]*/
+   /*
+* iSER specific session parameters
+*/
+   u8  RDMAExtensions; /* [0,1] == [No,Yes] */
 };
 
 struct iscsi_queue_req {
@@ -284,6 +293,7 @@ struct iscsi_data_count {
 };
 
 struct iscsi_param_list {
+   booliser;
struct list_headparam_list;
struct list_headextra_response_list;
 };
diff --git a/drivers/target/iscsi/iscsi_target_login.c 
b/drivers/target/iscsi/iscsi_target_login.c
index 0de5c47..e6a8269 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -340,6 +340,7 @@ static int iscsi_login_zero_tsih_s2(
struct iscsi_node_attrib *na;
struct iscsi_session *sess = conn-sess;
unsigned char buf[32];
+   bool iser = false;
 
sess-tpg = conn-tpg;
 
@@ -361,7 +362,10 @@ static int iscsi_login_zero_tsih_s2(
return -1;
}
 
-   iscsi_set_keys_to_negotiate(0, conn-param_list);
+   if (conn-conn_transport-transport_type == ISCSI_INFINIBAND)
+   iser = true;
+
+   iscsi_set_keys_to_negotiate(conn-param_list, iser);
 
if (sess-sess_ops-SessionType)
return iscsi_set_keys_irrelevant_for_discovery(
@@ -399,6 +403,56 @@ static int iscsi_login_zero_tsih_s2(
 
if (iscsi_login_disable_FIM_keys(conn-param_list, conn)  0)
return -1;
+   /*
+* Set RDMAExtensions=Yes by default for iSER enabled network portals
+*/
+   if (iser) {
+   struct iscsi_param *param;
+   unsigned long mrdsl, off;
+   int rc;
+
+   sprintf(buf, RDMAExtensions=Yes);
+   if (iscsi_change_param_value(buf, conn-param_list, 0)  0) {
+   iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+   ISCSI_LOGIN_STATUS_NO_RESOURCES);
+   return -1;
+   }
+   /*
+* Make MaxRecvDataSegmentLength PAGE_SIZE aligned for
+* Immediate Data + Unsolicitied Data-OUT if necessary..
+*/
+   param = iscsi_find_param_from_key(MaxRecvDataSegmentLength,
+ conn-param_list);
+   if (!param) {
+   iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+   ISCSI_LOGIN_STATUS_NO_RESOURCES);
+   return -1;
+   }
+   rc = strict_strtoul(param-value, 0, mrdsl);
+   if (rc  0) {
+   iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+   ISCSI_LOGIN_STATUS_NO_RESOURCES);
+   return -1;
+   }
+   off = mrdsl % PAGE_SIZE;
+   if (!off)
+   return 0;
+
+   if (mrdsl  PAGE_SIZE)
+   mrdsl = PAGE_SIZE;
+   

[RFC-v4 2/9] iscsi-target: Add iscsit_transport API template

2013-04-12 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

Add basic struct iscsit_transport API template to allow iscsi-target for
running with external transport modules using existing iscsi_target_core.h
code.

For all external modules, this calls try_module_get() and module_put()
to obtain + release an external iscsit_transport module reference count.

Also include the iscsi-target symbols necessary in iscsi_transport.h to
allow external transport modules to function.

v3 changes:
- Add iscsit_build_reject export for ISTATE_SEND_REJECT usage

v2 changes:

- Drop unnecessary export of iscsit_get_transport + iscsit_put_transport 
(roland)
- Add -iscsit_queue_data_in() to remove extra context switch on RDMA_WRITE
- Add -iscsit_queue_status() to remove extra context switch on IB_SEND status
- Add -iscsit_get_dataout() to remove extra context switch on RDMA_READ
- Drop -iscsit_free_cmd()
- Drop -iscsit_unmap_cmd()
- Rename iscsit_create_transport() - iscsit_register_transport() (andy)
- Rename iscsit_destroy_transport() - iscsit_unregister_transport() (andy)

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/Makefile |3 +-
 drivers/target/iscsi/iscsi_target_transport.c |   55 
 include/target/iscsi/iscsi_transport.h|   83 +
 3 files changed, 140 insertions(+), 1 deletions(-)
 create mode 100644 drivers/target/iscsi/iscsi_target_transport.c
 create mode 100644 include/target/iscsi/iscsi_transport.h

diff --git a/drivers/target/iscsi/Makefile b/drivers/target/iscsi/Makefile
index 5b9a2cf..13a9240 100644
--- a/drivers/target/iscsi/Makefile
+++ b/drivers/target/iscsi/Makefile
@@ -15,6 +15,7 @@ iscsi_target_mod-y += iscsi_target_parameters.o \
iscsi_target_util.o \
iscsi_target.o \
iscsi_target_configfs.o \
-   iscsi_target_stat.o
+   iscsi_target_stat.o \
+   iscsi_target_transport.o
 
 obj-$(CONFIG_ISCSI_TARGET) += iscsi_target_mod.o
diff --git a/drivers/target/iscsi/iscsi_target_transport.c 
b/drivers/target/iscsi/iscsi_target_transport.c
new file mode 100644
index 000..882728f
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_transport.c
@@ -0,0 +1,55 @@
+#include linux/spinlock.h
+#include linux/list.h
+#include target/iscsi/iscsi_transport.h
+
+static LIST_HEAD(g_transport_list);
+static DEFINE_MUTEX(transport_mutex);
+
+struct iscsit_transport *iscsit_get_transport(int type)
+{
+   struct iscsit_transport *t;
+
+   mutex_lock(transport_mutex);
+   list_for_each_entry(t, g_transport_list, t_node) {
+   if (t-transport_type == type) {
+   if (t-owner  !try_module_get(t-owner)) {
+   t = NULL;
+   }
+   mutex_unlock(transport_mutex);
+   return t;
+   }
+   }
+   mutex_unlock(transport_mutex);
+
+   return NULL;
+}
+
+void iscsit_put_transport(struct iscsit_transport *t)
+{
+   if (t-owner)
+   module_put(t-owner);
+}
+
+int iscsit_register_transport(struct iscsit_transport *t)
+{
+   INIT_LIST_HEAD(t-t_node);
+
+   mutex_lock(transport_mutex);
+   list_add_tail(t-t_node, g_transport_list);
+   mutex_unlock(transport_mutex);
+
+   pr_debug(Registered iSCSI transport: %s\n, t-name);
+
+   return 0;
+}
+EXPORT_SYMBOL(iscsit_register_transport);
+
+void iscsit_unregister_transport(struct iscsit_transport *t)
+{
+   mutex_lock(transport_mutex);
+   list_del(t-t_node);
+   mutex_unlock(transport_mutex);
+
+   pr_debug(Unregistered iSCSI transport: %s\n, t-name);
+}
+EXPORT_SYMBOL(iscsit_unregister_transport);
diff --git a/include/target/iscsi/iscsi_transport.h 
b/include/target/iscsi/iscsi_transport.h
new file mode 100644
index 000..23a87d0
--- /dev/null
+++ b/include/target/iscsi/iscsi_transport.h
@@ -0,0 +1,83 @@
+#include linux/module.h
+#include linux/list.h
+#include ../../../drivers/target/iscsi/iscsi_target_core.h
+
+struct iscsit_transport {
+#define ISCSIT_TRANSPORT_NAME  16
+   char name[ISCSIT_TRANSPORT_NAME];
+   int transport_type;
+   struct module *owner;
+   struct list_head t_node;
+   int (*iscsit_setup_np)(struct iscsi_np *, struct 
__kernel_sockaddr_storage *);
+   int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *);
+   void (*iscsit_free_np)(struct iscsi_np *);
+   void (*iscsit_free_conn)(struct iscsi_conn *);
+   struct iscsi_cmd *(*iscsit_alloc_cmd)(struct iscsi_conn *, gfp_t);
+   int (*iscsit_get_login_rx)(struct iscsi_conn *, struct iscsi_login *);
+   int (*iscsit_put_login_tx)(struct iscsi_conn *, struct iscsi_login *, 
u32);
+   int (*iscsit_immediate_queue)(struct iscsi_conn *, struct iscsi_cmd *, 
int);
+   int