Commit d2c21422 authored by Shannon Nelson's avatar Shannon Nelson Committed by David S. Miller

ionic: linearize tso skb with too many frags

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: 0f3154e6 ("ionic: Add Tx and Rx handling")
Signed-off-by: default avatarShannon Nelson <snelson@pensando.io>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fc649670
...@@ -1079,15 +1079,17 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, struct sk_buff *skb) ...@@ -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; int sg_elems = q->lif->qtype_info[IONIC_QTYPE_TXQ].max_sg_elems;
struct ionic_tx_stats *stats = q_to_tx_stats(q); struct ionic_tx_stats *stats = q_to_tx_stats(q);
int ndescs;
int err; 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)) 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) if (skb_shinfo(skb)->nr_frags <= sg_elems)
return 1; return ndescs;
/* Too many frags, so linearize */ /* Too many frags, so linearize */
err = skb_linearize(skb); err = skb_linearize(skb);
...@@ -1096,8 +1098,7 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, struct sk_buff *skb) ...@@ -1096,8 +1098,7 @@ static int ionic_tx_descs_needed(struct ionic_queue *q, struct sk_buff *skb)
stats->linearize++; stats->linearize++;
/* Need 1 desc and zero sg elems */ return ndescs;
return 1;
} }
static int ionic_maybe_stop_tx(struct ionic_queue *q, int ndescs) static int ionic_maybe_stop_tx(struct ionic_queue *q, int ndescs)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment