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: Octavian Purdila <octavian.purdila@intel.com> Reviewed-by: Christoph Paasch <christoph.paasch@uclouvain.be> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
27fa589de5
Коммит
6cc55e096f
|
@ -535,7 +535,7 @@ void tcp_retransmit_timer(struct sock *sk);
|
||||||
void tcp_xmit_retransmit_queue(struct sock *);
|
void tcp_xmit_retransmit_queue(struct sock *);
|
||||||
void tcp_simple_retransmit(struct sock *);
|
void tcp_simple_retransmit(struct sock *);
|
||||||
int tcp_trim_head(struct sock *, struct sk_buff *, u32);
|
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_probe0(struct sock *);
|
||||||
void tcp_send_partial(struct sock *);
|
void tcp_send_partial(struct sock *);
|
||||||
|
|
|
@ -1167,7 +1167,7 @@ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb,
|
||||||
}
|
}
|
||||||
pkt_len = new_len;
|
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)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -2241,7 +2241,8 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
mss = skb_shinfo(skb)->gso_size;
|
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)
|
if (err < 0)
|
||||||
break;
|
break;
|
||||||
cnt = packets;
|
cnt = packets;
|
||||||
|
|
|
@ -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.
|
* Remember, these are still headerless SKBs at this point.
|
||||||
*/
|
*/
|
||||||
int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
|
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 tcp_sock *tp = tcp_sk(sk);
|
||||||
struct sk_buff *buff;
|
struct sk_buff *buff;
|
||||||
|
@ -1089,11 +1089,11 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
|
||||||
if (nsize < 0)
|
if (nsize < 0)
|
||||||
nsize = 0;
|
nsize = 0;
|
||||||
|
|
||||||
if (skb_unclone(skb, GFP_ATOMIC))
|
if (skb_unclone(skb, gfp))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Get a new skb... force flag on. */
|
/* 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)
|
if (buff == NULL)
|
||||||
return -ENOMEM; /* We'll just try again later. */
|
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. */
|
/* All of a TSO frame must be composed of paged data. */
|
||||||
if (skb->len != skb->data_len)
|
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);
|
buff = sk_stream_alloc_skb(sk, 0, gfp);
|
||||||
if (unlikely(buff == NULL))
|
if (unlikely(buff == NULL))
|
||||||
|
@ -2122,7 +2122,8 @@ void tcp_send_loss_probe(struct sock *sk)
|
||||||
goto rearm_timer;
|
goto rearm_timer;
|
||||||
|
|
||||||
if ((pcount > 1) && (skb->len > (pcount - 1) * mss)) {
|
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;
|
goto rearm_timer;
|
||||||
skb = tcp_write_queue_tail(sk);
|
skb = tcp_write_queue_tail(sk);
|
||||||
}
|
}
|
||||||
|
@ -2463,7 +2464,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
if (skb->len > cur_mss) {
|
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. */
|
return -ENOMEM; /* We'll try again later. */
|
||||||
} else {
|
} else {
|
||||||
int oldpcount = tcp_skb_pcount(skb);
|
int oldpcount = tcp_skb_pcount(skb);
|
||||||
|
@ -3244,7 +3245,7 @@ int tcp_write_wakeup(struct sock *sk)
|
||||||
skb->len > mss) {
|
skb->len > mss) {
|
||||||
seg_size = min(seg_size, mss);
|
seg_size = min(seg_size, mss);
|
||||||
TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH;
|
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;
|
return -1;
|
||||||
} else if (!tcp_skb_pcount(skb))
|
} else if (!tcp_skb_pcount(skb))
|
||||||
tcp_set_skb_tso_segs(sk, skb, mss);
|
tcp_set_skb_tso_segs(sk, skb, mss);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче