Skip to content

Commit 31e4cdd

Browse files
committed
scsi: target: iscsi: switch to using the crc32c library
Now that the crc32c() library function directly takes advantage of architecture-specific optimizations, it is unnecessary to go through the crypto API. Just use crc32c(). This is much simpler, and it improves performance due to eliminating the crypto API overhead. Reviewed-by: Ard Biesheuvel <[email protected]> Reviewed-by: Martin K. Petersen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Eric Biggers <[email protected]>
1 parent 3ca4bec commit 31e4cdd

File tree

6 files changed

+49
-182
lines changed

6 files changed

+49
-182
lines changed

drivers/target/iscsi/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
config ISCSI_TARGET
33
tristate "SCSI Target Mode Stack"
44
depends on INET
5+
select CRC32
56
select CRYPTO
6-
select CRYPTO_CRC32C
7+
select CRYPTO_HASH
78
help
89
Say M to enable the SCSI target mode stack. A SCSI target mode stack
910
is software that makes local storage available over a storage network

drivers/target/iscsi/iscsi_target.c

Lines changed: 45 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
******************************************************************************/
1010

11-
#include <crypto/hash.h>
11+
#include <linux/crc32c.h>
1212
#include <linux/string.h>
1313
#include <linux/kthread.h>
1414
#include <linux/completion.h>
@@ -490,8 +490,8 @@ void iscsit_aborted_task(struct iscsit_conn *conn, struct iscsit_cmd *cmd)
490490
}
491491
EXPORT_SYMBOL(iscsit_aborted_task);
492492

493-
static void iscsit_do_crypto_hash_buf(struct ahash_request *, const void *,
494-
u32, u32, const void *, void *);
493+
static u32 iscsit_crc_buf(const void *buf, u32 payload_length,
494+
u32 padding, const void *pad_bytes);
495495
static void iscsit_tx_thread_wait_for_tcp(struct iscsit_conn *);
496496

497497
static int
@@ -510,9 +510,7 @@ iscsit_xmit_nondatain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
510510
if (conn->conn_ops->HeaderDigest) {
511511
u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
512512

513-
iscsit_do_crypto_hash_buf(conn->conn_tx_hash, hdr,
514-
ISCSI_HDR_LEN, 0, NULL,
515-
header_digest);
513+
*header_digest = iscsit_crc_buf(hdr, ISCSI_HDR_LEN, 0, NULL);
516514

517515
iov[0].iov_len += ISCSI_CRC_LEN;
518516
tx_size += ISCSI_CRC_LEN;
@@ -537,11 +535,9 @@ iscsit_xmit_nondatain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
537535
}
538536

539537
if (conn->conn_ops->DataDigest) {
540-
iscsit_do_crypto_hash_buf(conn->conn_tx_hash,
541-
data_buf, data_buf_len,
542-
padding, &cmd->pad_bytes,
543-
&cmd->data_crc);
544-
538+
cmd->data_crc = iscsit_crc_buf(data_buf, data_buf_len,
539+
padding,
540+
&cmd->pad_bytes);
545541
iov[niov].iov_base = &cmd->data_crc;
546542
iov[niov++].iov_len = ISCSI_CRC_LEN;
547543
tx_size += ISCSI_CRC_LEN;
@@ -566,8 +562,8 @@ iscsit_xmit_nondatain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
566562
static int iscsit_map_iovec(struct iscsit_cmd *cmd, struct kvec *iov, int nvec,
567563
u32 data_offset, u32 data_length);
568564
static void iscsit_unmap_iovec(struct iscsit_cmd *);
569-
static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsit_cmd *,
570-
u32, u32, u32, u8 *);
565+
static u32 iscsit_crc_sglist(const struct iscsit_cmd *cmd, u32 data_length,
566+
u32 padding, const u8 *pad_bytes);
571567
static int
572568
iscsit_xmit_datain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
573569
const struct iscsi_datain *datain)
@@ -584,10 +580,8 @@ iscsit_xmit_datain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
584580
if (conn->conn_ops->HeaderDigest) {
585581
u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
586582

587-
iscsit_do_crypto_hash_buf(conn->conn_tx_hash, cmd->pdu,
588-
ISCSI_HDR_LEN, 0, NULL,
589-
header_digest);
590-
583+
*header_digest = iscsit_crc_buf(cmd->pdu, ISCSI_HDR_LEN, 0,
584+
NULL);
591585
iov[0].iov_len += ISCSI_CRC_LEN;
592586
tx_size += ISCSI_CRC_LEN;
593587

@@ -614,12 +608,8 @@ iscsit_xmit_datain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
614608
}
615609

