2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-15 14:17:18 +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

@@ -846,51 +846,61 @@ netdev_dummy_rxq_drain(struct netdev_rxq *rxq_)
}
static int
netdev_dummy_send(struct netdev *netdev, struct dpif_packet *pkt,
netdev_dummy_send(struct netdev *netdev, struct dpif_packet **pkts, int cnt,
bool may_steal)
{
struct netdev_dummy *dev = netdev_dummy_cast(netdev);
const void *buffer = ofpbuf_data(&pkt->ofpbuf);
size_t size = ofpbuf_size(&pkt->ofpbuf);
int error = 0;
int i;
if (size < ETH_HEADER_LEN) {
return EMSGSIZE;
} else {
const struct eth_header *eth = buffer;
int max_size;
for (i = 0; i < cnt; i++) {
const void *buffer = ofpbuf_data(&pkts[i]->ofpbuf);
size_t size = ofpbuf_size(&pkts[i]->ofpbuf);
if (size < ETH_HEADER_LEN) {
error = EMSGSIZE;
break;
} else {
const struct eth_header *eth = buffer;
int max_size;
ovs_mutex_lock(&dev->mutex);
max_size = dev->mtu + ETH_HEADER_LEN;
ovs_mutex_unlock(&dev->mutex);
if (eth->eth_type == htons(ETH_TYPE_VLAN)) {
max_size += VLAN_HEADER_LEN;
}
if (size > max_size) {
error = EMSGSIZE;
break;
}
}
ovs_mutex_lock(&dev->mutex);
max_size = dev->mtu + ETH_HEADER_LEN;
dev->stats.tx_packets++;
dev->stats.tx_bytes += size;
dummy_packet_conn_send(&dev->conn, buffer, size);
if (dev->tx_pcap) {
struct ofpbuf packet;
ofpbuf_use_const(&packet, buffer, size);
ovs_pcap_write(dev->tx_pcap, &packet);
fflush(dev->tx_pcap);
}
ovs_mutex_unlock(&dev->mutex);
if (eth->eth_type == htons(ETH_TYPE_VLAN)) {
max_size += VLAN_HEADER_LEN;
}
if (size > max_size) {
return EMSGSIZE;
}
}
ovs_mutex_lock(&dev->mutex);
dev->stats.tx_packets++;
dev->stats.tx_bytes += size;
dummy_packet_conn_send(&dev->conn, buffer, size);
if (dev->tx_pcap) {
struct ofpbuf packet;
ofpbuf_use_const(&packet, buffer, size);
ovs_pcap_write(dev->tx_pcap, &packet);
fflush(dev->tx_pcap);
}
ovs_mutex_unlock(&dev->mutex);
if (may_steal) {
dpif_packet_delete(pkt);
for (i = 0; i < cnt; i++) {
dpif_packet_delete(pkts[i]);
}
}
return 0;
return error;
}
static int