diff options
-rw-r--r-- | net/core/skbuff.c | 10 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 2 |
2 files changed, 2 insertions, 10 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 246ca1c81715..a003f953a0a6 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -963,7 +963,7 @@ struct ubuf_info *sock_zerocopy_alloc(struct sock *sk, size_t size) | |||
963 | uarg->len = 1; | 963 | uarg->len = 1; |
964 | uarg->bytelen = size; | 964 | uarg->bytelen = size; |
965 | uarg->zerocopy = 1; | 965 | uarg->zerocopy = 1; |
966 | atomic_set(&uarg->refcnt, 0); | 966 | atomic_set(&uarg->refcnt, 1); |
967 | sock_hold(sk); | 967 | sock_hold(sk); |
968 | 968 | ||
969 | return uarg; | 969 | return uarg; |
@@ -1005,6 +1005,7 @@ struct ubuf_info *sock_zerocopy_realloc(struct sock *sk, size_t size, | |||
1005 | uarg->len++; | 1005 | uarg->len++; |
1006 | uarg->bytelen = bytelen; | 1006 | uarg->bytelen = bytelen; |
1007 | atomic_set(&sk->sk_zckey, ++next); | 1007 | atomic_set(&sk->sk_zckey, ++next); |
1008 | sock_zerocopy_get(uarg); | ||
1008 | return uarg; | 1009 | return uarg; |
1009 | } | 1010 | } |
1010 | } | 1011 | } |
@@ -1102,13 +1103,6 @@ void sock_zerocopy_put_abort(struct ubuf_info *uarg) | |||
1102 | atomic_dec(&sk->sk_zckey); | 1103 | atomic_dec(&sk->sk_zckey); |
1103 | uarg->len--; | 1104 | uarg->len--; |
1104 | 1105 | ||
1105 | /* sock_zerocopy_put expects a ref. Most sockets take one per | ||
1106 | * skb, which is zero on abort. tcp_sendmsg holds one extra, to | ||
1107 | * avoid an skb send inside the main loop triggering uarg free. | ||
1108 | */ | ||
1109 | if (sk->sk_type != SOCK_STREAM) | ||
1110 | atomic_inc(&uarg->refcnt); | ||
1111 | |||
1112 | sock_zerocopy_put(uarg); | 1106 | sock_zerocopy_put(uarg); |
1113 | } | 1107 | } |
1114 | } | 1108 | } |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 7a3d84375836..5091402720ab 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1190,8 +1190,6 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) | |||
1190 | goto out_err; | 1190 | goto out_err; |
1191 | } | 1191 | } |
1192 | 1192 | ||
1193 | /* skb may be freed in main loop, keep extra ref on uarg */ | ||
1194 | sock_zerocopy_get(uarg); | ||
1195 | if (!(sk_check_csum_caps(sk) && sk->sk_route_caps & NETIF_F_SG)) | 1193 | if (!(sk_check_csum_caps(sk) && sk->sk_route_caps & NETIF_F_SG)) |
1196 | uarg->zerocopy = 0; | 1194 | uarg->zerocopy = 0; |
1197 | } | 1195 | } |