Re: [PATCH 0/9] block/scsi: Implement SMR drive support
On 04/08/2016 08:35 PM, Shaun Tancheff wrote: On Mon, Apr 4, 2016 at 5:00 PM, Hannes Reinecke wrote: Hi all, here's a patchset implementing SMR (shingled magnetic recording) device support for the block and SCSI layer. There are two main parts to it: - mapping the 'RESET WRITE POINTER' command to the 'discard' functionality. The 'RESET WRITE POINTER' operation is pretty close to the existing 'discard' functionality with the 'discard_zeroes_blocks' bit set. So I've added a new 'reset_wp' provisioning mode for this. Completely agree with the REQ_OP_DISCARD -> Reset WP translation seems like a good idea. I have tried something similar and ended up essentially adding a 'reset wp' flag instead. Now I am optimistic to see if I can use you patch to get the discard -> reset wp working in my device mapper. It works quite well here with my setup, although I've tripped across two caveats: - We currently don't handle conventional zones. It would make sense to fallback to normal block zeroing here. - Issuing 'RESET WP' is dead slow (at least on the prototypes I've had) Short-circuiting it for empty zones is a _major_ performance win here; the time for issuing discards for an entire drive is reduced by several orders of magnitude. So you absolutely need an in-kernel zone tree for this. - Adding a 'zone' pointer to the request queue. This pointer holds an RB-tree with the zone information, which can be used by other layers to access the write pointer. Here is where I have some concerns. Having a common in-kernel shadow of the drive's zone state seems problematic to me. Well, this is the general SMR programming model, is it not? And as already pointed out above you really want this tree to be present to avoid unnecessary RESET WP calls. You also need it to format READ calls correctly for host-managed drives; from my understanding of the programming model any READ call crossing the write pointer will be aborted. Which you could easily circumvent by splitting the READ call in two parts, one up to the read pointer and another beyond it. For which again you need the zone tree. Also if I am understanding the direction here it is to hold the zone information in an rbtree. Since that comes to just under 30,000 entries I think it would be better to shift to an array of write pointer offsets. The thing is that using an rbtree might actually be faster than an array; the rbtree entries easily fit into the processor cache, whereas the array doesn't. So you might end up having a slower access when using arrays despite being easier to code. At the moment my translation layer keeps track of activity and state of all the zones on the drive so that is how I have been handling the zone data up to this point. As outlined above: Any driver/filesystem need access to the zone states as it might need to align its internal structures to the zones. But you also need to keep track of the zones in the SCSI layer so as to format the RESET WP correctly. Which means you basically need a common tree. As you might've seen I've also programmed my own zoned device-mapper device, caching individual zones. We should discuss if those two approached can't be merged, to end up with a common device-mapper target. Cheers, Hannes -- Dr. Hannes Reinecke zSeries & Storage h...@suse.de +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC 14/34] iscsi-target: export symbols
On Fri, Apr 08, 2016 at 12:16:43AM -0700, Nicholas A. Bellinger wrote: > On Sun, 2016-03-13 at 17:43 +0530, Varun Prakash wrote: > > On Fri, Mar 11, 2016 at 10:28:33PM -0800, Nicholas A. Bellinger wrote: > > > Hi Varun & Co, > > > > > > On Mon, 2016-03-07 at 15:22 -0800, Nicholas A. Bellinger wrote: > > > > > > > > > > > > The drivers/net/ethernet/chelsio/cxgb4/ prerequisites for supporting > > > iscsi segment offload (ISO) + page pod manager (PPM) are in > > > target-pending/for-next-merge, and patches #13+ have been dropped > > > for initial v4.6-rc1 merge. > > > > > > Also, there haven't been any further linux-next subsystem merge failures > > > beyond the initial t4fw_api.h conflict as reported by SFR. > > > > > > https://lkml.org/lkml/2016/2/29/34 > > > > > > So please go ahead and post stand-alone cxgb4 driver changes for > > > initial ISO + PPM to net-dev + target-devel, and Hariprasad should > > > review + ack these ASAP. > > > > Yes, I will post cxgb4 patch series, thanks. > > Great. Just curious how -v2 is coming along..? > > I've got a few cycles over the weekend, and plan to start reviewing as > the series hits the list. > I will post v2 series today, thanks. > Btw, I asked Sagi to help out with review as well. > -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 02/16] iscsi-target: add int (*iscsit_xmit_pdu)()
Add int (*iscsit_xmit_pdu)() to struct iscsit_transport, iscsi-target uses this callback to transmit an iSCSI PDU. Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target.c| 391 + include/target/iscsi/iscsi_transport.h | 2 + 2 files changed, 102 insertions(+), 291 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index fdb33ba..0e7a481 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -504,6 +504,79 @@ static void *iscsit_alloc_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd) return cmd->pdu; } +static void iscsit_do_crypto_hash_buf(struct ahash_request *, const void *, + u32, u32, u8 *, u8 *); +static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *); + +static int iscsit_xmit_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd, + const void *data_buf, u32 data_buf_len) +{ + struct iscsi_hdr *hdr = (struct iscsi_hdr *)cmd->pdu; + struct kvec *iov; + u32 niov = 0, tx_size = ISCSI_HDR_LEN; + int ret; + + iov = &cmd->iov_misc[0]; + iov[niov].iov_base = cmd->pdu; + iov[niov++].iov_len = ISCSI_HDR_LEN; + + if (conn->conn_ops->HeaderDigest) { + u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; + + iscsit_do_crypto_hash_buf(conn->conn_tx_hash, hdr, + ISCSI_HDR_LEN, 0, NULL, + (u8 *)header_digest); + + iov[0].iov_len += ISCSI_CRC_LEN; + tx_size += ISCSI_CRC_LEN; + pr_debug("Attaching CRC32C HeaderDigest" +" to opcode 0x%x 0x%08x\n", +hdr->opcode, *header_digest); + } + + if (data_buf_len) { + u32 padding = ((-data_buf_len) & 3); + + iov[niov].iov_base = (void *)data_buf; + iov[niov++].iov_len = data_buf_len; + tx_size += data_buf_len; + + if (padding != 0) { + iov[niov].iov_base = &cmd->pad_bytes; + iov[niov++].iov_len = padding; + tx_size += padding; + pr_debug("Attaching %u additional" +" padding bytes.\n", padding); + } + + if (conn->conn_ops->DataDigest) { + iscsit_do_crypto_hash_buf(conn->conn_tx_hash, + data_buf, data_buf_len, + padding, + (u8 *)&cmd->pad_bytes, + (u8 *)&cmd->data_crc); + + iov[niov].iov_base = &cmd->data_crc; + iov[niov++].iov_len = ISCSI_CRC_LEN; + tx_size += ISCSI_CRC_LEN; + pr_debug("Attached DataDigest for %u" +" bytes opcode 0x%x, CRC 0x%08x\n", +data_buf_len, hdr->opcode, cmd->data_crc); + } + } + + cmd->iov_misc_count = niov; + cmd->tx_size = tx_size; + + ret = iscsit_send_tx_data(cmd, conn, 1); + if (ret < 0) { + iscsit_tx_thread_wait_for_tcp(conn); + return ret; + } + + return 0; +} + static enum target_prot_op iscsit_get_sup_prot_ops(struct iscsi_conn *conn) { return TARGET_PROT_NORMAL; @@ -525,6 +598,7 @@ static struct iscsit_transport iscsi_target_transport = { .iscsit_queue_status= iscsit_queue_rsp, .iscsit_aborted_task= iscsit_aborted_task, .iscsit_alloc_pdu = iscsit_alloc_pdu, + .iscsit_xmit_pdu= iscsit_xmit_pdu, .iscsit_get_sup_prot_ops = iscsit_get_sup_prot_ops, }; @@ -2540,7 +2614,6 @@ static int iscsit_send_conn_drop_async_message( { struct iscsi_async *hdr; - cmd->tx_size = ISCSI_HDR_LEN; cmd->iscsi_opcode = ISCSI_OP_ASYNC_EVENT; hdr = conn->conn_transport->iscsit_alloc_pdu(conn, cmd); @@ -2561,25 +2634,11 @@ static int iscsit_send_conn_drop_async_message( hdr->param2 = cpu_to_be16(conn->sess->sess_ops->DefaultTime2Wait); hdr->param3 = cpu_to_be16(conn->sess->sess_ops->DefaultTime2Retain); - if (conn->conn_ops->HeaderDigest) { - u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; - - iscsit_do_crypto_hash_buf(conn->conn_tx_hash, hdr, - ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); - - cmd->tx_size += ISCSI_CRC_LEN; - pr_debug("Attaching CRC32C HeaderDigest to" - " Async Message 0x%08x\n", *header_digest); - } - - cmd->iov_misc[0].iov_base
[PATCH v2 00/16] Chelsio iSCSI target offload driver
This is v2 patch series for Chelsio iSCSI target offload driver(cxgbit.ko). cxgbit.ko registers with iSCSI target transport and offloads multiple CPU intensive tasks to Chelsio T5 adapters. T5 adapters has following offload features for iSCSI -TCP/IP offload -iSCSI PDU recovery by reassembling TCP segments. -Header and Data Digest offload. -iSCSI segmentation offload(ISO). -Direct Data Placement(DDP). -v2 - added hw offload transport type (Nicholas). - added PDU alloc, free, xmit callbacks (Nicholas). - created single patch for all cxgbit.ko files (Nicholas). - merged definition and usage of int (*iscsit_validate_params)() in a single patch (Christoph). - merged definition and usage of void (*iscsit_release_cmd)() in a single patch (Christoph). - renamed void (*iscsit_rx_pdu)() to void (*iscsit_get_rx_pdu)() (Sagi). - added dependency on INET in Kconfig (Arnd). - added check for NULL sg in cxgbit_set_one_ppod() (Dan Carpenter). Please review. Thanks Varun Prakash (16): iscsi-target: add callback to alloc and free PDU iscsi-target: add int (*iscsit_xmit_pdu)() iscsi-target: add int (*iscsit_xmit_datain_pdu)() iscsi-target: add void (*iscsit_release_cmd)() iscsi-target: add void (*iscsit_get_rx_pdu)() iscsi-target: split iscsi_target_rx_thread() iscsi-target: add int (*iscsit_validate_params)() iscsi-target: add void (*iscsit_get_r2t_ttt)() iscsi-target: move iscsit_thread_check_cpumask() iscsi-target: use conn->network_transport in text rsp iscsi-target: add new offload transport type iscsi-target: clear tx_thread_active iscsi-target: call complete on conn_logout_comp iscsi-target: export symbols iscsi-target: fix seq_end_offset calculation cxgbit: add files for cxgbit.ko drivers/infiniband/ulp/isert/ib_isert.c | 10 + drivers/target/iscsi/Kconfig |2 + drivers/target/iscsi/Makefile |1 + drivers/target/iscsi/cxgbit/Kconfig |7 + drivers/target/iscsi/cxgbit/Makefile |6 + drivers/target/iscsi/cxgbit/cxgbit.h | 358 drivers/target/iscsi/cxgbit/cxgbit_cm.c | 2086 + drivers/target/iscsi/cxgbit/cxgbit_ddp.c | 325 drivers/target/iscsi/cxgbit/cxgbit_lro.h | 72 + drivers/target/iscsi/cxgbit/cxgbit_main.c | 703 +++ drivers/target/iscsi/cxgbit/cxgbit_target.c | 1601 drivers/target/iscsi/iscsi_target.c | 740 +++- drivers/target/iscsi/iscsi_target_configfs.c | 76 + drivers/target/iscsi/iscsi_target_datain_values.c |1 + drivers/target/iscsi/iscsi_target_erl0.c |6 +- drivers/target/iscsi/iscsi_target_login.c | 13 +- drivers/target/iscsi/iscsi_target_nego.c |1 + drivers/target/iscsi/iscsi_target_parameters.c|1 + drivers/target/iscsi/iscsi_target_util.c |5 + include/target/iscsi/iscsi_target_core.h | 27 + include/target/iscsi/iscsi_transport.h| 45 + 21 files changed, 5648 insertions(+), 438 deletions(-) create mode 100644 drivers/target/iscsi/cxgbit/Kconfig create mode 100644 drivers/target/iscsi/cxgbit/Makefile create mode 100644 drivers/target/iscsi/cxgbit/cxgbit.h create mode 100644 drivers/target/iscsi/cxgbit/cxgbit_cm.c create mode 100644 drivers/target/iscsi/cxgbit/cxgbit_ddp.c create mode 100644 drivers/target/iscsi/cxgbit/cxgbit_lro.h create mode 100644 drivers/target/iscsi/cxgbit/cxgbit_main.c create mode 100644 drivers/target/iscsi/cxgbit/cxgbit_target.c -- 2.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 01/16] iscsi-target: add callback to alloc and free PDU
Add two callbacks to struct iscsit_transport - 1. void *(*iscsit_alloc_pdu)() iscsi-target uses this callback for iSCSI PDU allocation. 2. void (*iscsit_free_pdu) iscsi-target uses this callback to free an iSCSI PDU which was allocated by iscsit_alloc_pdu(). Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target.c| 76 -- include/target/iscsi/iscsi_transport.h | 2 + 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 961202f..fdb33ba 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -499,6 +499,11 @@ static void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd) __iscsit_free_cmd(cmd, scsi_cmd, true); } +static void *iscsit_alloc_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd) +{ + return cmd->pdu; +} + static enum target_prot_op iscsit_get_sup_prot_ops(struct iscsi_conn *conn) { return TARGET_PROT_NORMAL; @@ -519,6 +524,7 @@ static struct iscsit_transport iscsi_target_transport = { .iscsit_queue_data_in = iscsit_queue_rsp, .iscsit_queue_status= iscsit_queue_rsp, .iscsit_aborted_task= iscsit_aborted_task, + .iscsit_alloc_pdu = iscsit_alloc_pdu, .iscsit_get_sup_prot_ops = iscsit_get_sup_prot_ops, }; @@ -2537,7 +2543,10 @@ static int iscsit_send_conn_drop_async_message( cmd->tx_size = ISCSI_HDR_LEN; cmd->iscsi_opcode = ISCSI_OP_ASYNC_EVENT; - hdr = (struct iscsi_async *) cmd->pdu; + hdr = conn->conn_transport->iscsit_alloc_pdu(conn, cmd); + if (unlikely(!hdr)) + return -ENOMEM; + hdr->opcode = ISCSI_OP_ASYNC_EVENT; hdr->flags = ISCSI_FLAG_CMD_FINAL; cmd->init_task_tag = RESERVED_ITT; @@ -2630,7 +2639,7 @@ iscsit_build_datain_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn, static int iscsit_send_datain(struct iscsi_cmd *cmd, struct iscsi_conn *conn) { - struct iscsi_data_rsp *hdr = (struct iscsi_data_rsp *)&cmd->pdu[0]; + struct iscsi_data_rsp *hdr; struct iscsi_datain datain; struct iscsi_datain_req *dr; struct kvec *iov; @@ -2675,6 +2684,10 @@ static int iscsit_send_datain(struct iscsi_cmd *cmd, struct iscsi_conn *conn) set_statsn = true; } + hdr = conn->conn_transport->iscsit_alloc_pdu(conn, cmd); + if (unlikely(!hdr)) + return -ENOMEM; + iscsit_build_datain_pdu(cmd, conn, &datain, hdr, set_statsn); iov = &cmd->iov_data[0]; @@ -2843,13 +2856,20 @@ EXPORT_SYMBOL(iscsit_build_logout_rsp); static int iscsit_send_logout(struct iscsi_cmd *cmd, struct iscsi_conn *conn) { + struct iscsi_logout_rsp *hdr; struct kvec *iov; int niov = 0, tx_size, rc; - rc = iscsit_build_logout_rsp(cmd, conn, - (struct iscsi_logout_rsp *)&cmd->pdu[0]); - if (rc < 0) + hdr = conn->conn_transport->iscsit_alloc_pdu(conn, cmd); + if (unlikely(!hdr)) + return -ENOMEM; + + rc = iscsit_build_logout_rsp(cmd, conn, hdr); + if (rc < 0) { + if (conn->conn_transport->iscsit_free_pdu) + conn->conn_transport->iscsit_free_pdu(conn, cmd); return rc; + } tx_size = ISCSI_HDR_LEN; iov = &cmd->iov_misc[0]; @@ -2909,9 +2929,13 @@ static int iscsit_send_unsolicited_nopin( struct iscsi_conn *conn, int want_response) { - struct iscsi_nopin *hdr = (struct iscsi_nopin *)&cmd->pdu[0]; + struct iscsi_nopin *hdr; int tx_size = ISCSI_HDR_LEN, ret; + hdr = conn->conn_transport->iscsit_alloc_pdu(conn, cmd); + if (unlikely(!hdr)) + return -ENOMEM; + iscsit_build_nopin_rsp(cmd, conn, hdr, false); if (conn->conn_ops->HeaderDigest) { @@ -2950,11 +2974,15 @@ static int iscsit_send_unsolicited_nopin( static int iscsit_send_nopin(struct iscsi_cmd *cmd, struct iscsi_conn *conn) { - struct iscsi_nopin *hdr = (struct iscsi_nopin *)&cmd->pdu[0]; + struct iscsi_nopin *hdr; struct kvec *iov; u32 padding = 0; int niov = 0, tx_size; + hdr = conn->conn_transport->iscsit_alloc_pdu(conn, cmd); + if (unlikely(!hdr)) + return -ENOMEM; + iscsit_build_nopin_rsp(cmd, conn, hdr, true); tx_size = ISCSI_HDR_LEN; @@ -3028,7 +3056,10 @@ static int iscsit_send_r2t( if (!r2t) return -1; - hdr = (struct iscsi_r2t_rsp *) cmd->pdu; + hdr = conn->conn_transport->iscsit_alloc_pdu(conn, cmd); + if (unlikely(!hdr)) + return -ENOMEM; + memset(hdr, 0, ISCSI_HDR_LEN); hdr->opcode = ISCSI_OP_R2T; hdr->flag
[PATCH v2 05/16] iscsi-target: add void (*iscsit_get_rx_pdu)()
Add void (*iscsit_get_rx_pdu)() to struct iscsit_transport, iscsi-target uses this callback to receive and process Rx iSCSI PDUs. Signed-off-by: Varun Prakash --- drivers/infiniband/ulp/isert/ib_isert.c | 10 ++ drivers/target/iscsi/iscsi_target.c | 10 ++ include/target/iscsi/iscsi_transport.h | 1 + 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 411e446..9118d7c 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -3273,6 +3273,15 @@ static void isert_free_conn(struct iscsi_conn *conn) isert_put_conn(isert_conn); } +static void isert_get_rx_pdu(struct iscsi_conn *conn) +{ + struct completion comp; + + init_completion(&comp); + + wait_for_completion_interruptible(&comp); +} + static struct iscsit_transport iser_target_transport = { .name = "IB/iSER", .transport_type = ISCSI_INFINIBAND, @@ -3291,6 +3300,7 @@ static struct iscsit_transport iser_target_transport = { .iscsit_queue_data_in = isert_put_datain, .iscsit_queue_status= isert_put_response, .iscsit_aborted_task= isert_aborted_task, + .iscsit_get_rx_pdu = isert_get_rx_pdu, .iscsit_get_sup_prot_ops = isert_get_sup_prot_ops, }; diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 9e65e5d..4311636 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -3989,14 +3989,8 @@ int iscsi_target_rx_thread(void *arg) if (rc < 0 || iscsi_target_check_conn_state(conn)) return 0; - if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) { - struct completion comp; - - init_completion(&comp); - rc = wait_for_completion_interruptible(&comp); - if (rc < 0) - goto transport_err; - + if (conn->conn_transport->iscsit_get_rx_pdu) { + conn->conn_transport->iscsit_get_rx_pdu(conn); goto transport_err; } diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h index 19cef94..1f63d8c 100644 --- a/include/target/iscsi/iscsi_transport.h +++ b/include/target/iscsi/iscsi_transport.h @@ -30,6 +30,7 @@ struct iscsit_transport { struct iscsi_datain_req *, struct iscsi_datain *); void (*iscsit_release_cmd)(struct iscsi_conn *, struct iscsi_cmd *); + void (*iscsit_get_rx_pdu)(struct iscsi_conn *); enum target_prot_op (*iscsit_get_sup_prot_ops)(struct iscsi_conn *); }; -- 2.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 06/16] iscsi-target: split iscsi_target_rx_thread()
split iscsi_target_rx_thread() into two parts, 1. iscsi_target_rx_thread() is common to all transport drivers, it will call Rx function registered by transport driver. 2. iscsit_get_rx_pdu() is Rx function for ISCSI_TCP transport. Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target.c | 59 + 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 4311636..98d96d4 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -480,6 +480,7 @@ int iscsit_del_np(struct iscsi_np *np) 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 void iscsit_get_rx_pdu(struct iscsi_conn *); static int iscsit_queue_rsp(struct iscsi_conn *conn, struct iscsi_cmd *cmd) { @@ -678,6 +679,7 @@ static struct iscsit_transport iscsi_target_transport = { .iscsit_alloc_pdu = iscsit_alloc_pdu, .iscsit_xmit_pdu= iscsit_xmit_pdu, .iscsit_xmit_datain_pdu = iscsit_xmit_datain_pdu, + .iscsit_get_rx_pdu = iscsit_get_rx_pdu, .iscsit_get_sup_prot_ops = iscsit_get_sup_prot_ops, }; @@ -3969,30 +3971,12 @@ static bool iscsi_target_check_conn_state(struct iscsi_conn *conn) return ret; } -int iscsi_target_rx_thread(void *arg) +static void iscsit_get_rx_pdu(struct iscsi_conn *conn) { - int ret, rc; + int ret; u8 buffer[ISCSI_HDR_LEN], opcode; u32 checksum = 0, digest = 0; - struct iscsi_conn *conn = arg; struct kvec iov; - /* -* Allow ourselves to be interrupted by SIGINT so that a -* connection recovery / failure event can be triggered externally. -*/ - allow_signal(SIGINT); - /* -* Wait for iscsi_post_login_handler() to complete before allowing -* incoming iscsi/tcp socket I/O, and/or failing the connection. -*/ - rc = wait_for_completion_interruptible(&conn->rx_login_comp); - if (rc < 0 || iscsi_target_check_conn_state(conn)) - return 0; - - if (conn->conn_transport->iscsit_get_rx_pdu) { - conn->conn_transport->iscsit_get_rx_pdu(conn); - goto transport_err; - } while (!kthread_should_stop()) { /* @@ -4010,7 +3994,7 @@ int iscsi_target_rx_thread(void *arg) ret = rx_data(conn, &iov, 1, ISCSI_HDR_LEN); if (ret != ISCSI_HDR_LEN) { iscsit_rx_thread_wait_for_tcp(conn); - goto transport_err; + return; } if (conn->conn_ops->HeaderDigest) { @@ -4020,7 +4004,7 @@ int iscsi_target_rx_thread(void *arg) ret = rx_data(conn, &iov, 1, ISCSI_CRC_LEN); if (ret != ISCSI_CRC_LEN) { iscsit_rx_thread_wait_for_tcp(conn); - goto transport_err; + return; } iscsit_do_crypto_hash_buf(conn->conn_rx_hash, @@ -4044,7 +4028,7 @@ int iscsi_target_rx_thread(void *arg) } if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) - goto transport_err; + return; opcode = buffer[0] & ISCSI_OPCODE_MASK; @@ -4055,15 +4039,38 @@ int iscsi_target_rx_thread(void *arg) " while in Discovery Session, rejecting.\n", opcode); iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, buffer); - goto transport_err; + return; } ret = iscsi_target_rx_opcode(conn, buffer); if (ret < 0) - goto transport_err; + return; } +} + +int iscsi_target_rx_thread(void *arg) +{ + int rc; + struct iscsi_conn *conn = arg; + + /* +* Allow ourselves to be interrupted by SIGINT so that a +* connection recovery / failure event can be triggered externally. +*/ + allow_signal(SIGINT); + /* +* Wait for iscsi_post_login_handler() to complete before allowing +* incoming iscsi/tcp socket I/O, and/or failing the connection. +*/ + rc = wait_for_completion_interruptible(&conn->rx_login_comp); + if (rc < 0 || iscsi_target_check_conn_state(conn)) + return 0; + + if (!conn->conn_transport->iscsit_get_rx_pdu) + return 0; + + conn->conn_transport->iscsit_get_rx_pdu(conn); -transport_err: if (!signal_pending(current)) atomic_set(&conn->transport_failed, 1); iscsit_
[PATCH v2 12/16] iscsi-target: clear tx_thread_active
clear tx_thread_active for ISCSI_HW_OFFLOAD transport in logout_post_handler functions. Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index e61249d..959644f 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -4417,7 +4417,8 @@ static void iscsit_logout_post_handler_closesession( * always sleep waiting for RX/TX thread shutdown to complete * within iscsit_close_connection(). */ - if (conn->conn_transport->transport_type == ISCSI_TCP) + if ((conn->conn_transport->transport_type == ISCSI_TCP) || + (conn->conn_transport->transport_type == ISCSI_HW_OFFLOAD)) sleep = cmpxchg(&conn->tx_thread_active, true, false); atomic_set(&conn->conn_logout_remove, 0); @@ -4434,7 +4435,8 @@ static void iscsit_logout_post_handler_samecid( { int sleep = 1; - if (conn->conn_transport->transport_type == ISCSI_TCP) + if ((conn->conn_transport->transport_type == ISCSI_TCP) || + (conn->conn_transport->transport_type == ISCSI_HW_OFFLOAD)) sleep = cmpxchg(&conn->tx_thread_active, true, false); atomic_set(&conn->conn_logout_remove, 0); -- 2.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 14/16] iscsi-target: export symbols
export symbols for ISCSI_HW_OFFLOAD transport drivers. Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target.c | 25 ++--- drivers/target/iscsi/iscsi_target_datain_values.c | 1 + drivers/target/iscsi/iscsi_target_login.c | 3 ++- drivers/target/iscsi/iscsi_target_nego.c | 1 + drivers/target/iscsi/iscsi_target_parameters.c| 1 + drivers/target/iscsi/iscsi_target_util.c | 2 ++ include/target/iscsi/iscsi_transport.h| 33 +++ 7 files changed, 56 insertions(+), 10 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index edce5af..941f676 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -478,17 +478,16 @@ 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 void iscsit_get_rx_pdu(struct iscsi_conn *); -static int iscsit_queue_rsp(struct iscsi_conn *conn, struct iscsi_cmd *cmd) +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; } +EXPORT_SYMBOL(iscsit_queue_rsp); -static void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd) +void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd) { bool scsi_cmd = (cmd->iscsi_opcode == ISCSI_OP_SCSI_CMD); @@ -499,6 +498,7 @@ static void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd) __iscsit_free_cmd(cmd, scsi_cmd, true); } +EXPORT_SYMBOL(iscsit_aborted_task); static void *iscsit_alloc_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd) { @@ -795,7 +795,7 @@ static void __exit iscsi_target_cleanup_module(void) kfree(iscsit_global); } -static int iscsit_add_reject( +int iscsit_add_reject( struct iscsi_conn *conn, u8 reason, unsigned char *buf) @@ -825,6 +825,7 @@ static int iscsit_add_reject( return -1; } +EXPORT_SYMBOL(iscsit_add_reject); static int iscsit_add_reject_from_cmd( struct iscsi_cmd *cmd, @@ -880,6 +881,7 @@ int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8 reason, unsigned char *buf) { return iscsit_add_reject_from_cmd(cmd, reason, false, buf); } +EXPORT_SYMBOL(iscsit_reject_cmd); /* * Map some portion of the allocated scatterlist to an iovec, suitable for @@ -2496,7 +2498,7 @@ iscsit_handle_logout_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, } EXPORT_SYMBOL(iscsit_handle_logout_cmd); -static int iscsit_handle_snack( +int iscsit_handle_snack( struct iscsi_conn *conn, unsigned char *buf) { @@ -2549,6 +2551,7 @@ static int iscsit_handle_snack( return 0; } +EXPORT_SYMBOL(iscsit_handle_snack); static void iscsit_rx_thread_wait_for_tcp(struct iscsi_conn *conn) { @@ -2732,7 +2735,7 @@ static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn) } } -static void +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) @@ -2776,6 +2779,7 @@ iscsit_build_datain_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn, cmd->init_task_tag, ntohl(hdr->statsn), ntohl(hdr->datasn), ntohl(hdr->offset), datain->length, conn->cid); } +EXPORT_SYMBOL(iscsit_build_datain_pdu); static int iscsit_send_datain(struct iscsi_cmd *cmd, struct iscsi_conn *conn) { @@ -3174,6 +3178,7 @@ int iscsit_build_r2ts_for_cmd( return 0; } +EXPORT_SYMBOL(iscsit_build_r2ts_for_cmd); void iscsit_build_rsp_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn, bool inc_stat_sn, struct iscsi_scsi_rsp *hdr) @@ -3619,7 +3624,7 @@ void iscsit_thread_get_cpumask(struct iscsi_conn *conn) cpumask_setall(conn->conn_cpumask); } -static int +int iscsit_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) { int ret; @@ -3661,6 +3666,7 @@ iscsit_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state err: return -1; } +EXPORT_SYMBOL(iscsit_immediate_queue); static int iscsit_handle_immediate_queue(struct iscsi_conn *conn) @@ -3685,7 +3691,7 @@ iscsit_handle_immediate_queue(struct iscsi_conn *conn) return 0; } -static int +int iscsit_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) { int ret; @@ -3790,6 +3796,7 @@ check_rsp_state: err: return -1; } +EXPORT_SYMBOL(iscsit_response_queue); static int iscsit_handle_response_queue(struct iscsi_conn *conn) { diff --git a/drivers/target/iscsi/iscsi_target_datain_values.c b/drivers/target/iscsi/iscsi_target_datain_values.c index f
[PATCH v2 07/16] iscsi-target: add int (*iscsit_validate_params)()
Add int (*iscsit_validate_params)() to struct iscsit_transport, iscsi-target uses this callback for validating conn operational parameters. Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target_login.c | 10 ++ include/target/iscsi/iscsi_transport.h| 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 8436d56..83574eea 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -1387,6 +1387,16 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) goto old_sess_out; } + if (conn->conn_transport->iscsit_validate_params) { + ret = conn->conn_transport->iscsit_validate_params(conn); + if (ret < 0) { + if (zero_tsih) + goto new_sess_out; + else + goto old_sess_out; + } + } + ret = iscsi_target_start_negotiation(login, conn); if (ret < 0) goto new_sess_out; diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h index 1f63d8c..dbef892 100644 --- a/include/target/iscsi/iscsi_transport.h +++ b/include/target/iscsi/iscsi_transport.h @@ -31,6 +31,7 @@ struct iscsit_transport { struct iscsi_datain *); void (*iscsit_release_cmd)(struct iscsi_conn *, struct iscsi_cmd *); void (*iscsit_get_rx_pdu)(struct iscsi_conn *); + int (*iscsit_validate_params)(struct iscsi_conn *); enum target_prot_op (*iscsit_get_sup_prot_ops)(struct iscsi_conn *); }; -- 2.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 03/16] iscsi-target: add int (*iscsit_xmit_datain_pdu)()
Add int (*iscsit_xmit_datain_pdu)() to struct iscsit_transport, iscsi-target uses this callback to transmit a DATAIN iSCSI PDU. Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target.c| 143 +++-- include/target/iscsi/iscsi_transport.h | 3 + 2 files changed, 86 insertions(+), 60 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 0e7a481..9e65e5d 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -577,6 +577,84 @@ static int iscsit_xmit_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd, return 0; } +static int iscsit_map_iovec(struct iscsi_cmd *, struct kvec *, u32, u32); +static void iscsit_unmap_iovec(struct iscsi_cmd *); +static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsi_cmd *, + u32, u32, u32, u8 *); +static int +iscsit_xmit_datain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd, + struct iscsi_datain_req *dr, struct iscsi_datain *datain) +{ + struct kvec *iov; + u32 iov_count = 0, tx_size = 0; + int ret, iov_ret; + + iov = &cmd->iov_data[0]; + iov[iov_count].iov_base = cmd->pdu; + iov[iov_count++].iov_len = ISCSI_HDR_LEN; + tx_size += ISCSI_HDR_LEN; + + if (conn->conn_ops->HeaderDigest) { + u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; + + iscsit_do_crypto_hash_buf(conn->conn_tx_hash, cmd->pdu, + ISCSI_HDR_LEN, 0, NULL, + (u8 *)header_digest); + + iov[0].iov_len += ISCSI_CRC_LEN; + tx_size += ISCSI_CRC_LEN; + + pr_debug("Attaching CRC32 HeaderDigest for DataIN PDU 0x%08x\n", +*header_digest); + } + + iov_ret = iscsit_map_iovec(cmd, &cmd->iov_data[1], + datain->offset, datain->length); + if (iov_ret < 0) + return -1; + + iov_count += iov_ret; + tx_size += datain->length; + + cmd->padding = ((-datain->length) & 3); + if (cmd->padding) { + iov[iov_count].iov_base = cmd->pad_bytes; + iov[iov_count++].iov_len= cmd->padding; + tx_size += cmd->padding; + + pr_debug("Attaching %u padding bytes\n", cmd->padding); + } + + if (conn->conn_ops->DataDigest) { + cmd->data_crc = iscsit_do_crypto_hash_sg(conn->conn_tx_hash, +cmd, datain->offset, +datain->length, +cmd->padding, +cmd->pad_bytes); + + iov[iov_count].iov_base = &cmd->data_crc; + iov[iov_count++].iov_len = ISCSI_CRC_LEN; + tx_size += ISCSI_CRC_LEN; + + pr_debug("Attached CRC32C DataDigest %d bytes, crc 0x%08x\n", +datain->length + cmd->padding, cmd->data_crc); + } + + cmd->iov_data_count = iov_count; + cmd->tx_size = tx_size; + + ret = iscsit_fe_sendpage_sg(cmd, conn); + + iscsit_unmap_iovec(cmd); + + if (ret < 0) { + iscsit_tx_thread_wait_for_tcp(conn); + return ret; + } + + return 0; +} + static enum target_prot_op iscsit_get_sup_prot_ops(struct iscsi_conn *conn) { return TARGET_PROT_NORMAL; @@ -599,6 +677,7 @@ static struct iscsit_transport iscsi_target_transport = { .iscsit_aborted_task= iscsit_aborted_task, .iscsit_alloc_pdu = iscsit_alloc_pdu, .iscsit_xmit_pdu= iscsit_xmit_pdu, + .iscsit_xmit_datain_pdu = iscsit_xmit_datain_pdu, .iscsit_get_sup_prot_ops = iscsit_get_sup_prot_ops, }; @@ -2701,9 +2780,7 @@ static int iscsit_send_datain(struct iscsi_cmd *cmd, struct iscsi_conn *conn) struct iscsi_data_rsp *hdr; struct iscsi_datain datain; struct iscsi_datain_req *dr; - struct kvec *iov; - u32 iov_count = 0, tx_size = 0; - int eodr = 0, ret, iov_ret; + int eodr = 0, ret; bool set_statsn = false; memset(&datain, 0, sizeof(struct iscsi_datain)); @@ -2749,64 +2826,10 @@ static int iscsit_send_datain(struct iscsi_cmd *cmd, struct iscsi_conn *conn) iscsit_build_datain_pdu(cmd, conn, &datain, hdr, set_statsn); - iov = &cmd->iov_data[0]; - iov[iov_count].iov_base = cmd->pdu; - iov[iov_count++].iov_len= ISCSI_HDR_LEN; - tx_size += ISCSI_HDR_LEN; - - if (conn->conn_ops->HeaderDigest) { - u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; - - iscsit_do_crypto_hash_buf(conn->conn_tx_hash, cmd->pdu, - I
[PATCH v2 11/16] iscsi-target: add new offload transport type
Add new transport type ISCSI_HW_OFFLOAD, hw offload transport drivers will use this transport type. Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target_configfs.c | 76 include/target/iscsi/iscsi_target_core.h | 1 + 2 files changed, 77 insertions(+) diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 97e5b69..3565e07 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -182,12 +182,88 @@ out: return rc; } +static ssize_t lio_target_np_hw_offload_show(struct config_item *item, +char *page) +{ + struct iscsi_tpg_np *tpg_np = to_iscsi_tpg_np(item); + struct iscsi_tpg_np *tpg_np_hw_offload; + ssize_t rb; + + tpg_np_hw_offload = iscsit_tpg_locate_child_np(tpg_np, + ISCSI_HW_OFFLOAD); + if (tpg_np_hw_offload) + rb = sprintf(page, "1\n"); + else + rb = sprintf(page, "0\n"); + + return rb; +} + +static ssize_t lio_target_np_hw_offload_store(struct config_item *item, + const char *page, size_t count) +{ + struct iscsi_tpg_np *tpg_np = to_iscsi_tpg_np(item); + struct iscsi_np *np; + struct iscsi_portal_group *tpg; + struct iscsi_tpg_np *tpg_np_hw_offload = NULL; + u32 op; + int rc = 0; + + rc = kstrtou32(page, 0, &op); + if (rc) + return rc; + + 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) { + tpg_np_hw_offload = iscsit_tpg_add_network_portal(tpg, + &np->np_sockaddr, tpg_np, ISCSI_HW_OFFLOAD); + + if (IS_ERR(tpg_np_hw_offload)) { + rc = PTR_ERR(tpg_np_hw_offload); + goto out; + } + } else { + tpg_np_hw_offload = iscsit_tpg_locate_child_np(tpg_np, + ISCSI_HW_OFFLOAD); + + if (tpg_np_hw_offload) { + rc = iscsit_tpg_del_network_portal(tpg, + tpg_np_hw_offload); + if (rc < 0) + goto out; + } + } + + iscsit_put_tpg(tpg); + return count; +out: + iscsit_put_tpg(tpg); + return rc; +} + CONFIGFS_ATTR(lio_target_np_, sctp); CONFIGFS_ATTR(lio_target_np_, iser); +CONFIGFS_ATTR(lio_target_np_, hw_offload); static struct configfs_attribute *lio_target_portal_attrs[] = { &lio_target_np_attr_sctp, &lio_target_np_attr_iser, + &lio_target_np_attr_hw_offload, NULL, }; diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h index 01c41f2..110c1fd 100644 --- a/include/target/iscsi/iscsi_target_core.h +++ b/include/target/iscsi/iscsi_target_core.h @@ -74,6 +74,7 @@ enum iscsit_transport_type { ISCSI_IWARP_TCP = 3, ISCSI_IWARP_SCTP= 4, ISCSI_INFINIBAND= 5, + ISCSI_HW_OFFLOAD= 6, }; /* RFC-3720 7.1.4 Standard Connection State Diagram for a Target */ -- 2.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 10/16] iscsi-target: use conn->network_transport in text rsp
Use conn->network_transport instead of ISCSI_TCP to build text response. Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index b655f0c..e61249d 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -3546,7 +3546,8 @@ static int iscsit_send_text_rsp( if (unlikely(!hdr)) return -ENOMEM; - text_length = iscsit_build_text_rsp(cmd, conn, hdr, ISCSI_TCP); + text_length = iscsit_build_text_rsp(cmd, conn, hdr, + conn->network_transport); if (text_length < 0) { if (conn->conn_transport->iscsit_free_pdu) conn->conn_transport->iscsit_free_pdu(conn, cmd); -- 2.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 04/16] iscsi-target: add void (*iscsit_release_cmd)()
Add void (*iscsit_release_cmd)() to struct iscsit_transport, iscsi-target uses this callback to release transport driver resources associated with an iSCSI cmd. Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target_util.c | 3 +++ include/target/iscsi/iscsi_transport.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 428b0d9..a533017 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -725,6 +725,9 @@ void __iscsit_free_cmd(struct iscsi_cmd *cmd, bool scsi_cmd, iscsit_remove_cmd_from_immediate_queue(cmd, conn); iscsit_remove_cmd_from_response_queue(cmd, conn); } + + if (conn && conn->conn_transport->iscsit_release_cmd) + conn->conn_transport->iscsit_release_cmd(conn, cmd); } void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown) diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h index 77ae41e..19cef94 100644 --- a/include/target/iscsi/iscsi_transport.h +++ b/include/target/iscsi/iscsi_transport.h @@ -29,6 +29,7 @@ struct iscsit_transport { int (*iscsit_xmit_datain_pdu)(struct iscsi_conn *, struct iscsi_cmd *, struct iscsi_datain_req *, struct iscsi_datain *); + void (*iscsit_release_cmd)(struct iscsi_conn *, struct iscsi_cmd *); enum target_prot_op (*iscsit_get_sup_prot_ops)(struct iscsi_conn *); }; -- 2.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 08/16] iscsi-target: add void (*iscsit_get_r2t_ttt)()
Add void (*iscsit_get_r2t_ttt)() to struct iscsit_transport, iscsi-target uses this callback to get r2t->targ_xfer_tag. Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target.c| 5 - include/target/iscsi/iscsi_transport.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 98d96d4..ec785c8 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -3060,7 +3060,10 @@ static int iscsit_send_r2t( int_to_scsilun(cmd->se_cmd.orig_fe_lun, (struct scsi_lun *)&hdr->lun); hdr->itt= cmd->init_task_tag; - r2t->targ_xfer_tag = session_get_next_ttt(conn->sess); + if (conn->conn_transport->iscsit_get_r2t_ttt) + conn->conn_transport->iscsit_get_r2t_ttt(conn, cmd, r2t); + else + r2t->targ_xfer_tag = session_get_next_ttt(conn->sess); hdr->ttt= cpu_to_be32(r2t->targ_xfer_tag); hdr->statsn = cpu_to_be32(conn->stat_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h index dbef892..f949e70 100644 --- a/include/target/iscsi/iscsi_transport.h +++ b/include/target/iscsi/iscsi_transport.h @@ -32,6 +32,8 @@ struct iscsit_transport { void (*iscsit_release_cmd)(struct iscsi_conn *, struct iscsi_cmd *); void (*iscsit_get_rx_pdu)(struct iscsi_conn *); int (*iscsit_validate_params)(struct iscsi_conn *); + void (*iscsit_get_r2t_ttt)(struct iscsi_conn *, struct iscsi_cmd *, + struct iscsi_r2t *); enum target_prot_op (*iscsit_get_sup_prot_ops)(struct iscsi_conn *); }; -- 2.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 09/16] iscsi-target: move iscsit_thread_check_cpumask()
Move iscsit_thread_check_cpumask() to header file so that ISCSI_HW_OFFLOAD and other transport drivers can call this function to ensure both tx and rx thread runs on same cpu. Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target.c | 26 -- include/target/iscsi/iscsi_target_core.h | 26 ++ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index ec785c8..b655f0c 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -3618,32 +3618,6 @@ void iscsit_thread_get_cpumask(struct iscsi_conn *conn) cpumask_setall(conn->conn_cpumask); } -static inline void iscsit_thread_check_cpumask( - struct iscsi_conn *conn, - struct task_struct *p, - int mode) -{ - /* -* mode == 1 signals iscsi_target_tx_thread() usage. -* mode == 0 signals iscsi_target_rx_thread() usage. -*/ - if (mode == 1) { - if (!conn->conn_tx_reset_cpumask) - return; - conn->conn_tx_reset_cpumask = 0; - } else { - if (!conn->conn_rx_reset_cpumask) - return; - conn->conn_rx_reset_cpumask = 0; - } - /* -* Update the CPU mask for this single kthread so that -* both TX and RX kthreads are scheduled to run on the -* same CPU. -*/ - set_cpus_allowed_ptr(p, conn->conn_cpumask); -} - static int iscsit_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) { diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h index c3371fa..01c41f2 100644 --- a/include/target/iscsi/iscsi_target_core.h +++ b/include/target/iscsi/iscsi_target_core.h @@ -890,4 +890,30 @@ static inline u32 session_get_next_ttt(struct iscsi_session *session) } extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, itt_t); + +static inline void iscsit_thread_check_cpumask( + struct iscsi_conn *conn, + struct task_struct *p, + int mode) +{ + /* +* mode == 1 signals iscsi_target_tx_thread() usage. +* mode == 0 signals iscsi_target_rx_thread() usage. +*/ + if (mode == 1) { + if (!conn->conn_tx_reset_cpumask) + return; + conn->conn_tx_reset_cpumask = 0; + } else { + if (!conn->conn_rx_reset_cpumask) + return; + conn->conn_rx_reset_cpumask = 0; + } + /* +* Update the CPU mask for this single kthread so that +* both TX and RX kthreads are scheduled to run on the +* same CPU. +*/ + set_cpus_allowed_ptr(p, conn->conn_cpumask); +} #endif /* ISCSI_TARGET_CORE_H */ -- 2.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 15/16] iscsi-target: fix seq_end_offset calculation
In case of unsolicited data, seq end offset for first sequence must be equal to the min of firstburstlength and data length. Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target_erl0.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index 210f6e4..a0fb5a8 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c @@ -44,10 +44,10 @@ void iscsit_set_dataout_sequence_values( */ if (cmd->unsolicited_data) { cmd->seq_start_offset = cmd->write_data_done; - cmd->seq_end_offset = (cmd->write_data_done + - ((cmd->se_cmd.data_length > + cmd->seq_end_offset = (cmd->se_cmd.data_length > conn->sess->sess_ops->FirstBurstLength) ? -conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length)); +conn->sess->sess_ops->FirstBurstLength : +cmd->se_cmd.data_length; return; } -- 2.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 13/16] iscsi-target: call complete on conn_logout_comp
ISCSI_HW_OFFLOAD transport drivers waits on conn_logout_comp as ISCSI_TCP driver so call complete if transport type is ISCSI_HW_OFFLOAD. Signed-off-by: Varun Prakash --- drivers/target/iscsi/iscsi_target.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 959644f..edce5af 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -4101,16 +4101,18 @@ int iscsit_close_connection( pr_debug("Closing iSCSI connection CID %hu on SID:" " %u\n", conn->cid, sess->sid); /* -* Always up conn_logout_comp for the traditional TCP case just in case -* the RX Thread in iscsi_target_rx_opcode() is sleeping and the logout -* response never got sent because the connection failed. +* Always up conn_logout_comp for the traditional TCP and HW_OFFLOAD +* case just in case the RX Thread in iscsi_target_rx_opcode() is +* sleeping and the logout response never got sent because the +* connection failed. * * However for iser-target, isert_wait4logout() is using conn_logout_comp * to signal logout response TX interrupt completion. Go ahead and skip * this for iser since isert_rx_opcode() does not wait on logout failure, * and to avoid iscsi_conn pointer dereference in iser-target code. */ - if (conn->conn_transport->transport_type == ISCSI_TCP) + if ((conn->conn_transport->transport_type == ISCSI_TCP) || + (conn->conn_transport->transport_type == ISCSI_HW_OFFLOAD)) complete(&conn->conn_logout_comp); if (!strcmp(current->comm, ISCSI_RX_THREAD_NAME)) { -- 2.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 16/16] cxgbit: add files for cxgbit.ko
cxgbit.h - This file contains data structure definitions for cxgbit.ko. cxgbit_lro.h - This file contains data structure definitions for LRO support. cxgbit_main.c - This file contains code for registering with iscsi target transport and cxgb4 driver. cxgbit_cm.c - This file contains code for connection management. cxgbit_target.c - This file contains code for processing iSCSI PDU. cxgbit_ddp.c - This file contains code for Direct Data Placement. v2: added check for NULL sg in cxgbit_set_one_ppod() Reported-by: Dan Carpenter cxgbit: add Kconfig and Makefile v2: added dependency on INET Reported-by: Arnd Bergmann iscsi-target: update Kconfig and Makefile for compiling cxgbit.ko. Signed-off-by: Varun Prakash --- drivers/target/iscsi/Kconfig|2 + drivers/target/iscsi/Makefile |1 + drivers/target/iscsi/cxgbit/Kconfig |7 + drivers/target/iscsi/cxgbit/Makefile|6 + drivers/target/iscsi/cxgbit/cxgbit.h| 358 + drivers/target/iscsi/cxgbit/cxgbit_cm.c | 2086 +++ drivers/target/iscsi/cxgbit/cxgbit_ddp.c| 325 + drivers/target/iscsi/cxgbit/cxgbit_lro.h| 72 + drivers/target/iscsi/cxgbit/cxgbit_main.c | 703 + drivers/target/iscsi/cxgbit/cxgbit_target.c | 1601 10 files changed, 5161 insertions(+) create mode 100644 drivers/target/iscsi/cxgbit/Kconfig create mode 100644 drivers/target/iscsi/cxgbit/Makefile create mode 100644 drivers/target/iscsi/cxgbit/cxgbit.h create mode 100644 drivers/target/iscsi/cxgbit/cxgbit_cm.c create mode 100644 drivers/target/iscsi/cxgbit/cxgbit_ddp.c create mode 100644 drivers/target/iscsi/cxgbit/cxgbit_lro.h create mode 100644 drivers/target/iscsi/cxgbit/cxgbit_main.c create mode 100644 drivers/target/iscsi/cxgbit/cxgbit_target.c diff --git a/drivers/target/iscsi/Kconfig b/drivers/target/iscsi/Kconfig index 8345fb4..bbdbf9c 100644 --- a/drivers/target/iscsi/Kconfig +++ b/drivers/target/iscsi/Kconfig @@ -7,3 +7,5 @@ config ISCSI_TARGET help Say M here to enable the ConfigFS enabled Linux-iSCSI.org iSCSI Target Mode Stack. + +source "drivers/target/iscsi/cxgbit/Kconfig" diff --git a/drivers/target/iscsi/Makefile b/drivers/target/iscsi/Makefile index 0f43be9..0f18295 100644 --- a/drivers/target/iscsi/Makefile +++ b/drivers/target/iscsi/Makefile @@ -18,3 +18,4 @@ iscsi_target_mod-y += iscsi_target_parameters.o \ iscsi_target_transport.o obj-$(CONFIG_ISCSI_TARGET) += iscsi_target_mod.o +obj-$(CONFIG_ISCSI_TARGET_CXGB4) += cxgbit/ diff --git a/drivers/target/iscsi/cxgbit/Kconfig b/drivers/target/iscsi/cxgbit/Kconfig new file mode 100644 index 000..c9b6a3c --- /dev/null +++ b/drivers/target/iscsi/cxgbit/Kconfig @@ -0,0 +1,7 @@ +config ISCSI_TARGET_CXGB4 + tristate "Chelsio iSCSI target offload driver" + depends on ISCSI_TARGET && CHELSIO_T4 && INET + select CHELSIO_T4_UWIRE + ---help--- + To compile this driver as module, choose M here: the module + will be called cxgbit. diff --git a/drivers/target/iscsi/cxgbit/Makefile b/drivers/target/iscsi/cxgbit/Makefile new file mode 100644 index 000..bd56c07 --- /dev/null +++ b/drivers/target/iscsi/cxgbit/Makefile @@ -0,0 +1,6 @@ +ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4 +ccflags-y += -Idrivers/target/iscsi + +obj-$(CONFIG_ISCSI_TARGET_CXGB4) += cxgbit.o + +cxgbit-y := cxgbit_main.o cxgbit_cm.o cxgbit_target.o cxgbit_ddp.o diff --git a/drivers/target/iscsi/cxgbit/cxgbit.h b/drivers/target/iscsi/cxgbit/cxgbit.h new file mode 100644 index 000..3aa9a3c --- /dev/null +++ b/drivers/target/iscsi/cxgbit/cxgbit.h @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2016 Chelsio Communications, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __CXGBIT_H__ +#define __CXGBIT_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include "t4_regs.h" +#include "t4_msg.h" +#include "cxgb4.h" +#include "cxgb4_uld.h" +#include "l2t.h" +#include "cxgb4_ppm.h" +#include "cxgbit_lro.h" + +extern struct mutex cdev_list_lock; +extern struct list_head cdev_list_head; +struct cxgbit_np; + +struct cxgbit_sock; + +struct cxgbit_cmd { + struct sk_buff *skb; + struct scatterlist sg; + struct cxgbi_task_tag_info ttinfo; + bool setup_ddp; + bool release; +}; + +#define CXGBIT_MAX_ISO_PAYLOAD \ + min_t(u32, MAX_SKB_FRAGS * PAGE_SIZE, 65535) + +struct cxgbit_iso_info { + u8 flags; + u32 mpdu; + u32 len; + u32 burst_len; +}; + +enum cxgbit_skcb_flags { + SKCBF_TX_NEED_HDR = (1 << 0), /* packet nee
LOAN
Brauchen Sie einen Kredit? Wir bieten Darlehen in 2% gelten heute Kontakt mit uns auf: legacyassetgro...@hotmail.com -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] sd: fixup capacity calculation for 4k drives
On 03/29/2016 01:06 AM, Hannes Reinecke wrote: > in sd_read_capacity() the sdkp->capacity field changes its meaning: > after the call to read_capacity_XX() it carries the _unscaled_ values, > making the comparison between the original value and the new value > always false for drives with a sector size != 512. > > Signed-off-by: Hannes Reinecke > --- > drivers/scsi/sd.c | 69 > +++ > 1 file changed, 39 insertions(+), 30 deletions(-) > > diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c > index 5a5457a..0afe113 100644 > --- a/drivers/scsi/sd.c > +++ b/drivers/scsi/sd.c > @@ -2046,7 +2046,7 @@ static void read_capacity_error(struct scsi_disk *sdkp, > struct scsi_device *sdp, > #define READ_CAPACITY_RETRIES_ON_RESET 10 > > static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, > - unsigned char *buffer) > + unsigned char *buffer, u64 *capacity) > { > unsigned char cmd[16]; > struct scsi_sense_hdr sshdr; > @@ -2054,8 +2054,8 @@ static int read_capacity_16(struct scsi_disk *sdkp, > struct scsi_device *sdp, > int the_result; > int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET; > unsigned int alignment; > - unsigned long long lba; > - unsigned sector_size; > + u64 lba; > + u32 sector_size; > > if (sdp->no_read_capacity_16) > return -EINVAL; > @@ -2114,7 +2114,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, > struct scsi_device *sdp, > sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " > "kernel compiled with support for large block " > "devices.\n"); > - sdkp->capacity = 0; > + *capacity = 0; > return -EOVERFLOW; > } > > @@ -2137,20 +2137,20 @@ static int read_capacity_16(struct scsi_disk *sdkp, > struct scsi_device *sdp, > sd_config_discard(sdkp, SD_LBP_WS16); > } > > - sdkp->capacity = lba + 1; > + *capacity = lba + 1; > return sector_size; > } > > static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, > - unsigned char *buffer) > + unsigned char *buffer, u64 *capacity) > { > unsigned char cmd[16]; > struct scsi_sense_hdr sshdr; > int sense_valid = 0; > int the_result; > int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET; > - sector_t lba; > - unsigned sector_size; > + u32 lba; > + u32 sector_size; > > do { > cmd[0] = READ_CAPACITY; > @@ -2191,7 +2191,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, > struct scsi_device *sdp, > /* Some buggy (usb cardreader) devices return an lba of > 0x when the want to report a size of 0 (with > which they really mean no media is present) */ > - sdkp->capacity = 0; > + *capacity = 0; > sdkp->physical_block_size = sector_size; > return sector_size; > } > @@ -2200,11 +2200,11 @@ static int read_capacity_10(struct scsi_disk *sdkp, > struct scsi_device *sdp, > sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " > "kernel compiled with support for large block " > "devices.\n"); > - sdkp->capacity = 0; > + *capacity = 0; > return -EOVERFLOW; > } > > - sdkp->capacity = lba + 1; > + *capacity = (u64)lba + 1; > sdkp->physical_block_size = sector_size; > return sector_size; > } > @@ -2230,34 +2230,38 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned > char *buffer) > { > int sector_size; > struct scsi_device *sdp = sdkp->device; > - sector_t old_capacity = sdkp->capacity; > + u64 old_capacity = sdkp->capacity, new_capacity; > > if (sd_try_rc16_first(sdp)) { > - sector_size = read_capacity_16(sdkp, sdp, buffer); > + sector_size = read_capacity_16(sdkp, sdp, buffer, > +&new_capacity); > if (sector_size == -EOVERFLOW) > goto got_data; > if (sector_size == -ENODEV) > return; > if (sector_size < 0) > - sector_size = read_capacity_10(sdkp, sdp, buffer); > + sector_size = read_capacity_10(sdkp, sdp, buffer, > +&new_capacity); > if (sector_size < 0) > return; > } else { > - sector_size = read_capacity_10(sdkp, sdp, buffer); > + sector_size = read_capacity_10(sdkp, sdp, buffer, > +&new_capacit