Skip to content

Commit

Permalink
[SCSI] scsi_tcp: rm data rx and tx tfms
Browse files Browse the repository at this point in the history
We currently allocated seperate tfms for data and header digests. There
is no reason for this since we can never calculate a rx header and
digest at the same time. Same for sends. So this patch removes the data
tfms and has the send and recv sides use the rx_tfm or tx_tfm.

I also made the connection creation code preallocate the tfms because I
thought I hit a bug where I changed the digests settings during a
relogin but could not allocate the tfm and then we just failed.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
  • Loading branch information
Mike Christie authored and James Bottomley committed Sep 2, 2006
1 parent 62f3830 commit dd8c0d9
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 72 deletions.
102 changes: 36 additions & 66 deletions drivers/scsi/iscsi_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ iscsi_recv_digest_update(struct iscsi_tcp_conn *tcp_conn, char* buf, int len)
struct scatterlist tmp;

sg_init_one(&tmp, buf, len);
crypto_digest_update(tcp_conn->data_rx_tfm, &tmp, 1);
crypto_digest_update(tcp_conn->rx_tfm, &tmp, 1);
}

static int iscsi_scsi_data_in(struct iscsi_conn *conn)
Expand Down Expand Up @@ -748,11 +748,11 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
if (conn->datadgst_en) {
if (!offset)
crypto_digest_update(
tcp_conn->data_rx_tfm,
tcp_conn->rx_tfm,
&sg[i], 1);
else
partial_sg_digest_update(
tcp_conn->data_rx_tfm,
tcp_conn->rx_tfm,
&sg[i],
sg[i].offset + offset,
sg[i].length - offset);
Expand All @@ -766,7 +766,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
/*
* data-in is complete, but buffer not...
*/
partial_sg_digest_update(tcp_conn->data_rx_tfm,
partial_sg_digest_update(tcp_conn->rx_tfm,
&sg[i],
sg[i].offset, sg[i].length-rc);
rc = 0;
Expand Down Expand Up @@ -885,10 +885,8 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
*/
rc = iscsi_tcp_hdr_recv(conn);
if (!rc && tcp_conn->in.datalen) {
if (conn->datadgst_en) {
BUG_ON(!tcp_conn->data_rx_tfm);
crypto_digest_init(tcp_conn->data_rx_tfm);
}
if (conn->datadgst_en)
crypto_digest_init(tcp_conn->rx_tfm);
tcp_conn->in_progress = IN_PROGRESS_DATA_RECV;
} else if (rc) {
iscsi_conn_failure(conn, rc);
Expand Down Expand Up @@ -940,10 +938,10 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
tcp_conn->in.padding);
memset(pad, 0, tcp_conn->in.padding);
sg_init_one(&sg, pad, tcp_conn->in.padding);
crypto_digest_update(tcp_conn->data_rx_tfm,
crypto_digest_update(tcp_conn->rx_tfm,
&sg, 1);
}
crypto_digest_final(tcp_conn->data_rx_tfm,
crypto_digest_final(tcp_conn->rx_tfm,
(u8 *) & tcp_conn->in.datadgst);
debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst);
tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
Expand Down Expand Up @@ -1188,7 +1186,7 @@ static inline void
iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn,
struct iscsi_tcp_cmd_task *tcp_ctask)
{
crypto_digest_init(tcp_conn->data_tx_tfm);
crypto_digest_init(tcp_conn->tx_tfm);
tcp_ctask->digest_count = 4;
}

Expand Down Expand Up @@ -1444,7 +1442,7 @@ iscsi_send_padding(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad,
tcp_ctask->pad_count);
if (conn->datadgst_en)
crypto_digest_update(tcp_conn->data_tx_tfm,
crypto_digest_update(tcp_conn->tx_tfm,
&tcp_ctask->sendbuf.sg, 1);
} else if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_PAD))
return 0;
Expand Down Expand Up @@ -1477,7 +1475,7 @@ iscsi_send_digest(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
tcp_conn = conn->dd_data;

if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_DATA_DIGEST)) {
crypto_digest_final(tcp_conn->data_tx_tfm, (u8*)digest);
crypto_digest_final(tcp_conn->tx_tfm, (u8*)digest);
iscsi_buf_init_iov(buf, (char*)digest, 4);
}
tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_DATA_DIGEST;
Expand Down Expand Up @@ -1511,7 +1509,7 @@ iscsi_send_data(struct iscsi_cmd_task *ctask, struct iscsi_buf *sendbuf,
rc = iscsi_sendpage(conn, sendbuf, count, &buf_sent);
*sent = *sent + buf_sent;
if (buf_sent && conn->datadgst_en)
partial_sg_digest_update(tcp_conn->data_tx_tfm,
partial_sg_digest_update(tcp_conn->tx_tfm,
&sendbuf->sg, sendbuf->sg.offset + offset,
buf_sent);
if (!iscsi_buf_left(sendbuf) && *sg != tcp_ctask->bad_sg) {
Expand Down Expand Up @@ -1547,10 +1545,6 @@ iscsi_send_unsol_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
if (conn->hdrdgst_en)
iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
(u8*)dtask->hdrext);
if (conn->datadgst_en) {
iscsi_data_digest_init(ctask->conn->dd_data, tcp_ctask);
dtask->digest = 0;
}

tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT;
iscsi_set_padding(tcp_ctask, ctask->data_count);
Expand All @@ -1563,6 +1557,12 @@ iscsi_send_unsol_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
return rc;
}

if (conn->datadgst_en) {
dtask = &tcp_ctask->unsol_dtask;
iscsi_data_digest_init(ctask->conn->dd_data, tcp_ctask);
dtask->digest = 0;
}

debug_scsi("uns dout [itt 0x%x dlen %d sent %d]\n",
ctask->itt, ctask->unsol_count, tcp_ctask->sent);
return 0;
Expand Down Expand Up @@ -1629,19 +1629,18 @@ static int iscsi_send_sol_pdu(struct iscsi_conn *conn,
if (conn->hdrdgst_en)
iscsi_hdr_digest(conn, &r2t->headbuf,
(u8*)dtask->hdrext);

if (conn->datadgst_en) {
iscsi_data_digest_init(conn->dd_data, tcp_ctask);
dtask->digest = 0;
}

rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count);
if (rc) {
tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
return rc;
}

if (conn->datadgst_en) {
iscsi_data_digest_init(conn->dd_data, tcp_ctask);
dtask->digest = 0;
}

iscsi_set_padding(tcp_ctask, r2t->data_count);
debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n",
r2t->solicit_datasn - 1, ctask->itt, r2t->data_count,
Expand Down Expand Up @@ -1764,8 +1763,20 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
/* initial operational parameters */
tcp_conn->hdr_size = sizeof(struct iscsi_hdr);

tcp_conn->tx_tfm = crypto_alloc_tfm("crc32c", 0);
if (!tcp_conn->tx_tfm)
goto free_tcp_conn;

tcp_conn->rx_tfm = crypto_alloc_tfm("crc32c", 0);
if (!tcp_conn->rx_tfm)
goto free_tx_tfm;

return cls_conn;

free_tx_tfm:
crypto_free_tfm(tcp_conn->tx_tfm);
free_tcp_conn:
kfree(tcp_conn);
tcp_conn_alloc_fail:
iscsi_conn_teardown(cls_conn);
return NULL;
Expand Down Expand Up @@ -1807,10 +1818,6 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)
crypto_free_tfm(tcp_conn->tx_tfm);
if (tcp_conn->rx_tfm)
crypto_free_tfm(tcp_conn->rx_tfm);
if (tcp_conn->data_tx_tfm)
crypto_free_tfm(tcp_conn->data_tx_tfm);
if (tcp_conn->data_rx_tfm)
crypto_free_tfm(tcp_conn->data_rx_tfm);
}

