summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorZhenyu Gao <sysugaozhenyu@gmail.com>2017-05-31 01:45:08 +0000
committerBen Pfaff <blp@ovn.org>2017-05-31 08:54:37 -0700
commit0a62ae2c62356a1b91b6477b5b28160c3c9e8ade (patch)
treed4e1a65b5ccf06224c09306a7085b883c9120f5e /lib
parent4f74db48afd9e8d9a4208a43bd637c02caff13fd (diff)
downloadopenvswitch-0a62ae2c62356a1b91b6477b5b28160c3c9e8ade.tar.gz
netdev-linux: Refactor netdev_linux_send() in forwarding batch packets.
We don't need to initialize sock,msg and sll before calling sendmsg each time. Just initialize them before the loop, it can reduce cpu cycles. Signed-off-by: Zhenyu Gao <sysugaozhenyu@gmail.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/netdev-linux.c64
1 files changed, 34 insertions, 30 deletions
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 3ad3d454c..8ae740a17 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -1192,11 +1192,40 @@ netdev_linux_send(struct netdev *netdev_, int qid OVS_UNUSED,
struct dp_packet_batch *batch, bool may_steal,
bool concurrent_txq OVS_UNUSED)
{
- int i;
int error = 0;
+ int sock = 0;
+
+ struct sockaddr_ll sll;
+ struct msghdr msg;
+ if (!is_tap_netdev(netdev_)) {
+ sock = af_packet_sock();
+ if (sock < 0) {
+ error = -sock;
+ goto free_batch;
+ }
+
+ int ifindex = netdev_get_ifindex(netdev_);
+ if (ifindex < 0) {
+ error = -ifindex;
+ goto free_batch;
+ }
+
+ /* We don't bother setting most fields in sockaddr_ll because the
+ * kernel ignores them for SOCK_RAW. */
+ memset(&sll, 0, sizeof sll);
+ sll.sll_family = AF_PACKET;
+ sll.sll_ifindex = ifindex;
+
+ msg.msg_name = &sll;
+ msg.msg_namelen = sizeof sll;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+ }
/* 'i' is incremented only if there's no error */
- for (i = 0; i < batch->count;) {
+ for (int i = 0; i < batch->count; ) {
const void *data = dp_packet_data(batch->packets[i]);
size_t size = dp_packet_size(batch->packets[i]);
ssize_t retval;
@@ -1206,38 +1235,12 @@ netdev_linux_send(struct netdev *netdev_, int qid OVS_UNUSED,
if (!is_tap_netdev(netdev_)) {
/* Use our AF_PACKET socket to send to this device. */
- struct sockaddr_ll sll;
- struct msghdr msg;
struct iovec iov;
- int ifindex;
- int sock;
-
- sock = af_packet_sock();
- if (sock < 0) {
- return -sock;
- }
-
- ifindex = netdev_get_ifindex(netdev_);
- if (ifindex < 0) {
- return -ifindex;
- }
-
- /* We don't bother setting most fields in sockaddr_ll because the
- * kernel ignores them for SOCK_RAW. */
- memset(&sll, 0, sizeof sll);
- sll.sll_family = AF_PACKET;
- sll.sll_ifindex = ifindex;
iov.iov_base = CONST_CAST(void *, data);
iov.iov_len = size;
- msg.msg_name = &sll;
- msg.msg_namelen = sizeof sll;
msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0;
retval = sendmsg(sock, &msg, 0);
} else {
@@ -1278,13 +1281,14 @@ netdev_linux_send(struct netdev *netdev_, int qid OVS_UNUSED,
i++;
}
- dp_packet_delete_batch(batch, may_steal);
-
if (error && error != EAGAIN) {
VLOG_WARN_RL(&rl, "error sending Ethernet packet on %s: %s",
netdev_get_name(netdev_), ovs_strerror(error));
}
+free_batch:
+ dp_packet_delete_batch(batch, may_steal);
+
return error;
}