|
@@ -802,6 +802,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
|
|
|
int err, is_udplite = IS_UDPLITE(sk);
|
|
|
int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
|
|
|
int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
|
|
|
+ struct sk_buff *skb;
|
|
|
|
|
|
if (len > 0xFFFF)
|
|
|
return -EMSGSIZE;
|
|
@@ -816,6 +817,8 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
|
|
|
ipc.opt = NULL;
|
|
|
ipc.tx_flags = 0;
|
|
|
|
|
|
+ getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
|
|
|
+
|
|
|
if (up->pending) {
|
|
|
/*
|
|
|
* There are pending frames.
|
|
@@ -940,6 +943,17 @@ back_from_confirm:
|
|
|
if (!ipc.addr)
|
|
|
daddr = ipc.addr = rt->rt_dst;
|
|
|
|
|
|
+ /* Lockless fast path for the non-corking case. */
|
|
|
+ if (!corkreq) {
|
|
|
+ skb = ip_make_skb(sk, getfrag, msg->msg_iov, ulen,
|
|
|
+ sizeof(struct udphdr), &ipc, &rt,
|
|
|
+ msg->msg_flags);
|
|
|
+ err = PTR_ERR(skb);
|
|
|
+ if (skb && !IS_ERR(skb))
|
|
|
+ err = udp_send_skb(skb, daddr, dport);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
lock_sock(sk);
|
|
|
if (unlikely(up->pending)) {
|
|
|
/* The socket is already corked while preparing it. */
|
|
@@ -961,7 +975,6 @@ back_from_confirm:
|
|
|
|
|
|
do_append_data:
|
|
|
up->len += ulen;
|
|
|
- getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
|
|
|
err = ip_append_data(sk, getfrag, msg->msg_iov, ulen,
|
|
|
sizeof(struct udphdr), &ipc, &rt,
|
|
|
corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
|