Skip to content

Commit 0ed96b4

Browse files
chelsiocudbgJakub Kicinski
authored andcommitted
cxgb4/chcr: update SGL DMA unmap for USO
The FW_ETH_TX_EO_WR used for sending UDP Segmentation Offload (USO) requests expects the headers to be part of the descriptor and the payload to be part of the SGL containing the DMA mapped addresses. Hence, the DMA address in the first entry of the SGL can start after the packet headers. Currently, unmap_sgl() tries to unmap from this wrong offset, instead of the originally mapped DMA address. So, use existing unmap_skb() instead, which takes originally saved DMA addresses as input. Update all necessary Tx paths to save the original DMA addresses, so that unmap_skb() can unmap them properly. v2: - No change. Signed-off-by: Rahul Lakkireddy <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent a9f852e commit 0ed96b4

File tree

4 files changed

+52
-115
lines changed

4 files changed

+52
-115
lines changed

drivers/crypto/chelsio/chcr_ipsec.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -673,16 +673,16 @@ static inline void txq_advance(struct sge_txq *q, unsigned int n)
673673
int chcr_ipsec_xmit(struct sk_buff *skb, struct net_device *dev)
674674
{
675675
struct xfrm_state *x = xfrm_input_state(skb);
676+
unsigned int last_desc, ndesc, flits = 0;
676677
struct ipsec_sa_entry *sa_entry;
677678
u64 *pos, *end, *before, *sgl;
679+
struct tx_sw_desc *sgl_sdesc;
678680
int qidx, left, credits;
679-
unsigned int flits = 0, ndesc;
680-
struct adapter *adap;
681+
bool immediate = false;
681682
struct sge_eth_txq *q;
683+
struct adapter *adap;
682684
struct port_info *pi;
683-
dma_addr_t addr[MAX_SKB_FRAGS + 1];
684685
struct sec_path *sp;
685-
bool immediate = false;
686686

687687
if (!x->xso.offload_handle)
688688
return NETDEV_TX_BUSY;
@@ -715,8 +715,14 @@ out_free: dev_kfree_skb_any(skb);
715715
return NETDEV_TX_BUSY;
716716
}
717717

718+
last_desc = q->q.pidx + ndesc - 1;
719+
if (last_desc >= q->q.size)
720+
last_desc -= q->q.size;
721+
sgl_sdesc = &q->q.sdesc[last_desc];
722+
718723
if (!immediate &&
719-
unlikely(cxgb4_map_skb(adap->pdev_dev, skb, addr) < 0)) {
724+
unlikely(cxgb4_map_skb(adap->pdev_dev, skb, sgl_sdesc->addr) < 0)) {
725+
memset(sgl_sdesc->addr, 0, sizeof(sgl_sdesc->addr));
720726
q->mapping_err++;
721727
goto out_free;
722728
}
@@ -742,17 +748,10 @@ out_free: dev_kfree_skb_any(skb);
742748
cxgb4_inline_tx_skb(skb, &q->q, sgl);
743749
dev_consume_skb_any(skb);
744750
} else {
745-
int last_desc;
746-
747751
cxgb4_write_sgl(skb, &q->q, (void *)sgl, end,
748-
0, addr);
752+
0, sgl_sdesc->addr);
749753
skb_orphan(skb);
750-
751-
last_desc = q->q.pidx + ndesc - 1;
752-
if (last_desc >= q->q.size)
753-
last_desc -= q->q.size;
754-
q->q.sdesc[last_desc].skb = skb;
755-
q->q.sdesc[last_desc].sgl = (struct ulptx_sgl *)sgl;
754+
sgl_sdesc->skb = skb;
756755
}
757756
txq_advance(&q->q, ndesc);
758757

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

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,12 @@ struct tx_desc {
735735
__be64 flit[8];
736736
};
737737

738-
struct tx_sw_desc;
738+
struct ulptx_sgl;
739+
740+
struct tx_sw_desc {
741+
struct sk_buff *skb; /* SKB to free after getting completion */
742+
dma_addr_t addr[MAX_SKB_FRAGS + 1]; /* DMA mapped addresses */
743+
};
739744

