Skip to content

Commit 03485f2

Browse files
vyasevichdavem330
authored andcommitted
udpv6: Add lockless sendmsg() support
This commit adds the same functionaliy to IPv6 that commit 903ab86 Author: Herbert Xu <[email protected]> Date: Tue Mar 1 02:36:48 2011 +0000 udp: Add lockless transmit path added to IPv4. UDP transmit path can now run without a socket lock, thus allowing multiple threads to send to a single socket more efficiently. This is only used when corking/MSG_MORE is not used. Signed-off-by: Vladislav Yasevich <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d39d938 commit 03485f2

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

net/ipv6/udp.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
11771177
if (len > INT_MAX - sizeof(struct udphdr))
11781178
return -EMSGSIZE;
11791179

1180+
getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
11801181
if (up->pending) {
11811182
/*
11821183
* There are pending frames.
@@ -1307,6 +1308,20 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
13071308
goto do_confirm;
13081309
back_from_confirm:
13091310

1311+
/* Lockless fast path for the non-corking case */
1312+
if (!corkreq) {
1313+
struct sk_buff *skb;
1314+
1315+
skb = ip6_make_skb(sk, getfrag, msg, ulen,
1316+
sizeof(struct udphdr), hlimit, tclass, opt,
1317+
&fl6, (struct rt6_info *)dst,
1318+
msg->msg_flags, dontfrag);
1319+
err = PTR_ERR(skb);
1320+
if (!IS_ERR_OR_NULL(skb))
1321+
err = udp_v6_send_skb(skb, &fl6);
1322+
goto release_dst;
1323+
}
1324+
13101325
lock_sock(sk);
13111326
if (unlikely(up->pending)) {
13121327
/* The socket is already corked while preparing it. */
@@ -1324,7 +1339,6 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
13241339
if (dontfrag < 0)
13251340
dontfrag = np->dontfrag;
13261341
up->len += ulen;
1327-
getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
13281342
err = ip6_append_data(sk, getfrag, msg, ulen,
13291343
sizeof(struct udphdr), hlimit, tclass, opt, &fl6,
13301344
(struct rt6_info *)dst,
@@ -1336,6 +1350,11 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
13361350
else if (unlikely(skb_queue_empty(&sk->sk_write_queue)))
13371351
up->pending = 0;
13381352

1353+
if (err > 0)
1354+
err = np->recverr ? net_xmit_errno(err) : 0;
1355+
release_sock(sk);
1356+
1357+
release_dst:
13391358
if (dst) {
13401359
if (connected) {
13411360
ip6_dst_store(sk, dst,
@@ -1352,9 +1371,6 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
13521371
dst = NULL;
13531372
}
13541373

1355-
if (err > 0)
1356-
err = np->recverr ? net_xmit_errno(err) : 0;
1357-
release_sock(sk);
13581374
out:
13591375
dst_release(dst);
13601376
fl6_sock_release(flowlabel);

0 commit comments

Comments
 (0)