Skip to content

Commit 79e57cf

Browse files
Varun PrakashNicholas Bellinger
authored andcommitted
target/cxgbit: add T6 iSCSI DDP completion feature
Chelsio T6 adapters reduce number of completion to host by generating single completion for all directly placed(DDP) iSCSI pdus in a sequence, completion contains iSCSI hdr of the last pdu in a sequence. On receiving DDP completion cxgbit driver finds iSCSI cmd using iscsit_find_cmd_from_itt_or_dump(), then updates cmd->write_data_done, cmd->next_burst_len, cmd->data_sn and calls __iscsit_check_dataout_hdr() to validate iSCSI hdr. (Update __iscsit_check_dataout_hdr parameter usage - nab) Signed-off-by: Varun Prakash <[email protected]> Signed-off-by: Bart Van Assche <[email protected]> Signed-off-by: Nicholas Bellinger <[email protected]>
1 parent 5248788 commit 79e57cf

File tree

4 files changed

+113
-43
lines changed

4 files changed

+113
-43
lines changed

drivers/target/iscsi/cxgbit/cxgbit_cm.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,9 @@ cxgbit_pass_accept_rpl(struct cxgbit_sock *csk, struct cpl_pass_accept_req *req)
11141114
opt2 = RX_CHANNEL_V(0) |
11151115
RSS_QUEUE_VALID_F | RSS_QUEUE_V(csk->rss_qid);
11161116

1117+
if (!is_t5(lldi->adapter_type))
1118+
opt2 |= RX_FC_DISABLE_F;
1119+
11171120
if (req->tcpopt.tstamp)
11181121
opt2 |= TSTAMPS_EN_F;
11191122
if (req->tcpopt.sack)

drivers/target/iscsi/cxgbit/cxgbit_lro.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ enum cxgbit_pducb_flags {
3131
PDUCBF_RX_DATA = (1 << 1), /* received pdu payload */
3232
PDUCBF_RX_STATUS = (1 << 2), /* received ddp status */
3333
PDUCBF_RX_DATA_DDPD = (1 << 3), /* pdu payload ddp'd */
34-
PDUCBF_RX_HCRC_ERR = (1 << 4), /* header digest error */
35-
PDUCBF_RX_DCRC_ERR = (1 << 5), /* data digest error */
34+
PDUCBF_RX_DDP_CMP = (1 << 4), /* ddp completion */
35+
PDUCBF_RX_HCRC_ERR = (1 << 5), /* header digest error */
36+
PDUCBF_RX_DCRC_ERR = (1 << 6), /* data digest error */
3637
};
3738

3839
struct cxgbit_lro_pdu_cb {

drivers/target/iscsi/cxgbit/cxgbit_main.c

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -165,29 +165,24 @@ static int cxgbit_uld_state_change(void *handle, enum cxgb4_state state)
165165
}
166166

