Commit 87a2fd28 authored by Daniel Borkmann's avatar Daniel Borkmann Committed by David S. Miller

packet: don't unconditionally schedule() in case of MSG_DONTWAIT

In tpacket_snd(), when we've discovered a first frame that is
not in status TP_STATUS_SEND_REQUEST, and return a NULL buffer,
we exit the send routine in case of MSG_DONTWAIT, since we've
finished traversing the mmaped send ring buffer and don't care
about pending frames.

While doing so, we still unconditionally call an expensive
schedule() in the packet_current_frame() "error" path, which
is unnecessary in this case since it's enough to just quit
the function.

Also, in case MSG_DONTWAIT is not set, we should rather test
for need_resched() first and do schedule() only if necessary
since meanwhile pending frames could already have finished
processing and called skb destructor.
Signed-off-by: default avatarDaniel Borkmann <dborkman@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 902fefb8
...@@ -2156,6 +2156,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ...@@ -2156,6 +2156,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
int err, reserve = 0; int err, reserve = 0;
void *ph; void *ph;
struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name; struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name;
bool need_wait = !(msg->msg_flags & MSG_DONTWAIT);
int tp_len, size_max; int tp_len, size_max;
unsigned char *addr; unsigned char *addr;
int len_sum = 0; int len_sum = 0;
...@@ -2198,10 +2199,10 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ...@@ -2198,10 +2199,10 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
do { do {
ph = packet_current_frame(po, &po->tx_ring, ph = packet_current_frame(po, &po->tx_ring,
TP_STATUS_SEND_REQUEST); TP_STATUS_SEND_REQUEST);
if (unlikely(ph == NULL)) { if (unlikely(ph == NULL)) {
schedule(); if (need_wait && need_resched())
schedule();
continue; continue;
} }
...@@ -2255,10 +2256,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ...@@ -2255,10 +2256,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
} }
packet_increment_head(&po->tx_ring); packet_increment_head(&po->tx_ring);
len_sum += tp_len; len_sum += tp_len;
} while (likely((ph != NULL) || } while (likely((ph != NULL) || (need_wait &&
((!(msg->msg_flags & MSG_DONTWAIT)) && atomic_read(&po->tx_ring.pending))));
(atomic_read(&po->tx_ring.pending))))
);
err = len_sum; err = len_sum;
goto out_put; goto out_put;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment