@@ -1548,6 +1548,7 @@ netdev_bsd_update_flags(struct netdev *netdev_, enum netdev_flags off,
netdev_bsd_rxq_recv, \
netdev_bsd_rxq_wait, \
netdev_bsd_rxq_drain, \
+ NULL, \
}
const struct netdev_class netdev_bsd_class =
@@ -1887,6 +1887,17 @@ netdev_dpdk_send__(struct netdev_dpdk *dev, int qid,
}
}
+/* Drain tx queues
+ * This is done periodically to empty the intermediate queue in case of
+ * few packets (< INTERIM_QUEUE_BURST_THRESHOLD) are buffered in the queue.
+ */
+static int
+netdev_dpdk_txq_drain(struct netdev *netdev OVS_UNUSED,
+ int qid OVS_UNUSED, bool concurrent_txq OVS_UNUSED)
+{
+ return 0;
+}
+
static int
netdev_dpdk_eth_send(struct netdev *netdev, int qid,
struct dp_packet_batch *batch, bool may_steal,
@@ -3236,7 +3247,7 @@ unlock:
SET_CONFIG, SET_TX_MULTIQ, SEND, \
GET_CARRIER, GET_STATS, \
GET_FEATURES, GET_STATUS, \
- RECONFIGURE, RXQ_RECV) \
+ RECONFIGURE, RXQ_RECV, TXQ_DRAIN) \
{ \
NAME, \
true, /* is_pmd */ \
@@ -3303,6 +3314,7 @@ unlock:
RXQ_RECV, \
NULL, /* rx_wait */ \
NULL, /* rxq_drain */ \
+ TXQ_DRAIN /* txq_drain */ \
}
static const struct netdev_class dpdk_class =
@@ -3319,7 +3331,8 @@ static const struct netdev_class dpdk_class =
netdev_dpdk_get_features,
netdev_dpdk_get_status,
netdev_dpdk_reconfigure,
- netdev_dpdk_rxq_recv);
+ netdev_dpdk_rxq_recv,
+ netdev_dpdk_txq_drain);
static const struct netdev_class dpdk_ring_class =
NETDEV_DPDK_CLASS(
@@ -3335,7 +3348,8 @@ static const struct netdev_class dpdk_ring_class =
netdev_dpdk_get_features,
netdev_dpdk_get_status,
netdev_dpdk_reconfigure,
- netdev_dpdk_rxq_recv);
+ netdev_dpdk_rxq_recv,
+ NULL);
static const struct netdev_class dpdk_vhost_class =
NETDEV_DPDK_CLASS(
@@ -3351,7 +3365,8 @@ static const struct netdev_class dpdk_vhost_class =
NULL,
NULL,
netdev_dpdk_vhost_reconfigure,
- netdev_dpdk_vhost_rxq_recv);
+ netdev_dpdk_vhost_rxq_recv,
+ NULL);
static const struct netdev_class dpdk_vhost_client_class =
NETDEV_DPDK_CLASS(
"dpdkvhostuserclient",
@@ -3366,7 +3381,8 @@ static const struct netdev_class dpdk_vhost_client_class =
NULL,
NULL,
netdev_dpdk_vhost_client_reconfigure,
- netdev_dpdk_vhost_rxq_recv);
+ netdev_dpdk_vhost_rxq_recv,
+ NULL);
void
netdev_dpdk_register(void)
@@ -1414,6 +1414,7 @@ netdev_dummy_update_flags(struct netdev *netdev_,
netdev_dummy_rxq_recv, \
netdev_dummy_rxq_wait, \
netdev_dummy_rxq_drain, \
+ NULL, \
}
static const struct netdev_class dummy_class =
@@ -2865,6 +2865,7 @@ netdev_linux_update_flags(struct netdev *netdev_, enum netdev_flags off,
netdev_linux_rxq_recv, \
netdev_linux_rxq_wait, \
netdev_linux_rxq_drain, \
+ NULL, \
}
const struct netdev_class netdev_linux_class =
@@ -335,6 +335,11 @@ struct netdev_class {
* If the function returns a non-zero value, some of the packets might have
* been sent anyway.
*
+ * Some netdev provider - like in case of 'dpdk' - may buffer the batch
+ * of packets into an intermediate queue. Buffered packets shall be
+ * transmitted when the packet count exceeds a threshold (or) by the
+ * periodic call to the drain function.
+ *
* If 'may_steal' is false, the caller retains ownership of all the
* packets. If 'may_steal' is true, the caller transfers ownership of all
* the packets to the network device, regardless of success.
@@ -769,6 +774,9 @@ struct netdev_class {
/* Discards all packets waiting to be received from 'rx'. */
int (*rxq_drain)(struct netdev_rxq *rx);
+
+ /* Drain all packets waiting to be sent on 'qid' queue. */
+ int (*txq_drain)(struct netdev *netdev, int qid, bool concurrent_txq);
};
int netdev_register_provider(const struct netdev_class *);
@@ -873,7 +873,8 @@ get_stats(const struct netdev *netdev, struct netdev_stats *stats)
NULL, /* rx_dealloc */ \
NULL, /* rx_recv */ \
NULL, /* rx_wait */ \
- NULL, /* rx_drain */
+ NULL, /* rx_drain */ \
+ NULL, /* tx_drain */
#define TUNNEL_CLASS(NAME, DPIF_PORT, BUILD_HEADER, PUSH_HEADER, POP_HEADER) \
@@ -695,6 +695,15 @@ netdev_rxq_drain(struct netdev_rxq *rx)
: 0);
}
+/* Drain packets on the 'qid' queue. */
+int
+netdev_txq_drain(struct netdev *netdev, int qid, bool netdev_txq_drain)
+{
+ return (netdev->netdev_class->txq_drain
+ ? netdev->netdev_class->txq_drain(netdev, qid, netdev_txq_drain)
+ : EOPNOTSUPP);
+}
+
/* Configures the number of tx queues of 'netdev'. Returns 0 if successful,
* otherwise a positive errno value.
*
@@ -156,6 +156,7 @@ int netdev_rxq_drain(struct netdev_rxq *);
int netdev_send(struct netdev *, int qid, struct dp_packet_batch *,
bool may_steal, bool concurrent_txq);
void netdev_send_wait(struct netdev *, int qid);
+int netdev_txq_drain(struct netdev *, int qid, bool concurrent_txq);
/* native tunnel APIs */
/* Structure to pass parameters required to build a tunnel header. */