2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 06:15:47 +00:00

netdev: netdev_send accepts multiple packets

The netdev_send function has been modified to accept multiple packets, to
allow netdev providers to amortize locking and queuing costs.
This is especially true for netdev-dpdk.

Later commits exploit the new API.

Signed-off-by: Daniele Di Proietto <ddiproietto@vmware.com>
Acked-by: Pravin B Shelar <pshelar@nicira.com>
This commit is contained in:
Daniele Di Proietto
2014-06-23 11:43:58 -07:00
committed by Pravin B Shelar
parent 910885540a
commit f4fd623c4c
8 changed files with 242 additions and 156 deletions

View File

@@ -686,14 +686,13 @@ netdev_bsd_rxq_drain(struct netdev_rxq *rxq_)
* system or a tap device.
*/
static int
netdev_bsd_send(struct netdev *netdev_, struct dpif_packet *pkt,
netdev_bsd_send(struct netdev *netdev_, struct dpif_packet **pkts, int cnt,
bool may_steal)
{
struct netdev_bsd *dev = netdev_bsd_cast(netdev_);
const char *name = netdev_get_name(netdev_);
const void *data = ofpbuf_data(&pkt->ofpbuf);
size_t size = ofpbuf_size(&pkt->ofpbuf);
int error;
int i;
ovs_mutex_lock(&dev->mutex);
if (dev->tap_fd < 0 && !dev->pcap) {
@@ -702,35 +701,43 @@ netdev_bsd_send(struct netdev *netdev_, struct dpif_packet *pkt,
error = 0;
}
while (!error) {
ssize_t retval;
if (dev->tap_fd >= 0) {
retval = write(dev->tap_fd, data, size);
} else {
retval = pcap_inject(dev->pcap, data, size);
}
if (retval < 0) {
if (errno == EINTR) {
continue;
for (i = 0; i < cnt; i++) {
const void *data = ofpbuf_data(&pkts[i]->ofpbuf);
size_t size = ofpbuf_size(&pkts[i]->ofpbuf);
while (!error) {
ssize_t retval;
if (dev->tap_fd >= 0) {
retval = write(dev->tap_fd, data, size);
} else {
error = errno;
if (error != EAGAIN) {
VLOG_WARN_RL(&rl, "error sending Ethernet packet on %s: "
"%s", name, ovs_strerror(error));
}
retval = pcap_inject(dev->pcap, data, size);
}
if (retval < 0) {
if (errno == EINTR) {
continue;
} else {
error = errno;
if (error != EAGAIN) {
VLOG_WARN_RL(&rl, "error sending Ethernet packet on"
" %s: %s", name, ovs_strerror(error));
}
}
} else if (retval != size) {
VLOG_WARN_RL(&rl, "sent partial Ethernet packet "
"(%"PRIuSIZE" bytes of "
"%"PRIuSIZE") on %s", retval, size, name);
error = EMSGSIZE;
} else {
break;
}
} else if (retval != size) {
VLOG_WARN_RL(&rl, "sent partial Ethernet packet (%"PRIuSIZE" bytes of "
"%"PRIuSIZE") on %s", retval, size, name);
error = EMSGSIZE;
} else {
break;
}
}
ovs_mutex_unlock(&dev->mutex);
if (may_steal) {
dpif_packet_delete(pkt);
for (i = 0; i < cnt; i++) {
dpif_packet_delete(pkts[i]);
}
}
return error;