@@ -44,6 +44,8 @@ struct nvme_tcp_request {
44
44
u32 data_len ;
45
45
u32 pdu_len ;
46
46
u32 pdu_sent ;
47
+ u32 h2cdata_left ;
48
+ u32 h2cdata_offset ;
47
49
u16 ttag ;
48
50
__le16 status ;
49
51
struct list_head entry ;
@@ -95,6 +97,7 @@ struct nvme_tcp_queue {
95
97
struct nvme_tcp_request * request ;
96
98
97
99
int queue_size ;
100
+ u32 maxh2cdata ;
98
101
size_t cmnd_capsule_len ;
99
102
struct nvme_tcp_ctrl * ctrl ;
100
103
unsigned long flags ;
@@ -572,23 +575,26 @@ static int nvme_tcp_handle_comp(struct nvme_tcp_queue *queue,
572
575
return ret ;
573
576
}
574
577
575
- static void nvme_tcp_setup_h2c_data_pdu (struct nvme_tcp_request * req ,
576
- struct nvme_tcp_r2t_pdu * pdu )
578
+ static void nvme_tcp_setup_h2c_data_pdu (struct nvme_tcp_request * req )
577
579
{
578
580
struct nvme_tcp_data_pdu * data = req -> pdu ;
579
581
struct nvme_tcp_queue * queue = req -> queue ;
580
582
struct request * rq = blk_mq_rq_from_pdu (req );
583
+ u32 h2cdata_sent = req -> pdu_len ;
581
584
u8 hdgst = nvme_tcp_hdgst_len (queue );
582
585
u8 ddgst = nvme_tcp_ddgst_len (queue );
583
586
584
587
req -> state = NVME_TCP_SEND_H2C_PDU ;
585
588
req -> offset = 0 ;
586
- req -> pdu_len = le32_to_cpu ( pdu -> r2t_length );
589
+ req -> pdu_len = min ( req -> h2cdata_left , queue -> maxh2cdata );
587
590
req -> pdu_sent = 0 ;
591
+ req -> h2cdata_left -= req -> pdu_len ;
592
+ req -> h2cdata_offset += h2cdata_sent ;
588
593
589
594
memset (data , 0 , sizeof (* data ));
590
595
data -> hdr .type = nvme_tcp_h2c_data ;
591
- data -> hdr .flags = NVME_TCP_F_DATA_LAST ;
596
+ if (!req -> h2cdata_left )
597
+ data -> hdr .flags = NVME_TCP_F_DATA_LAST ;
592
598
if (queue -> hdr_digest )
593
599
data -> hdr .flags |= NVME_TCP_F_HDGST ;
594
600
if (queue -> data_digest )
@@ -597,9 +603,9 @@ static void nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req,
597
603
data -> hdr .pdo = data -> hdr .hlen + hdgst ;
598
604
data -> hdr .plen =
599
605
cpu_to_le32 (data -> hdr .hlen + hdgst + req -> pdu_len + ddgst );
600
- data -> ttag = pdu -> ttag ;
606
+ data -> ttag = req -> ttag ;
601
607
data -> command_id = nvme_cid (rq );
602
- data -> data_offset = pdu -> r2t_offset ;
608
+ data -> data_offset = cpu_to_le32 ( req -> h2cdata_offset ) ;
603
609
data -> data_length = cpu_to_le32 (req -> pdu_len );
604
610
}
605
611
@@ -609,6 +615,7 @@ static int nvme_tcp_handle_r2t(struct nvme_tcp_queue *queue,
609
615
struct nvme_tcp_request * req ;
610
616
struct request * rq ;
611
617
u32 r2t_length = le32_to_cpu (pdu -> r2t_length );
618
+ u32 r2t_offset = le32_to_cpu (pdu -> r2t_offset );
612
619
613
620
rq = nvme_find_rq (nvme_tcp_tagset (queue ), pdu -> command_id );
614
621
if (!rq ) {
@@ -633,14 +640,19 @@ static int nvme_tcp_handle_r2t(struct nvme_tcp_queue *queue,
633
640
return - EPROTO ;
634
641
}
635
642
636
- if (unlikely (le32_to_cpu ( pdu -> r2t_offset ) < req -> data_sent )) {
643
+ if (unlikely (r2t_offset < req -> data_sent )) {
637
644
dev_err (queue -> ctrl -> ctrl .device ,
638
645
"req %d unexpected r2t offset %u (expected %zu)\n" ,
639
- rq -> tag , le32_to_cpu ( pdu -> r2t_offset ) , req -> data_sent );
646
+ rq -> tag , r2t_offset , req -> data_sent );
640
647
return - EPROTO ;
641
648
}
642
649
643
- nvme_tcp_setup_h2c_data_pdu (req , pdu );
650
+ req -> pdu_len = 0 ;
651
+ req -> h2cdata_left = r2t_length ;
652
+ req -> h2cdata_offset = r2t_offset ;
653
+ req -> ttag = pdu -> ttag ;
654
+
655
+ nvme_tcp_setup_h2c_data_pdu (req );
644
656
nvme_tcp_queue_request (req , false, true);
645
657
646
658
return 0 ;
@@ -928,6 +940,7 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req)
928
940
{
929
941
struct nvme_tcp_queue * queue = req -> queue ;
930
942
int req_data_len = req -> data_len ;
943
+ u32 h2cdata_left = req -> h2cdata_left ;
931
944
932
945
while (true) {
933
946
struct page * page = nvme_tcp_req_cur_page (req );
@@ -972,7 +985,10 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req)
972
985
req -> state = NVME_TCP_SEND_DDGST ;
973
986
req -> offset = 0 ;
974
987
} else {
975
- nvme_tcp_done_send_req (queue );
988
+ if (h2cdata_left )
989
+ nvme_tcp_setup_h2c_data_pdu (req );
990
+ else
991
+ nvme_tcp_done_send_req (queue );
976
992
}
977
993
return 1 ;
978
994
}
@@ -1030,9 +1046,14 @@ static int nvme_tcp_try_send_data_pdu(struct nvme_tcp_request *req)
1030
1046
if (queue -> hdr_digest && !req -> offset )
1031
1047
nvme_tcp_hdgst (queue -> snd_hash , pdu , sizeof (* pdu ));
1032
1048
1033
- ret = kernel_sendpage (queue -> sock , virt_to_page (pdu ),
1034
- offset_in_page (pdu ) + req -> offset , len ,
1035
- MSG_DONTWAIT | MSG_MORE | MSG_SENDPAGE_NOTLAST );
1049
+ if (!req -> h2cdata_left )
1050
+ ret = kernel_sendpage (queue -> sock , virt_to_page (pdu ),
1051
+ offset_in_page (pdu ) + req -> offset , len ,
1052
+ MSG_DONTWAIT | MSG_MORE | MSG_SENDPAGE_NOTLAST );
1053
+ else
1054
+ ret = sock_no_sendpage (queue -> sock , virt_to_page (pdu ),
1055
+ offset_in_page (pdu ) + req -> offset , len ,
1056
+ MSG_DONTWAIT | MSG_MORE );
1036
1057
if (unlikely (ret <= 0 ))
1037
1058
return ret ;
1038
1059
@@ -1052,6 +1073,7 @@ static int nvme_tcp_try_send_ddgst(struct nvme_tcp_request *req)
1052
1073
{
1053
1074
struct nvme_tcp_queue * queue = req -> queue ;
1054
1075
size_t offset = req -> offset ;
1076
+ u32 h2cdata_left = req -> h2cdata_left ;
1055
1077
int ret ;
1056
1078
struct msghdr msg = { .msg_flags = MSG_DONTWAIT };
1057
1079
struct kvec iov = {
@@ -1069,7 +1091,10 @@ static int nvme_tcp_try_send_ddgst(struct nvme_tcp_request *req)
1069
1091
return ret ;
1070
1092
1071
1093
if (offset + ret == NVME_TCP_DIGEST_LENGTH ) {
1072
- nvme_tcp_done_send_req (queue );
1094
+ if (h2cdata_left )
1095
+ nvme_tcp_setup_h2c_data_pdu (req );
1096
+ else
1097
+ nvme_tcp_done_send_req (queue );
1073
1098
return 1 ;
1074
1099
}
1075
1100
@@ -1261,6 +1286,7 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
1261
1286
struct msghdr msg = {};
1262
1287
struct kvec iov ;
1263
1288
bool ctrl_hdgst , ctrl_ddgst ;
1289
+ u32 maxh2cdata ;
1264
1290
int ret ;
1265
1291
1266
1292
icreq = kzalloc (sizeof (* icreq ), GFP_KERNEL );
@@ -1344,6 +1370,14 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
1344
1370
goto free_icresp ;
1345
1371
}
1346
1372
1373
+ maxh2cdata = le32_to_cpu (icresp -> maxdata );
1374
+ if ((maxh2cdata % 4 ) || (maxh2cdata < NVME_TCP_MIN_MAXH2CDATA )) {
1375
+ pr_err ("queue %d: invalid maxh2cdata returned %u\n" ,
1376
+ nvme_tcp_queue_id (queue ), maxh2cdata );
1377
+ goto free_icresp ;
1378
+ }
1379
+ queue -> maxh2cdata = maxh2cdata ;
1380
+
1347
1381
ret = 0 ;
1348
1382
free_icresp :
1349
1383
kfree (icresp );
@@ -2329,6 +2363,7 @@ static blk_status_t nvme_tcp_setup_cmd_pdu(struct nvme_ns *ns,
2329
2363
req -> data_sent = 0 ;
2330
2364
req -> pdu_len = 0 ;
2331
2365
req -> pdu_sent = 0 ;
2366
+ req -> h2cdata_left = 0 ;
2332
2367
req -> data_len = blk_rq_nr_phys_segments (rq ) ?
2333
2368
blk_rq_payload_bytes (rq ) : 0 ;
2334
2369
req -> curr_bio = rq -> bio ;
0 commit comments