diff options
author | Zhenyu Gao <sysugaozhenyu@gmail.com> | 2017-05-31 01:45:08 +0000 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2017-05-31 08:54:37 -0700 |
commit | 0a62ae2c62356a1b91b6477b5b28160c3c9e8ade (patch) | |
tree | d4e1a65b5ccf06224c09306a7085b883c9120f5e /lib | |
parent | 4f74db48afd9e8d9a4208a43bd637c02caff13fd (diff) | |
download | openvswitch-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.c | 64 |
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; } |