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

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
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -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);
@@ -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)