diff options
author | Kretschmer, Mathias <mathias.kretschmer@fokus.fraunhofer.de> | 2015-05-08 15:44:37 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-05-10 19:40:08 -0400 |
commit | fbf33a2802f71dba06faa948af805884ff16a2ab (patch) | |
tree | 94a5d1b3c78f23b9a82bfbbdf97c17c9cfa29abc /net/packet/af_packet.c | |
parent | cd9c39977754d9602b5783a44f4af09530a58254 (diff) |
af_packet / TX_RING not fully non-blocking (w/ MSG_DONTWAIT).
This patch fixes an issue where the send(MSG_DONTWAIT) call
on a TX_RING is not fully non-blocking in cases where the device's sndBuf is
full. We pass nonblock=true to sock_alloc_send_skb() and return any possibly
occuring error code (most likely EGAIN) to the caller. As the fast-path stays
as it is, we keep the unlikely() around skb == NULL.
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/packet/af_packet.c')
-rw-r--r-- | net/packet/af_packet.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 5102c3cc4eec..b5989c6ee551 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2311,11 +2311,14 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) tlen = dev->needed_tailroom; skb = sock_alloc_send_skb(&po->sk, hlen + tlen + sizeof(struct sockaddr_ll), - 0, &err); + !need_wait, &err); - if (unlikely(skb == NULL)) + if (unlikely(skb == NULL)) { + /* we assume the socket was initially writeable ... */ + if (likely(len_sum > 0)) + err = len_sum; goto out_status; - + } tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto, addr, hlen); if (tp_len > dev->mtu + dev->hard_header_len) { |