167167
static void
168-
cxgbit_proc_ddp_status(unsigned int tid, struct cpl_rx_data_ddp *cpl,
169-
struct cxgbit_lro_pdu_cb *pdu_cb)
168+
cxgbit_process_ddpvld(struct cxgbit_sock *csk, struct cxgbit_lro_pdu_cb *pdu_cb,
169+
u32 ddpvld)
170170
{
171-
unsigned int status = ntohl(cpl->ddpvld);
172171

173-
pdu_cb->flags |= PDUCBF_RX_STATUS;
174-
pdu_cb->ddigest = ntohl(cpl->ulp_crc);
175-
pdu_cb->pdulen = ntohs(cpl->len);
176-
177-
if (status & (1 << CPL_RX_ISCSI_DDP_STATUS_HCRC_SHIFT)) {
178-
pr_info("tid 0x%x, status 0x%x, hcrc bad.\n", tid, status);
172+
if (ddpvld & (1 << CPL_RX_ISCSI_DDP_STATUS_HCRC_SHIFT)) {
173+
pr_info("tid 0x%x, status 0x%x, hcrc bad.\n", csk->tid, ddpvld);
179174
pdu_cb->flags |= PDUCBF_RX_HCRC_ERR;
180175
}
181176

182-
if (status & (1 << CPL_RX_ISCSI_DDP_STATUS_DCRC_SHIFT)) {
183-
pr_info("tid 0x%x, status 0x%x, dcrc bad.\n", tid, status);
177+
if (ddpvld & (1 << CPL_RX_ISCSI_DDP_STATUS_DCRC_SHIFT)) {
178+
pr_info("tid 0x%x, status 0x%x, dcrc bad.\n", csk->tid, ddpvld);
184179
pdu_cb->flags |= PDUCBF_RX_DCRC_ERR;
185180
}
186181

187-
if (status & (1 << CPL_RX_ISCSI_DDP_STATUS_PAD_SHIFT))
188-
pr_info("tid 0x%x, status 0x%x, pad bad.\n", tid, status);
182+
if (ddpvld & (1 << CPL_RX_ISCSI_DDP_STATUS_PAD_SHIFT))
183+
pr_info("tid 0x%x, status 0x%x, pad bad.\n", csk->tid, ddpvld);
189184

190-
if ((status & (1 << CPL_RX_ISCSI_DDP_STATUS_DDP_SHIFT)) &&
185+
if ((ddpvld & (1 << CPL_RX_ISCSI_DDP_STATUS_DDP_SHIFT)) &&
191186
(!(pdu_cb->flags & PDUCBF_RX_DATA))) {
192187
pdu_cb->flags |= PDUCBF_RX_DATA_DDPD;
193188
}
@@ -201,13 +196,17 @@ cxgbit_lro_add_packet_rsp(struct sk_buff *skb, u8 op, const __be64 *rsp)
201196
lro_cb->pdu_idx);
202197
struct cpl_rx_iscsi_ddp *cpl = (struct cpl_rx_iscsi_ddp *)(rsp + 1);
203198

204-
cxgbit_proc_ddp_status(lro_cb->csk->tid, cpl, pdu_cb);
199+
cxgbit_process_ddpvld(lro_cb->csk, pdu_cb, be32_to_cpu(cpl->ddpvld));
200+
201+
pdu_cb->flags |= PDUCBF_RX_STATUS;
202+
pdu_cb->ddigest = ntohl(cpl->ulp_crc);
203+
pdu_cb->pdulen = ntohs(cpl->len);
205204

206205
if (pdu_cb->flags & PDUCBF_RX_HDR)
207206
pdu_cb->complete = true;
208207

209-
lro_cb->complete = true;
210208
lro_cb->pdu_totallen += pdu_cb->pdulen;
209+
lro_cb->complete = true;
211210
lro_cb->pdu_idx++;
212211
}
213212

@@ -257,7 +256,7 @@ cxgbit_lro_add_packet_gl(struct sk_buff *skb, u8 op, const struct pkt_gl *gl)
257256
cxgbit_skcb_flags(skb) = 0;
258257

259258
lro_cb->complete = false;
260-
} else {
259+
} else if (op == CPL_ISCSI_DATA) {
261260
struct cpl_iscsi_data *cpl = (struct cpl_iscsi_data *)gl->va;
262261

263262
offset = sizeof(struct cpl_iscsi_data);
@@ -267,6 +266,36 @@ cxgbit_lro_add_packet_gl(struct sk_buff *skb, u8 op, const struct pkt_gl *gl)
267266
pdu_cb->doffset = lro_cb->offset;
268267
pdu_cb->nr_dfrags = gl->nfrags;
269268
pdu_cb->dfrag_idx = skb_shinfo(skb)->nr_frags;
269+
lro_cb->complete = false;
270+
} else {
271+
struct cpl_rx_iscsi_cmp *cpl;
272+
273+
cpl = (struct cpl_rx_iscsi_cmp *)gl->va;
274+
offset = sizeof(struct cpl_rx_iscsi_cmp);
275+
pdu_cb->flags |= (PDUCBF_RX_HDR | PDUCBF_RX_STATUS);
276+
len = be16_to_cpu(cpl->len);
277+
pdu_cb->hdr = gl->va + offset;
278+
pdu_cb->hlen = len;
279+
pdu_cb->hfrag_idx = skb_shinfo(skb)->nr_frags;
280+
pdu_cb->ddigest = be32_to_cpu(cpl->ulp_crc);
281+
pdu_cb->pdulen = ntohs(cpl->len);
282+
283+
if (unlikely(gl->nfrags > 1))
284+
cxgbit_skcb_flags(skb) = 0;
285+
286+
cxgbit_process_ddpvld(lro_cb->csk, pdu_cb,
287+
be32_to_cpu(cpl->ddpvld));
288+
289+
if (pdu_cb->flags & PDUCBF_RX_DATA_DDPD) {
290+
pdu_cb->flags |= PDUCBF_RX_DDP_CMP;
291+
pdu_cb->complete = true;
292+
} else if (pdu_cb->flags & PDUCBF_RX_DATA) {
293+
pdu_cb->complete = true;
294+
}
295+
296+
lro_cb->pdu_totallen += pdu_cb->hlen + pdu_cb->dlen;
297+
lro_cb->complete = true;
298+
lro_cb->pdu_idx++;
270299
}
271300

272301
cxgbit_copy_frags(skb, gl, offset);
@@ -413,6 +442,7 @@ cxgbit_uld_lro_rx_handler(void *hndl, const __be64 *rsp,
413442
switch (op) {
414443
case CPL_ISCSI_HDR:
415444
case CPL_ISCSI_DATA:
445+
case CPL_RX_ISCSI_CMP:
416446
case CPL_RX_ISCSI_DDP:
417447
case CPL_FW4_ACK:
418448
lro_flush = false;
@@ -459,7 +489,8 @@ cxgbit_uld_lro_rx_handler(void *hndl, const __be64 *rsp,
459489
return 0;
460490
}
461491

462-
if (op == CPL_ISCSI_HDR || op == CPL_ISCSI_DATA) {
492+
if ((op == CPL_ISCSI_HDR) || (op == CPL_ISCSI_DATA) ||
493+
(op == CPL_RX_ISCSI_CMP)) {
463494
if (!cxgbit_lro_receive(csk, op, rsp, gl, lro_mgr,
464495
napi))
465496
return 0;

drivers/target/iscsi/cxgbit/cxgbit_target.c

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,11 +1021,36 @@ static int cxgbit_handle_iscsi_dataout(struct cxgbit_sock *csk)
10211021
int rc, sg_nents, sg_off;
10221022
bool dcrc_err = false;
10231023

1024-
rc = iscsit_check_dataout_hdr(conn, (unsigned char *)hdr, &cmd);
1025-
if (rc < 0)
1026-
return rc;
1027-
else if (!cmd)
1028-
return 0;
1024+
if (pdu_cb->flags & PDUCBF_RX_DDP_CMP) {
1025+
u32 offset = be32_to_cpu(hdr->offset);
1026+
u32 ddp_data_len;
1027+
u32 payload_length = ntoh24(hdr->dlength);
1028+
bool success = false;
1029+
1030+
cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt, 0);
1031+
if (!cmd)
1032+
return 0;
1033+
1034+
ddp_data_len = offset - cmd->write_data_done;
1035+
atomic_long_add(ddp_data_len, &conn->sess->rx_data_octets);
1036+
1037+
cmd->write_data_done = offset;
1038+
cmd->next_burst_len = ddp_data_len;
1039+
cmd->data_sn = be32_to_cpu(hdr->datasn);
1040+
1041+
rc = __iscsit_check_dataout_hdr(conn, (unsigned char *)hdr,
1042+
cmd, payload_length, &success);
1043+
if (rc < 0)
1044+
return rc;
1045+
else if (!success)
1046+
return 0;
1047+
} else {
1048+
rc = iscsit_check_dataout_hdr(conn, (unsigned char *)hdr, &cmd);
1049+
if (rc < 0)
1050+
return rc;
1051+
else if (!cmd)
1052+
return 0;
1053+
}
10291054

10301055
if (pdu_cb->flags & PDUCBF_RX_DCRC_ERR) {
10311056
pr_err("ITT: 0x%08x, Offset: %u, Length: %u,"
@@ -1389,6 +1414,9 @@ static void cxgbit_lro_hskb_reset(struct cxgbit_sock *csk)
13891414
for (i = 0; i < ssi->nr_frags; i++)
13901415
put_page(skb_frag_page(&ssi->frags[i]));
13911416
ssi->nr_frags = 0;
1417+
skb->data_len = 0;
1418+
skb->truesize -= skb->len;
1419+
skb->len = 0;
13921420
}
13931421

13941422
static void
@@ -1402,39 +1430,42 @@ cxgbit_lro_skb_merge(struct cxgbit_sock *csk, struct sk_buff *skb, u8 pdu_idx)
14021430
unsigned int len = 0;
14031431

14041432
if (pdu_cb->flags & PDUCBF_RX_HDR) {
1405-
hpdu_cb->flags = pdu_cb->flags;
1433+
u8 hfrag_idx = hssi->nr_frags;
1434+
1435+
hpdu_cb->flags |= pdu_cb->flags;
14061436
hpdu_cb->seq = pdu_cb->seq;
14071437
hpdu_cb->hdr = pdu_cb->hdr;
14081438
hpdu_cb->hlen = pdu_cb->hlen;
14091439

1410-
memcpy(&hssi->frags[0], &ssi->frags[pdu_cb->hfrag_idx],
1440+
memcpy(&hssi->frags[hfrag_idx], &ssi->frags[pdu_cb->hfrag_idx],
14111441
sizeof(skb_frag_t));
14121442

1413-
get_page(skb_frag_page(&hssi->frags[0]));
1414-
hssi->nr_frags = 1;
1415-
hpdu_cb->frags = 1;
1416-
hpdu_cb->hfrag_idx = 0;
1443+
get_page(skb_frag_page(&hssi->frags[hfrag_idx]));
1444+
hssi->nr_frags++;
1445+
hpdu_cb->frags++;
1446+
hpdu_cb->hfrag_idx = hfrag_idx;
14171447

1418-
len = hssi->frags[0].size;
1419-
hskb->len = len;
1420-
hskb->data_len = len;
1421-
hskb->truesize = len;
1448+
len = hssi->frags[hfrag_idx].size;
1449+
hskb->len += len;
1450+
hskb->data_len += len;
1451+
hskb->truesize += len;
14221452
}
14231453

14241454
if (pdu_cb->flags & PDUCBF_RX_DATA) {
1425-
u8 hfrag_idx = 1, i;
1455+
u8 dfrag_idx = hssi->nr_frags, i;
14261456

14271457
hpdu_cb->flags |= pdu_cb->flags;
1458+
hpdu_cb->dfrag_idx = dfrag_idx;
14281459

14291460
len = 0;
1430-
for (i = 0; i < pdu_cb->nr_dfrags; hfrag_idx++, i++) {
1431-
memcpy(&hssi->frags[hfrag_idx],
1461+
for (i = 0; i < pdu_cb->nr_dfrags; dfrag_idx++, i++) {
1462+
memcpy(&hssi->frags[dfrag_idx],
14321463
&ssi->frags[pdu_cb->dfrag_idx + i],
14331464
sizeof(skb_frag_t));
14341465

1435-
get_page(skb_frag_page(&hssi->frags[hfrag_idx]));
1466+
get_page(skb_frag_page(&hssi->frags[dfrag_idx]));
14361467

1437-
len += hssi->frags[hfrag_idx].size;
1468+
len += hssi->frags[dfrag_idx].size;
14381469

14391470
hssi->nr_frags++;
14401471
hpdu_cb->frags++;
@@ -1443,7 +1474,6 @@ cxgbit_lro_skb_merge(struct cxgbit_sock *csk, struct sk_buff *skb, u8 pdu_idx)
14431474
hpdu_cb->dlen = pdu_cb->dlen;
14441475
hpdu_cb->doffset = hpdu_cb->hlen;
14451476
hpdu_cb->nr_dfrags = pdu_cb->nr_dfrags;
1446-
hpdu_cb->dfrag_idx = 1;
14471477
hskb->len += len;
14481478
hskb->data_len += len;
14491479
hskb->truesize += len;
@@ -1528,10 +1558,15 @@ static int cxgbit_rx_lro_skb(struct cxgbit_sock *csk, struct sk_buff *skb)
15281558

15291559
static int cxgbit_rx_skb(struct cxgbit_sock *csk, struct sk_buff *skb)
15301560
{
1561+
struct cxgb4_lld_info *lldi = &csk->com.cdev->lldi;
15311562
int ret = -1;
15321563

1533-
if (likely(cxgbit_skcb_flags(skb) & SKCBF_RX_LRO))
1534-
ret = cxgbit_rx_lro_skb(csk, skb);
1564+
if (likely(cxgbit_skcb_flags(skb) & SKCBF_RX_LRO)) {
1565+
if (is_t5(lldi->adapter_type))
1566+
ret = cxgbit_rx_lro_skb(csk, skb);
1567+
else
1568+
ret = cxgbit_process_lro_skb(csk, skb);
1569+
}
15351570

15361571
__kfree_skb(skb);
15371572
return ret;

0 commit comments

Comments
 (0)