Skip to content

Commit

Permalink
ionic: linearize tso skb with too many frags
Browse files Browse the repository at this point in the history
[ Upstream commit d2c2142 ]

We were linearizing non-TSO skbs that had too many frags, but
we weren't checking number of frags on TSO skbs.  This could
lead to a bad page reference when we received a TSO skb with
more frags than the Tx descriptor could support.

v2: use gso_segs rather than yet another division
    don't rework the check on the nr_frags

Fixes: 0f3154e ("ionic: Add Tx and Rx handling")
Signed-off-by: Shannon Nelson <snelson@pensando.io>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
emusln authored and gregkh committed Mar 30, 2021
1 parent bbdf319 commit 7ad5b92
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions drivers/net/ethernet/pensando/ionic/ionic_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1079,15 +1079,17 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, struct sk_buff *skb)
{
int sg_elems = q->lif->qtype_info[IONIC_QTYPE_TXQ].max_sg_elems;
struct ionic_tx_stats *stats = q_to_tx_stats(q);
int ndescs;
int err;

/* If TSO, need roundup(skb->len/mss) descs */
/* Each desc is mss long max, so a descriptor for each gso_seg */
if (skb_is_gso(skb))
return (skb->len / skb_shinfo(skb)->gso_size) + 1;
ndescs = skb_shinfo(skb)->gso_segs;
else
ndescs = 1;

/* If non-TSO, just need 1 desc and nr_frags sg elems */
if (skb_shinfo(skb)->nr_frags <= sg_elems)
return 1;
return ndescs;

/* Too many frags, so linearize */
err = skb_linearize(skb);
Expand All @@ -1096,8 +1098,7 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, struct sk_buff *skb)

stats->linearize++;

/* Need 1 desc and zero sg elems */
return 1;
return ndescs;
}

static int ionic_maybe_stop_tx(struct ionic_queue *q, int ndescs)
Expand Down

0 comments on commit 7ad5b92

Please sign in to comment.