616610
if (conn->conn_ops->DataDigest) {
617-
cmd->data_crc = iscsit_do_crypto_hash_sg(conn->conn_tx_hash,
618-
cmd, datain->offset,
619-
datain->length,
620-
cmd->padding,
621-
cmd->pad_bytes);
622-
611+
cmd->data_crc = iscsit_crc_sglist(cmd, datain->length,
612+
cmd->padding, cmd->pad_bytes);
623613
iov[iov_count].iov_base = &cmd->data_crc;
624614
iov[iov_count++].iov_len = ISCSI_CRC_LEN;
625615
tx_size += ISCSI_CRC_LEN;
@@ -1404,77 +1394,45 @@ iscsit_handle_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
14041394
return iscsit_get_immediate_data(cmd, hdr, dump_payload);
14051395
}
14061396

1407-
static u32 iscsit_do_crypto_hash_sg(
1408-
struct ahash_request *hash,
1409-
struct iscsit_cmd *cmd,
1410-
u32 data_offset,
1411-
u32 data_length,
1412-
u32 padding,
1413-
u8 *pad_bytes)
1397+
static u32 iscsit_crc_sglist(const struct iscsit_cmd *cmd, u32 data_length,
1398+
u32 padding, const u8 *pad_bytes)
14141399
{
1415-
u32 data_crc;
1416-
struct scatterlist *sg;
1417-
unsigned int page_off;
1418-
1419-
crypto_ahash_init(hash);
1420-
1421-
sg = cmd->first_data_sg;
1422-
page_off = cmd->first_data_sg_off;
1423-
1424-
if (data_length && page_off) {
1425-
struct scatterlist first_sg;
1426-
u32 len = min_t(u32, data_length, sg->length - page_off);
1427-
1428-
sg_init_table(&first_sg, 1);
1429-
sg_set_page(&first_sg, sg_page(sg), len, sg->offset + page_off);
1430-
1431-
ahash_request_set_crypt(hash, &first_sg, NULL, len);
1432-
crypto_ahash_update(hash);
1433-
1434-
data_length -= len;
1435-
sg = sg_next(sg);
1436-
}
1400+
struct scatterlist *sg = cmd->first_data_sg;
1401+
unsigned int page_off = cmd->first_data_sg_off;
1402+
u32 crc = ~0;
14371403

14381404
while (data_length) {
1439-
u32 cur_len = min_t(u32, data_length, sg->length);
1405+
u32 cur_len = min_t(u32, data_length, sg->length - page_off);
1406+
const void *virt;
14401407

1441-
ahash_request_set_crypt(hash, sg, NULL, cur_len);
1442-
crypto_ahash_update(hash);
1408+
virt = kmap_local_page(sg_page(sg)) + sg->offset + page_off;
1409+
crc = crc32c(crc, virt, cur_len);
1410+
kunmap_local(virt);
14431411

1444-
data_length -= cur_len;
14451412
/* iscsit_map_iovec has already checked for invalid sg pointers */
14461413
sg = sg_next(sg);
1447-
}
14481414

1449-
if (padding) {
1450-
struct scatterlist pad_sg;
1451-
1452-
sg_init_one(&pad_sg, pad_bytes, padding);
1453-
ahash_request_set_crypt(hash, &pad_sg, (u8 *)&data_crc,
1454-
padding);
1455-
crypto_ahash_finup(hash);
1456-
} else {
1457-
ahash_request_set_crypt(hash, NULL, (u8 *)&data_crc, 0);
1458-
crypto_ahash_final(hash);
1415+
page_off = 0;
1416+
data_length -= cur_len;
14591417
}
14601418

1461-
return data_crc;
1419+
if (padding)
1420+
crc = crc32c(crc, pad_bytes, padding);
1421+
1422+
return ~crc;
14621423
}
14631424

1464-
static void iscsit_do_crypto_hash_buf(struct ahash_request *hash,
1465-
const void *buf, u32 payload_length, u32 padding,
1466-
const void *pad_bytes, void *data_crc)
1425+
static u32 iscsit_crc_buf(const void *buf, u32 payload_length,
1426+
u32 padding, const void *pad_bytes)
14671427
{
1468-
struct scatterlist sg[2];
1428+
u32 crc = ~0;
14691429

1470-
sg_init_table(sg, ARRAY_SIZE(sg));
1471-
sg_set_buf(sg, buf, payload_length);
1472-
if (padding)
1473-
sg_set_buf(sg + 1, pad_bytes, padding);
1430+
crc = crc32c(crc, buf, payload_length);
14741431

1475-
ahash_request_set_crypt(hash, sg, data_crc, payload_length + padding);
1432+
if (padding)
1433+
crc = crc32c(crc, pad_bytes, padding);
14761434

1477-
crypto_ahash_digest(hash);
1435+
return ~crc;
14781436
}
14791437

