Skip to content

Commit 238a0f7

Browse files
brettcreeleydavem330
authored andcommitted
ionic: Cleanups in the Tx hotpath code
Buffer DMA mapping happens in ionic_tx_map_skb() and this function is called from ionic_tx() and ionic_tx_tso(). If ionic_tx_map_skb() succeeds, but a failure is encountered later in ionic_tx() or ionic_tx_tso() we aren't unmapping the buffers. This can be fixed in ionic_tx() by changing functions it calls to return void because they always return 0. For ionic_tx_tso(), there's an actual possibility that we leave the buffers mapped, so fix this by introducing the helper function ionic_tx_desc_unmap_bufs(). This function is also re-used in ionic_tx_clean(). Fixes: 0f3154e ("ionic: Add Tx and Rx handling") Signed-off-by: Brett Creeley <[email protected]> Signed-off-by: Shannon Nelson <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 584fb76 commit 238a0f7

File tree

1 file changed

+34
-32
lines changed

1 file changed

+34
-32
lines changed

drivers/net/ethernet/pensando/ionic/ionic_txrx.c

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -669,27 +669,37 @@ static int ionic_tx_map_skb(struct ionic_queue *q, struct sk_buff *skb,
669669
return -EIO;
670670
}
671671

672+
static void ionic_tx_desc_unmap_bufs(struct ionic_queue *q,
673+
struct ionic_desc_info *desc_info)
674+
{
675+
struct ionic_buf_info *buf_info = desc_info->bufs;
676+
struct device *dev = q->dev;
677+
unsigned int i;
678+
679+
if (!desc_info->nbufs)
680+
return;
681+
682+
dma_unmap_single(dev, (dma_addr_t)buf_info->dma_addr,
683+
buf_info->len, DMA_TO_DEVICE);
684+
buf_info++;
685+
for (i = 1; i < desc_info->nbufs; i++, buf_info++)
686+
dma_unmap_page(dev, (dma_addr_t)buf_info->dma_addr,
687+
buf_info->len, DMA_TO_DEVICE);
688+
689+
desc_info->nbufs = 0;
690+
}
691+
672692
static void ionic_tx_clean(struct ionic_queue *q,
673693
struct ionic_desc_info *desc_info,
674694
struct ionic_cq_info *cq_info,
675695
void *cb_arg)
676696
{
677-
struct ionic_buf_info *buf_info = desc_info->bufs;
678697
struct ionic_tx_stats *stats = q_to_tx_stats(q);
679698
struct ionic_qcq *qcq = q_to_qcq(q);
680699
struct sk_buff *skb = cb_arg;
681-
struct device *dev = q->dev;
682-
unsigned int i;
683700
u16 qi;
684701

685-
if (desc_info->nbufs) {
686-
dma_unmap_single(dev, (dma_addr_t)buf_info->dma_addr,
687-
buf_info->len, DMA_TO_DEVICE);
688-
buf_info++;
689-
for (i = 1; i < desc_info->nbufs; i++, buf_info++)
690-
dma_unmap_page(dev, (dma_addr_t)buf_info->dma_addr,
691-
buf_info->len, DMA_TO_DEVICE);
692-
}
702+
ionic_tx_desc_unmap_bufs(q, desc_info);
693703

694704
if (!skb)
695705
return;
@@ -931,8 +941,11 @@ static int ionic_tx_tso(struct ionic_queue *q, struct sk_buff *skb)
931941
err = ionic_tx_tcp_inner_pseudo_csum(skb);
932942
else
933943
err = ionic_tx_tcp_pseudo_csum(skb);
934-
if (err)
944+
if (err) {
945+
/* clean up mapping from ionic_tx_map_skb */
946+
ionic_tx_desc_unmap_bufs(q, desc_info);
935947
return err;
948+
}
936949

937950
if (encap)
938951
hdrlen = skb_inner_transport_header(skb) - skb->data +
@@ -1003,8 +1016,8 @@ static int ionic_tx_tso(struct ionic_queue *q, struct sk_buff *skb)
10031016
return 0;
10041017
}
10051018

1006-
static int ionic_tx_calc_csum(struct ionic_queue *q, struct sk_buff *skb,
1007-
struct ionic_desc_info *desc_info)
1019+
static void ionic_tx_calc_csum(struct ionic_queue *q, struct sk_buff *skb,
1020+
struct ionic_desc_info *desc_info)
10081021
{
10091022
struct ionic_txq_desc *desc = desc_info->txq_desc;
10101023
struct ionic_buf_info *buf_info = desc_info->bufs;
@@ -1038,12 +1051,10 @@ static int ionic_tx_calc_csum(struct ionic_queue *q, struct sk_buff *skb,
10381051
stats->crc32_csum++;
10391052
else
10401053
stats->csum++;
1041-
1042-
return 0;
10431054
}
10441055

1045-
static int ionic_tx_calc_no_csum(struct ionic_queue *q, struct sk_buff *skb,
1046-
struct ionic_desc_info *desc_info)
1056+
static void ionic_tx_calc_no_csum(struct ionic_queue *q, struct sk_buff *skb,
1057+
struct ionic_desc_info *desc_info)
10471058
{
10481059
struct ionic_txq_desc *desc = desc_info->txq_desc;
10491060
struct ionic_buf_info *buf_info = desc_info->bufs;
@@ -1074,12 +1085,10 @@ static int ionic_tx_calc_no_csum(struct ionic_queue *q, struct sk_buff *skb,
10741085
desc->csum_offset = 0;
10751086

10761087
stats->csum_none++;
1077-
1078-
return 0;
10791088
}
10801089

1081-
static int ionic_tx_skb_frags(struct ionic_queue *q, struct sk_buff *skb,
1082-
struct ionic_desc_info *desc_info)
1090+
static void ionic_tx_skb_frags(struct ionic_queue *q, struct sk_buff *skb,
1091+
struct ionic_desc_info *desc_info)
10831092
{
10841093
struct ionic_txq_sg_desc *sg_desc = desc_info->txq_sg_desc;
10851094
struct ionic_buf_info *buf_info = &desc_info->bufs[1];
@@ -1093,31 +1102,24 @@ static int ionic_tx_skb_frags(struct ionic_queue *q, struct sk_buff *skb,
10931102
}
10941103

10951104
stats->frags += skb_shinfo(skb)->nr_frags;
1096-
1097-
return 0;
10981105
}
10991106

11001107
static int ionic_tx(struct ionic_queue *q, struct sk_buff *skb)
11011108
{
11021109
struct ionic_desc_info *desc_info = &q->info[q->head_idx];
11031110
struct ionic_tx_stats *stats = q_to_tx_stats(q);
1104-
int err;
11051111

11061112
if (unlikely(ionic_tx_map_skb(q, skb, desc_info)))
11071113
return -EIO;
11081114

11091115
/* set up the initial descriptor */
11101116
if (skb->ip_summed == CHECKSUM_PARTIAL)
1111-
err = ionic_tx_calc_csum(q, skb, desc_info);
1117+
ionic_tx_calc_csum(q, skb, desc_info);
11121118
else
1113-
err = ionic_tx_calc_no_csum(q, skb, desc_info);
1114-
if (err)
1115-
return err;
1119+
ionic_tx_calc_no_csum(q, skb, desc_info);
11161120

11171121
/* add frags */
1118-
err = ionic_tx_skb_frags(q, skb, desc_info);
1119-
if (err)
1120-
return err;
1122+
ionic_tx_skb_frags(q, skb, desc_info);
11211123

11221124
skb_tx_timestamp(skb);
11231125
stats->pkts++;

0 commit comments

Comments
 (0)