Skip to content

Commit 21f82ac

Browse files
rmchelsiokuba-moo
authored andcommitted
ch_ktls/cxgb4: handle partial tag alone SKBs
If TCP congestion caused a very small packets which only has some part fo the TAG, and that too is not till the end. HW can't handle such case, so falling back to sw crypto in such cases. v1->v2: - Marked chcr_ktls_sw_fallback() static. Fixes: dc05f3d ("chcr: Handle first or middle part of record") Signed-off-by: Rohit Maheshwari <rohitm@chelsio.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 659bf03 commit 21f82ac

4 files changed

Lines changed: 119 additions & 1 deletion

File tree

drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3573,6 +3573,8 @@ static int chcr_stats_show(struct seq_file *seq, void *v)
35733573
atomic64_read(&adap->ch_ktls_stats.ktls_tx_complete_pkts));
35743574
seq_printf(seq, "TX trim pkts : %20llu\n",
35753575
atomic64_read(&adap->ch_ktls_stats.ktls_tx_trimmed_pkts));
3576+
seq_printf(seq, "TX sw fallback : %20llu\n",
3577+
atomic64_read(&adap->ch_ktls_stats.ktls_tx_fallback));
35763578
while (i < MAX_NPORTS) {
35773579
ktls_port = &adap->ch_ktls_stats.ktls_port[i];
35783580
seq_printf(seq, "Port %d\n", i);

drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ struct ch_ktls_stats_debug {
388388
atomic64_t ktls_tx_retransmit_pkts;
389389
atomic64_t ktls_tx_complete_pkts;
390390
atomic64_t ktls_tx_trimmed_pkts;
391+
atomic64_t ktls_tx_fallback;
391392
};
392393
#endif
393394

drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1545,6 +1545,88 @@ static int chcr_ktls_tx_plaintxt(struct chcr_ktls_info *tx_info,
15451545
return 0;
15461546
}
15471547

1548+
static int chcr_ktls_tunnel_pkt(struct chcr_ktls_info *tx_info,
1549+
struct sk_buff *skb,
1550+
struct sge_eth_txq *q)
1551+
{
1552+
u32 ctrl, iplen, maclen, wr_mid = 0, len16;
1553+
struct tx_sw_desc *sgl_sdesc;
1554+
struct fw_eth_tx_pkt_wr *wr;
1555+
struct cpl_tx_pkt_core *cpl;
1556+
unsigned int flits, ndesc;
1557+
int credits, last_desc;
1558+
u64 cntrl1, *end;
1559+
void *pos;
1560+
1561+
ctrl = sizeof(*cpl);
1562+
flits = DIV_ROUND_UP(sizeof(*wr) + ctrl, 8);
1563+
1564+
flits += chcr_sgl_len(skb_shinfo(skb)->nr_frags + 1);
1565+
len16 = DIV_ROUND_UP(flits, 2);
1566+
/* check how many descriptors needed */
1567+
ndesc = DIV_ROUND_UP(flits, 8);
1568+
1569+
credits = chcr_txq_avail(&q->q) - ndesc;
1570+
if (unlikely(credits < 0)) {
1571+
chcr_eth_txq_stop(q);
1572+
return -ENOMEM;
1573+
}
1574+
1575+
if (unlikely(credits < ETHTXQ_STOP_THRES)) {
1576+
chcr_eth_txq_stop(q);
1577+
wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F;
1578+
}
1579+
1580+
last_desc = q->q.pidx + ndesc - 1;
1581+
if (last_desc >= q->q.size)
1582+
last_desc -= q->q.size;
1583+
sgl_sdesc = &q->q.sdesc[last_desc];
1584+
1585+
if (unlikely(cxgb4_map_skb(tx_info->adap->pdev_dev, skb,
1586+
sgl_sdesc->addr) < 0)) {
1587+
memset(sgl_sdesc->addr, 0, sizeof(sgl_sdesc->addr));
1588+
q->mapping_err++;
1589+
return -ENOMEM;
1590+
}
1591+
1592+
iplen = skb_network_header_len(skb);
1593+
maclen = skb_mac_header_len(skb);
1594+
1595+
pos = &q->q.desc[q->q.pidx];
1596+
end = (u64 *)pos + flits;
1597+
wr = pos;
1598+
1599+
/* Firmware work request header */
1600+
wr->op_immdlen = htonl(FW_WR_OP_V(FW_ETH_TX_PKT_WR) |
1601+
FW_WR_IMMDLEN_V(ctrl));
1602+
1603+
wr->equiq_to_len16 = htonl(wr_mid | FW_WR_LEN16_V(len16));
1604+
wr->r3 = 0;
1605+
1606+
cpl = (void *)(wr + 1);
1607+
1608+
/* CPL header */
1609+
cpl->ctrl0 = htonl(TXPKT_OPCODE_V(CPL_TX_PKT) |
1610+
TXPKT_INTF_V(tx_info->tx_chan) |
1611+
TXPKT_PF_V(tx_info->adap->pf));
1612+
cpl->pack = 0;
1613+
cntrl1 = TXPKT_CSUM_TYPE_V(tx_info->ip_family == AF_INET ?
1614+
TX_CSUM_TCPIP : TX_CSUM_TCPIP6);
1615+
cntrl1 |= T6_TXPKT_ETHHDR_LEN_V(maclen - ETH_HLEN) |
1616+
TXPKT_IPHDR_LEN_V(iplen);
1617+
/* checksum offload */
1618+
cpl->ctrl1 = cpu_to_be64(cntrl1);
1619+
cpl->len = htons(skb->len);
1620+
1621+
pos = cpl + 1;
1622+
1623+
cxgb4_write_sgl(skb, &q->q, pos, end, 0, sgl_sdesc->addr);
1624+
sgl_sdesc->skb = skb;
1625+
chcr_txq_advance(&q->q, ndesc);
1626+
cxgb4_ring_tx_db(tx_info->adap, &q->q, ndesc);
1627+
return 0;
1628+
}
1629+
15481630
/*
15491631
* chcr_ktls_copy_record_in_skb
15501632
* @nskb - new skb where the frags to be added.
@@ -1733,7 +1815,7 @@ static int chcr_short_record_handler(struct chcr_ktls_info *tx_info,
17331815
(TLS_CIPHER_AES_GCM_128_TAG_SIZE -
17341816
remaining_record);
17351817
if (!trimmed_len)
1736-
goto out;
1818+
return FALLBACK;
17371819

17381820
WARN_ON(trimmed_len > data_len);
17391821

@@ -1837,6 +1919,34 @@ static int chcr_short_record_handler(struct chcr_ktls_info *tx_info,
18371919
return NETDEV_TX_BUSY;
18381920
}
18391921

1922+
static int chcr_ktls_sw_fallback(struct sk_buff *skb,
1923+
struct chcr_ktls_info *tx_info,
1924+
struct sge_eth_txq *q)
1925+
{
1926+
u32 data_len, skb_offset;
1927+
struct sk_buff *nskb;
1928+
struct tcphdr *th;
1929+
1930+
nskb = tls_encrypt_skb(skb);
1931+
1932+
if (!nskb)
1933+
return 0;
1934+
1935+
th = tcp_hdr(nskb);
1936+
skb_offset = skb_transport_offset(nskb) + tcp_hdrlen(nskb);
1937+
data_len = nskb->len - skb_offset;
1938+
skb_tx_timestamp(nskb);
1939+
1940+
if (chcr_ktls_tunnel_pkt(tx_info, nskb, q))
1941+
goto out;
1942+
1943+
tx_info->prev_seq = ntohl(th->seq) + data_len;
1944+
atomic64_inc(&tx_info->adap->ch_ktls_stats.ktls_tx_fallback);
1945+
return 0;
1946+
out:
1947+
dev_kfree_skb_any(nskb);
1948+
return 0;
1949+
}
18401950
/* nic tls TX handler */
18411951
static int chcr_ktls_xmit(struct sk_buff *skb, struct net_device *dev)
18421952
{
@@ -2012,6 +2122,10 @@ static int chcr_ktls_xmit(struct sk_buff *skb, struct net_device *dev)
20122122
if (ret) {
20132123
if (th->fin)
20142124
dev_kfree_skb_any(skb);
2125+
2126+
if (ret == FALLBACK)
2127+
return chcr_ktls_sw_fallback(skb, tx_info, q);
2128+
20152129
return NETDEV_TX_OK;
20162130
}
20172131

drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#define CHCR_KTLS_WR_SIZE (CHCR_PLAIN_TX_DATA_LEN +\
2828
sizeof(struct cpl_tx_sec_pdu))
29+
#define FALLBACK 35
2930

3031
enum ch_ktls_open_state {
3132
CH_KTLS_OPEN_SUCCESS = 0,

0 commit comments

Comments
 (0)