From f4fd623c4c253be8d4020771b65a4b3d13c86ae8 Mon Sep 17 00:00:00 2001 From: Daniele Di Proietto Date: Mon, 23 Jun 2014 11:43:58 -0700 Subject: 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 Acked-by: Pravin B Shelar --- lib/netdev-bsd.c | 55 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 24 deletions(-) (limited to 'lib/netdev-bsd.c') diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c index 92838a5c1..65ae9f9da 100644 --- a/lib/netdev-bsd.c +++ b/lib/netdev-bsd.c @@ -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; -- cgit v1.2.1