kfree(tcp_conn);
Expand Down Expand Up @@ -1968,48 +1975,11 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
case ISCSI_PARAM_HDRDGST_EN:
iscsi_set_param(cls_conn, param, buf, buflen);
tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
if (conn->hdrdgst_en) {
if (conn->hdrdgst_en)
tcp_conn->hdr_size += sizeof(__u32);
if (!tcp_conn->tx_tfm)
tcp_conn->tx_tfm = crypto_alloc_tfm("crc32c",
0);
if (!tcp_conn->tx_tfm)
return -ENOMEM;
if (!tcp_conn->rx_tfm)
tcp_conn->rx_tfm = crypto_alloc_tfm("crc32c",
0);
if (!tcp_conn->rx_tfm) {
crypto_free_tfm(tcp_conn->tx_tfm);
return -ENOMEM;
}
} else {
if (tcp_conn->tx_tfm)
crypto_free_tfm(tcp_conn->tx_tfm);
if (tcp_conn->rx_tfm)
crypto_free_tfm(tcp_conn->rx_tfm);
}
break;
case ISCSI_PARAM_DATADGST_EN:
iscsi_set_param(cls_conn, param, buf, buflen);
if (conn->datadgst_en) {
if (!tcp_conn->data_tx_tfm)
tcp_conn->data_tx_tfm =
crypto_alloc_tfm("crc32c", 0);
if (!tcp_conn->data_tx_tfm)
return -ENOMEM;
if (!tcp_conn->data_rx_tfm)
tcp_conn->data_rx_tfm =
crypto_alloc_tfm("crc32c", 0);
if (!tcp_conn->data_rx_tfm) {
crypto_free_tfm(tcp_conn->data_tx_tfm);
return -ENOMEM;
}
} else {
if (tcp_conn->data_tx_tfm)
crypto_free_tfm(tcp_conn->data_tx_tfm);
if (tcp_conn->data_rx_tfm)
crypto_free_tfm(tcp_conn->data_rx_tfm);
}
tcp_conn->sendpage = conn->datadgst_en ?
sock_no_sendpage : tcp_conn->sock->ops->sendpage;
break;
Expand Down
8 changes: 2 additions & 6 deletions drivers/scsi/iscsi_tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,6 @@ struct iscsi_tcp_conn {
* stop to terminate */
/* iSCSI connection-wide sequencing */
int hdr_size; /* PDU header size */

struct crypto_tfm *rx_tfm; /* CRC32C (Rx) */
struct crypto_tfm *data_rx_tfm; /* CRC32C (Rx) for data */

/* control data */
struct iscsi_tcp_recv in; /* TCP receive context */
int in_progress; /* connection state machine */
Expand All @@ -94,9 +90,9 @@ struct iscsi_tcp_conn {
void (*old_state_change)(struct sock *);
void (*old_write_space)(struct sock *);

/* xmit */
/* data and header digests */
struct crypto_tfm *tx_tfm; /* CRC32C (Tx) */
struct crypto_tfm *data_tx_tfm; /* CRC32C (Tx) for data */
struct crypto_tfm *rx_tfm; /* CRC32C (Rx) */

/* MIB custom statistics */
uint32_t sendpage_failures_cnt;
Expand Down

0 comments on commit dd8c0d9

Please sign in to comment.