Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6cc55e09 authored by Octavian Purdila's avatar Octavian Purdila Committed by David S. Miller
Browse files

tcp: add gfp parameter to tcp_fragment



tcp_fragment can be called from process context (from tso_fragment).
Add a new gfp parameter to allow it to preserve atomic memory if
possible.

Signed-off-by: default avatarOctavian Purdila <octavian.purdila@intel.com>
Reviewed-by: default avatarChristoph Paasch <christoph.paasch@uclouvain.be>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 27fa589d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -535,7 +535,7 @@ void tcp_retransmit_timer(struct sock *sk);
void tcp_xmit_retransmit_queue(struct sock *);
void tcp_simple_retransmit(struct sock *);
int tcp_trim_head(struct sock *, struct sk_buff *, u32);
int tcp_fragment(struct sock *, struct sk_buff *, u32, unsigned int);
int tcp_fragment(struct sock *, struct sk_buff *, u32, unsigned int, gfp_t);

void tcp_send_probe0(struct sock *);
void tcp_send_partial(struct sock *);
+3 −2
Original line number Diff line number Diff line
@@ -1167,7 +1167,7 @@ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb,
			}
			pkt_len = new_len;
		}
		err = tcp_fragment(sk, skb, pkt_len, mss);
		err = tcp_fragment(sk, skb, pkt_len, mss, GFP_ATOMIC);
		if (err < 0)
			return err;
	}
@@ -2241,7 +2241,8 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
				break;

			mss = skb_shinfo(skb)->gso_size;
			err = tcp_fragment(sk, skb, (packets - oldcnt) * mss, mss);
			err = tcp_fragment(sk, skb, (packets - oldcnt) * mss,
					   mss, GFP_ATOMIC);
			if (err < 0)
				break;
			cnt = packets;
+8 −7
Original line number Diff line number Diff line
@@ -1074,7 +1074,7 @@ static void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int de
 * Remember, these are still headerless SKBs at this point.
 */
int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
		 unsigned int mss_now)
		 unsigned int mss_now, gfp_t gfp)
{
	struct tcp_sock *tp = tcp_sk(sk);
	struct sk_buff *buff;
@@ -1089,11 +1089,11 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
	if (nsize < 0)
		nsize = 0;

	if (skb_unclone(skb, GFP_ATOMIC))
	if (skb_unclone(skb, gfp))
		return -ENOMEM;

	/* Get a new skb... force flag on. */
	buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC);
	buff = sk_stream_alloc_skb(sk, nsize, gfp);
	if (buff == NULL)
		return -ENOMEM; /* We'll just try again later. */

@@ -1625,7 +1625,7 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len,

	/* All of a TSO frame must be composed of paged data.  */
	if (skb->len != skb->data_len)
		return tcp_fragment(sk, skb, len, mss_now);
		return tcp_fragment(sk, skb, len, mss_now, gfp);

	buff = sk_stream_alloc_skb(sk, 0, gfp);
	if (unlikely(buff == NULL))
@@ -2122,7 +2122,8 @@ void tcp_send_loss_probe(struct sock *sk)
		goto rearm_timer;

	if ((pcount > 1) && (skb->len > (pcount - 1) * mss)) {
		if (unlikely(tcp_fragment(sk, skb, (pcount - 1) * mss, mss)))
		if (unlikely(tcp_fragment(sk, skb, (pcount - 1) * mss, mss,
					  GFP_ATOMIC)))
			goto rearm_timer;
		skb = tcp_write_queue_tail(sk);
	}
@@ -2463,7 +2464,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
		return -EAGAIN;

	if (skb->len > cur_mss) {
		if (tcp_fragment(sk, skb, cur_mss, cur_mss))
		if (tcp_fragment(sk, skb, cur_mss, cur_mss, GFP_ATOMIC))
			return -ENOMEM; /* We'll try again later. */
	} else {
		int oldpcount = tcp_skb_pcount(skb);
@@ -3244,7 +3245,7 @@ int tcp_write_wakeup(struct sock *sk)
		    skb->len > mss) {
			seg_size = min(seg_size, mss);
			TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH;
			if (tcp_fragment(sk, skb, seg_size, mss))
			if (tcp_fragment(sk, skb, seg_size, mss, GFP_ATOMIC))
				return -1;
		} else if (!tcp_skb_pcount(skb))
			tcp_set_skb_tso_segs(sk, skb, mss);