소스 검색

Merge branch 'net-ubuf_info-refcnt-conversion'

Eric Dumazet says:

====================
net: ubuf_info.refcnt conversion

Yet another atomic_t -> refcount_t conversion, split in two patches.

First patch prepares the automatic conversion done in the second patch.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
David S. Miller 8 년 전
부모
커밋
250b0f7831
4개의 변경된 파일8개의 추가작업 그리고 15개의 파일을 삭제
  1. 1 1
      drivers/vhost/net.c
  2. 3 2
      include/linux/skbuff.h
  3. 4 10
      net/core/skbuff.c
  4. 0 2
      net/ipv4/tcp.c

+ 1 - 1
drivers/vhost/net.c

@@ -533,7 +533,7 @@ static void handle_tx(struct vhost_net *net)
 			ubuf->callback = vhost_zerocopy_callback;
 			ubuf->callback = vhost_zerocopy_callback;
 			ubuf->ctx = nvq->ubufs;
 			ubuf->ctx = nvq->ubufs;
 			ubuf->desc = nvq->upend_idx;
 			ubuf->desc = nvq->upend_idx;
-			atomic_set(&ubuf->refcnt, 1);
+			refcount_set(&ubuf->refcnt, 1);
 			msg.msg_control = ubuf;
 			msg.msg_control = ubuf;
 			msg.msg_controllen = sizeof(ubuf);
 			msg.msg_controllen = sizeof(ubuf);
 			ubufs = nvq->ubufs;
 			ubufs = nvq->ubufs;

+ 3 - 2
include/linux/skbuff.h

@@ -22,6 +22,7 @@
 #include <linux/cache.h>
 #include <linux/cache.h>
 #include <linux/rbtree.h>
 #include <linux/rbtree.h>
 #include <linux/socket.h>
 #include <linux/socket.h>
+#include <linux/refcount.h>
 
 
 #include <linux/atomic.h>
 #include <linux/atomic.h>
 #include <asm/types.h>
 #include <asm/types.h>
@@ -456,7 +457,7 @@ struct ubuf_info {
 			u32 bytelen;
 			u32 bytelen;
 		};
 		};
 	};
 	};
-	atomic_t refcnt;
+	refcount_t refcnt;
 
 
 	struct mmpin {
 	struct mmpin {
 		struct user_struct *user;
 		struct user_struct *user;
@@ -472,7 +473,7 @@ struct ubuf_info *sock_zerocopy_realloc(struct sock *sk, size_t size,
 
 
 static inline void sock_zerocopy_get(struct ubuf_info *uarg)
 static inline void sock_zerocopy_get(struct ubuf_info *uarg)
 {
 {
-	atomic_inc(&uarg->refcnt);
+	refcount_inc(&uarg->refcnt);
 }
 }
 
 
 void sock_zerocopy_put(struct ubuf_info *uarg);
 void sock_zerocopy_put(struct ubuf_info *uarg);

+ 4 - 10
net/core/skbuff.c

@@ -963,7 +963,7 @@ struct ubuf_info *sock_zerocopy_alloc(struct sock *sk, size_t size)
 	uarg->len = 1;
 	uarg->len = 1;
 	uarg->bytelen = size;
 	uarg->bytelen = size;
 	uarg->zerocopy = 1;
 	uarg->zerocopy = 1;
-	atomic_set(&uarg->refcnt, 0);
+	refcount_set(&uarg->refcnt, 1);
 	sock_hold(sk);
 	sock_hold(sk);
 
 
 	return uarg;
 	return uarg;
@@ -1005,6 +1005,7 @@ struct ubuf_info *sock_zerocopy_realloc(struct sock *sk, size_t size,
 			uarg->len++;
 			uarg->len++;
 			uarg->bytelen = bytelen;
 			uarg->bytelen = bytelen;
 			atomic_set(&sk->sk_zckey, ++next);
 			atomic_set(&sk->sk_zckey, ++next);
+			sock_zerocopy_get(uarg);
 			return uarg;
 			return uarg;
 		}
 		}
 	}
 	}
@@ -1085,7 +1086,7 @@ EXPORT_SYMBOL_GPL(sock_zerocopy_callback);
 
 
 void sock_zerocopy_put(struct ubuf_info *uarg)
 void sock_zerocopy_put(struct ubuf_info *uarg)
 {
 {
-	if (uarg && atomic_dec_and_test(&uarg->refcnt)) {
+	if (uarg && refcount_dec_and_test(&uarg->refcnt)) {
 		if (uarg->callback)
 		if (uarg->callback)
 			uarg->callback(uarg, uarg->zerocopy);
 			uarg->callback(uarg, uarg->zerocopy);
 		else
 		else
@@ -1102,13 +1103,6 @@ void sock_zerocopy_put_abort(struct ubuf_info *uarg)
 		atomic_dec(&sk->sk_zckey);
 		atomic_dec(&sk->sk_zckey);
 		uarg->len--;
 		uarg->len--;
 
 
-		/* sock_zerocopy_put expects a ref. Most sockets take one per
-		 * skb, which is zero on abort. tcp_sendmsg holds one extra, to
-		 * avoid an skb send inside the main loop triggering uarg free.
-		 */
-		if (sk->sk_type != SOCK_STREAM)
-			atomic_inc(&uarg->refcnt);
-
 		sock_zerocopy_put(uarg);
 		sock_zerocopy_put(uarg);
 	}
 	}
 }
 }
@@ -1489,7 +1483,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
 		if (skb_orphan_frags(skb, gfp_mask))
 		if (skb_orphan_frags(skb, gfp_mask))
 			goto nofrags;
 			goto nofrags;
 		if (skb_zcopy(skb))
 		if (skb_zcopy(skb))
-			atomic_inc(&skb_uarg(skb)->refcnt);
+			refcount_inc(&skb_uarg(skb)->refcnt);
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
 			skb_frag_ref(skb, i);
 			skb_frag_ref(skb, i);
 
 

+ 0 - 2
net/ipv4/tcp.c

@@ -1190,8 +1190,6 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
 			goto out_err;
 			goto out_err;
 		}
 		}
 
 
-		/* skb may be freed in main loop, keep extra ref on uarg */
-		sock_zerocopy_get(uarg);
 		if (!(sk_check_csum_caps(sk) && sk->sk_route_caps & NETIF_F_SG))
 		if (!(sk_check_csum_caps(sk) && sk->sk_route_caps & NETIF_F_SG))
 			uarg->zerocopy = 0;
 			uarg->zerocopy = 0;
 	}
 	}