14801438
int
@@ -1662,11 +1620,8 @@ iscsit_get_dataout(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
16621620
if (conn->conn_ops->DataDigest) {
16631621
u32 data_crc;
16641622

1665-
data_crc = iscsit_do_crypto_hash_sg(conn->conn_rx_hash, cmd,
1666-
be32_to_cpu(hdr->offset),
1667-
payload_length, padding,
1668-
cmd->pad_bytes);
1669-
1623+
data_crc = iscsit_crc_sglist(cmd, payload_length, padding,
1624+
cmd->pad_bytes);
16701625
if (checksum != data_crc) {
16711626
pr_err("ITT: 0x%08x, Offset: %u, Length: %u,"
16721627
" DataSN: 0x%08x, CRC32C DataDigest 0x%08x"
@@ -1925,10 +1880,8 @@ static int iscsit_handle_nop_out(struct iscsit_conn *conn, struct iscsit_cmd *cm
19251880
}
19261881

19271882
if (conn->conn_ops->DataDigest) {
1928-
iscsit_do_crypto_hash_buf(conn->conn_rx_hash, ping_data,
1929-
payload_length, padding,
1930-
cmd->pad_bytes, &data_crc);
1931-
1883+
data_crc = iscsit_crc_buf(ping_data, payload_length,
1884+
padding, cmd->pad_bytes);
19321885
if (checksum != data_crc) {
19331886
pr_err("Ping data CRC32C DataDigest"
19341887
" 0x%08x does not match computed 0x%08x\n",
@@ -2328,10 +2281,7 @@ iscsit_handle_text_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
23282281
goto reject;
23292282

23302283
if (conn->conn_ops->DataDigest) {
2331-
iscsit_do_crypto_hash_buf(conn->conn_rx_hash,
2332-
text_in, rx_size, 0, NULL,
2333-
&data_crc);
2334-
2284+
data_crc = iscsit_crc_buf(text_in, rx_size, 0, NULL);
23352285
if (checksum != data_crc) {
23362286
pr_err("Text data CRC32C DataDigest"
23372287
" 0x%08x does not match computed"
@@ -2688,10 +2638,8 @@ static int iscsit_handle_immediate_data(
26882638
if (conn->conn_ops->DataDigest) {
26892639
u32 data_crc;
26902640

2691-
data_crc = iscsit_do_crypto_hash_sg(conn->conn_rx_hash, cmd,
2692-
cmd->write_data_done, length, padding,
2693-
cmd->pad_bytes);
2694-
2641+
data_crc = iscsit_crc_sglist(cmd, length, padding,
2642+
cmd->pad_bytes);
26952643
if (checksum != data_crc) {
26962644
pr_err("ImmediateData CRC32C DataDigest 0x%08x"
26972645
" does not match computed 0x%08x\n", checksum,
@@ -4116,10 +4064,8 @@ static void iscsit_get_rx_pdu(struct iscsit_conn *conn)
41164064
break;
41174065
}
41184066

4119-
iscsit_do_crypto_hash_buf(conn->conn_rx_hash, buffer,
4120-
ISCSI_HDR_LEN, 0, NULL,
4121-
&checksum);
4122-
4067+
checksum = iscsit_crc_buf(buffer, ISCSI_HDR_LEN, 0,
4068+
NULL);
41234069
if (digest != checksum) {
41244070
pr_err("HeaderDigest CRC32C failed,"
41254071
" received 0x%08x, computed 0x%08x\n",
@@ -4406,15 +4352,6 @@ int iscsit_close_connection(
44064352
*/
44074353
iscsit_check_conn_usage_count(conn);
44084354

4409-
ahash_request_free(conn->conn_tx_hash);
4410-
if (conn->conn_rx_hash) {
4411-
struct crypto_ahash *tfm;
4412-
4413-
tfm = crypto_ahash_reqtfm(conn->conn_rx_hash);
4414-
ahash_request_free(conn->conn_rx_hash);
4415-
crypto_free_ahash(tfm);
4416-
}
4417-
44184355
if (conn->sock)
44194356
sock_release(conn->sock);
44204357

drivers/target/iscsi/iscsi_target_login.c

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
*
99
******************************************************************************/
1010

11-
#include <crypto/hash.h>
1211
#include <linux/module.h>
1312
#include <linux/string.h>
1413
#include <linux/kthread.h>
@@ -71,46 +70,6 @@ static struct iscsi_login *iscsi_login_init_conn(struct iscsit_conn *conn)
7170
return NULL;
7271
}
7372

74-
/*
75-
* Used by iscsi_target_nego.c:iscsi_target_locate_portal() to setup
76-
* per struct iscsit_conn libcrypto contexts for crc32c and crc32-intel
77-
*/
78-
int iscsi_login_setup_crypto(struct iscsit_conn *conn)
79-
{
80-
struct crypto_ahash *tfm;
81-
82-
/*
83-
* Setup slicing by CRC32C algorithm for RX and TX libcrypto contexts
84-
* which will default to crc32c_intel.ko for cpu_has_xmm4_2, or fallback
85-
* to software 1x8 byte slicing from crc32c.ko
86-
*/
87-
tfm = crypto_alloc_ahash("crc32c", 0, CRYPTO_ALG_ASYNC);
88-
if (IS_ERR(tfm)) {
89-
pr_err("crypto_alloc_ahash() failed\n");
90-
return -ENOMEM;
91-
}
92-
93-
conn->conn_rx_hash = ahash_request_alloc(tfm, GFP_KERNEL);
94-
if (!conn->conn_rx_hash) {
95-
pr_err("ahash_request_alloc() failed for conn_rx_hash\n");
96-
crypto_free_ahash(tfm);
97-
return -ENOMEM;
98-
}
99-
ahash_request_set_callback(conn->conn_rx_hash, 0, NULL, NULL);
100-
101-
conn->conn_tx_hash = ahash_request_alloc(tfm, GFP_KERNEL);
102-
if (!conn->conn_tx_hash) {
103-
pr_err("ahash_request_alloc() failed for conn_tx_hash\n");
104-
ahash_request_free(conn->conn_rx_hash);
105-
conn->conn_rx_hash = NULL;
106-
crypto_free_ahash(tfm);
107-
return -ENOMEM;
108-
}
109-
ahash_request_set_callback(conn->conn_tx_hash, 0, NULL, NULL);
110-
111-
return 0;
112-
}
113-
11473
static int iscsi_login_check_initiator_version(
11574
struct iscsit_conn *conn,
11675
u8 version_max,
@@ -1165,15 +1124,6 @@ void iscsi_target_login_sess_out(struct iscsit_conn *conn,
11651124
iscsit_dec_session_usage_count(conn->sess);
11661125
}
11671126

1168-
ahash_request_free(conn->conn_tx_hash);
1169-
if (conn->conn_rx_hash) {
1170-
struct crypto_ahash *tfm;
1171-
1172-
tfm = crypto_ahash_reqtfm(conn->conn_rx_hash);
1173-
ahash_request_free(conn->conn_rx_hash);
1174-
crypto_free_ahash(tfm);
1175-
}
1176-
11771127
if (conn->param_list) {
11781128
iscsi_release_param_list(conn->param_list);
11791129
conn->param_list = NULL;

drivers/target/iscsi/iscsi_target_login.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ struct iscsi_login;
99
struct iscsi_np;
1010
struct sockaddr_storage;
1111

12-
extern int iscsi_login_setup_crypto(struct iscsit_conn *);
1312
extern int iscsi_check_for_session_reinstatement(struct iscsit_conn *);
1413
extern int iscsi_login_post_auth_non_zero_tsih(struct iscsit_conn *, u16, u32);
1514
extern int iscsit_setup_np(struct iscsi_np *,

drivers/target/iscsi/iscsi_target_nego.c

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,14 +1194,7 @@ int iscsi_target_locate_portal(
11941194
goto get_target;
11951195

11961196
sess->sess_ops->SessionType = 1;
1197-
/*
1198-
* Setup crc32c modules from libcrypto
1199-
*/
1200-
if (iscsi_login_setup_crypto(conn) < 0) {
1201-
pr_err("iscsi_login_setup_crypto() failed\n");
1202-
ret = -1;
1203-
goto out;
1204-
}
1197+
12051198
/*
12061199
* Serialize access across the discovery struct iscsi_portal_group to
12071200
* process login attempt.
@@ -1258,17 +1251,7 @@ int iscsi_target_locate_portal(
12581251
}
12591252
conn->tpg_np = tpg_np;
12601253
pr_debug("Located Portal Group Object: %hu\n", conn->tpg->tpgt);
1261-
/*
1262-
* Setup crc32c modules from libcrypto
1263-
*/
1264-
if (iscsi_login_setup_crypto(conn) < 0) {
1265-
pr_err("iscsi_login_setup_crypto() failed\n");
1266-
kref_put(&tpg_np->tpg_np_kref, iscsit_login_kref_put);
1267-
iscsit_put_tiqn_for_login(tiqn);
1268-
conn->tpg = NULL;
1269-
ret = -1;
1270-
goto out;
1271-
}
1254+
12721255
/*
12731256
* Serialize access across the struct iscsi_portal_group to
12741257
* process login attempt.

0 commit comments

Comments
 (0)