740745
struct sge_txq {
741746
unsigned int in_use; /* # of in-use Tx descriptors */
@@ -814,15 +819,10 @@ enum sge_eosw_state {
814819
CXGB4_EO_STATE_FLOWC_CLOSE_REPLY, /* Waiting for FLOWC close reply */
815820
};
816821

817-
struct sge_eosw_desc {
818-
struct sk_buff *skb; /* SKB to free after getting completion */
819-
dma_addr_t addr[MAX_SKB_FRAGS + 1]; /* DMA mapped addresses */
820-
};
821-
822822
struct sge_eosw_txq {
823823
spinlock_t lock; /* Per queue lock to synchronize completions */
824824
enum sge_eosw_state state; /* Current ETHOFLD State */
825-
struct sge_eosw_desc *desc; /* Descriptor ring to hold packets */
825+
struct tx_sw_desc *desc; /* Descriptor ring to hold packets */
826826
u32 ndesc; /* Number of descriptors */
827827
u32 pidx; /* Current Producer Index */
828828
u32 last_pidx; /* Last successfully transmitted Producer Index */
@@ -1151,11 +1151,6 @@ enum {
11511151
SCHED_CLASS_RATEMODE_ABS = 1, /* Kb/s */
11521152
};
11531153

1154-
struct tx_sw_desc { /* SW state per Tx descriptor */
1155-
struct sk_buff *skb;
1156-
struct ulptx_sgl *sgl;
1157-
};
1158-
11591154
/* Support for "sched_queue" command to allow one or more NIC TX Queues
11601155
* to be bound to a TX Scheduling Class.
11611156
*/

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ static int cxgb4_init_eosw_txq(struct net_device *dev,
7070
u32 eotid, u32 hwqid)
7171
{
7272
struct adapter *adap = netdev2adap(dev);
73-
struct sge_eosw_desc *ring;
73+
struct tx_sw_desc *ring;
7474

7575
memset(eosw_txq, 0, sizeof(*eosw_txq));
7676

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

Lines changed: 31 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -300,65 +300,6 @@ static void deferred_unmap_destructor(struct sk_buff *skb)
300300
}
301301
#endif
302302

303-
static void unmap_sgl(struct device *dev, const struct sk_buff *skb,
304-
const struct ulptx_sgl *sgl, const struct sge_txq *q)
305-
{
306-
const struct ulptx_sge_pair *p;
307-
unsigned int nfrags = skb_shinfo(skb)->nr_frags;
308-
309-
if (likely(skb_headlen(skb)))
310-
dma_unmap_single(dev, be64_to_cpu(sgl->addr0), ntohl(sgl->len0),
311-
DMA_TO_DEVICE);
312-
else {
313-
dma_unmap_page(dev, be64_to_cpu(sgl->addr0), ntohl(sgl->len0),
314-
DMA_TO_DEVICE);
315-
nfrags--;
316-
}
317-
318-
/*
319-
* the complexity below is because of the possibility of a wrap-around
320-
* in the middle of an SGL
321-
*/
322-
for (p = sgl->sge; nfrags >= 2; nfrags -= 2) {
323-
if (likely((u8 *)(p + 1) <= (u8 *)q->stat)) {
324-
unmap: dma_unmap_page(dev, be64_to_cpu(p->addr[0]),
325-
ntohl(p->len[0]), DMA_TO_DEVICE);
326-
dma_unmap_page(dev, be64_to_cpu(p->addr[1]),
327-
ntohl(p->len[1]), DMA_TO_DEVICE);
328-
p++;
329-
} else if ((u8 *)p == (u8 *)q->stat) {
330-
p = (const struct ulptx_sge_pair *)q->desc;
331-
goto unmap;
332-
} else if ((u8 *)p + 8 == (u8 *)q->stat) {
333-
const __be64 *addr = (const __be64 *)q->desc;
334-
335-
dma_unmap_page(dev, be64_to_cpu(addr[0]),
336-
ntohl(p->len[0]), DMA_TO_DEVICE);
337-
dma_unmap_page(dev, be64_to_cpu(addr[1]),
338-
ntohl(p->len[1]), DMA_TO_DEVICE);
339-
p = (const struct ulptx_sge_pair *)&addr[2];
340-
} else {
341-
const __be64 *addr = (const __be64 *)q->desc;
342-
343-
dma_unmap_page(dev, be64_to_cpu(p->addr[0]),
344-
ntohl(p->len[0]), DMA_TO_DEVICE);
345-
dma_unmap_page(dev, be64_to_cpu(addr[0]),
346-
ntohl(p->len[1]), DMA_TO_DEVICE);
347-
p = (const struct ulptx_sge_pair *)&addr[1];
348-
}
349-
}
350-
if (nfrags) {
351-
__be64 addr;
352-
353-
if ((u8 *)p == (u8 *)q->stat)
354-
p = (const struct ulptx_sge_pair *)q->desc;
355-
addr = (u8 *)p + 16 <= (u8 *)q->stat ? p->addr[0] :
356-
*(const __be64 *)q->desc;
357-
dma_unmap_page(dev, be64_to_cpu(addr), ntohl(p->len[0]),
358-
DMA_TO_DEVICE);
359-
}
360-
}
361-
362303
/**
363304
* free_tx_desc - reclaims Tx descriptors and their buffers
364305
* @adapter: the adapter
@@ -372,15 +313,16 @@ unmap: dma_unmap_page(dev, be64_to_cpu(p->addr[0]),
372313
void free_tx_desc(struct adapter *adap, struct sge_txq *q,
373314
unsigned int n, bool unmap)
374315
{
375-
struct tx_sw_desc *d;
376316
unsigned int cidx = q->cidx;
377-
struct device *dev = adap->pdev_dev;
317+
struct tx_sw_desc *d;
378318

379319
d = &q->sdesc[cidx];
380320
while (n--) {
381321
if (d->skb) { /* an SGL is present */
382-
if (unmap)
383-
unmap_sgl(dev, d->skb, d->sgl, q);
322+
if (unmap && d->addr[0]) {
323+
unmap_skb(adap->pdev_dev, d->skb, d->addr);
324+
memset(d->addr, 0, sizeof(d->addr));
325+
}
384326
dev_consume_skb_any(d->skb);
385327
d->skb = NULL;
386328
}
@@ -1414,13 +1356,13 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
14141356
{
14151357
enum cpl_tx_tnl_lso_type tnl_type = TX_TNL_TYPE_OPAQUE;
14161358
bool ptp_enabled = is_ptp_enabled(skb, dev);
1417-
dma_addr_t addr[MAX_SKB_FRAGS + 1];
1359+
unsigned int last_desc, flits, ndesc;
14181360
const struct skb_shared_info *ssi;
1361+
struct tx_sw_desc *sgl_sdesc;
14191362
struct fw_eth_tx_pkt_wr *wr;
14201363
struct cpl_tx_pkt_core *cpl;
14211364
int len, qidx, credits, ret;
14221365
const struct port_info *pi;
1423-
unsigned int flits, ndesc;
14241366
bool immediate = false;
14251367
u32 wr_mid, ctrl0, op;
14261368
u64 cntrl, *end, *sgl;
@@ -1489,8 +1431,14 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
14891431
if (skb->encapsulation && chip_ver > CHELSIO_T5)
14901432
tnl_type = cxgb_encap_offload_supported(skb);
14911433

1434+
last_desc = q->q.pidx + ndesc - 1;
1435+
if (last_desc >= q->q.size)
1436+
last_desc -= q->q.size;
1437+
sgl_sdesc = &q->q.sdesc[last_desc];
1438+
14921439
if (!immediate &&
1493-
unlikely(cxgb4_map_skb(adap->pdev_dev, skb, addr) < 0)) {
1440+
unlikely(cxgb4_map_skb(adap->pdev_dev, skb, sgl_sdesc->addr) < 0)) {
1441+
memset(sgl_sdesc->addr, 0, sizeof(sgl_sdesc->addr));
14941442
q->mapping_err++;
14951443
if (ptp_enabled)
14961444
spin_unlock(&adap->ptp_lock);
@@ -1618,16 +1566,10 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
16181566
cxgb4_inline_tx_skb(skb, &q->q, sgl);
16191567
dev_consume_skb_any(skb);
16201568
} else {
1621-
int last_desc;
1622-
1623-
cxgb4_write_sgl(skb, &q->q, (void *)sgl, end, 0, addr);
1569+
cxgb4_write_sgl(skb, &q->q, (void *)sgl, end, 0,
1570+
sgl_sdesc->addr);
16241571
skb_orphan(skb);
1625-
1626-
last_desc = q->q.pidx + ndesc - 1;
1627-
if (last_desc >= q->q.size)
1628-
last_desc -= q->q.size;
1629-
q->q.sdesc[last_desc].skb = skb;
1630-
q->q.sdesc[last_desc].sgl = (struct ulptx_sgl *)sgl;
1572+
sgl_sdesc->skb = skb;
16311573
}
16321574

16331575
txq_advance(&q->q, ndesc);
@@ -1725,12 +1667,12 @@ static inline unsigned int t4vf_calc_tx_flits(const struct sk_buff *skb)
17251667
static netdev_tx_t cxgb4_vf_eth_xmit(struct sk_buff *skb,
17261668
struct net_device *dev)
17271669
{
1728-
dma_addr_t addr[MAX_SKB_FRAGS + 1];
1670+
unsigned int last_desc, flits, ndesc;
17291671
const struct skb_shared_info *ssi;
17301672
struct fw_eth_tx_pkt_vm_wr *wr;
1673+
struct tx_sw_desc *sgl_sdesc;
17311674
struct cpl_tx_pkt_core *cpl;
17321675
const struct port_info *pi;
1733-
unsigned int flits, ndesc;
17341676
struct sge_eth_txq *txq;
17351677
struct adapter *adapter;
17361678
int qidx, credits, ret;
@@ -1782,12 +1724,19 @@ static netdev_tx_t cxgb4_vf_eth_xmit(struct sk_buff *skb,
17821724
return NETDEV_TX_BUSY;
17831725
}
17841726

1727+
last_desc = txq->q.pidx + ndesc - 1;
1728+
if (last_desc >= txq->q.size)
1729+
last_desc -= txq->q.size;
1730+
sgl_sdesc = &txq->q.sdesc[last_desc];
1731+
17851732
if (!t4vf_is_eth_imm(skb) &&
1786-
unlikely(cxgb4_map_skb(adapter->pdev_dev, skb, addr) < 0)) {
1733+
unlikely(cxgb4_map_skb(adapter->pdev_dev, skb,
1734+
sgl_sdesc->addr) < 0)) {
17871735
/* We need to map the skb into PCI DMA space (because it can't
17881736
* be in-lined directly into the Work Request) and the mapping
17891737
* operation failed. Record the error and drop the packet.
17901738
*/
1739+
memset(sgl_sdesc->addr, 0, sizeof(sgl_sdesc->addr));
17911740
txq->mapping_err++;
17921741
goto out_free;
17931742
}
@@ -1962,7 +1911,6 @@ static netdev_tx_t cxgb4_vf_eth_xmit(struct sk_buff *skb,
19621911
*/
19631912
struct ulptx_sgl *sgl = (struct ulptx_sgl *)(cpl + 1);
19641913
struct sge_txq *tq = &txq->q;
1965-
int last_desc;
19661914

19671915
/* If the Work Request header was an exact multiple of our TX
19681916
* Descriptor length, then it's possible that the starting SGL
@@ -1976,14 +1924,9 @@ static netdev_tx_t cxgb4_vf_eth_xmit(struct sk_buff *skb,
19761924
((void *)end - (void *)tq->stat));
19771925
}
19781926

1979-
cxgb4_write_sgl(skb, tq, sgl, end, 0, addr);
1927+
cxgb4_write_sgl(skb, tq, sgl, end, 0, sgl_sdesc->addr);
19801928
skb_orphan(skb);
1981-
1982-
last_desc = tq->pidx + ndesc - 1;
1983-
if (last_desc >= tq->size)
1984-
last_desc -= tq->size;
1985-
tq->sdesc[last_desc].skb = skb;
1986-
tq->sdesc[last_desc].sgl = sgl;
1929+
sgl_sdesc->skb = skb;
19871930
}
19881931

19891932
/* Advance our internal TX Queue state, tell the hardware about
@@ -2035,7 +1978,7 @@ static inline void eosw_txq_advance_index(u32 *idx, u32 n, u32 max)
20351978
void cxgb4_eosw_txq_free_desc(struct adapter *adap,
20361979
struct sge_eosw_txq *eosw_txq, u32 ndesc)
20371980
{
2038-
struct sge_eosw_desc *d;
1981+
struct tx_sw_desc *d;
20391982

20401983
d = &eosw_txq->desc[eosw_txq->last_cidx];
20411984
while (ndesc--) {
@@ -2167,7 +2110,7 @@ static void ethofld_hard_xmit(struct net_device *dev,
21672110
struct cpl_tx_pkt_core *cpl;
21682111
struct fw_eth_tx_eo_wr *wr;
21692112
bool skip_eotx_wr = false;
2170-
struct sge_eosw_desc *d;
2113+
struct tx_sw_desc *d;
21712114
struct sk_buff *skb;
21722115
u8 flits, ndesc;
21732116
int left;

0 commit comments

Comments
 (0)