#endif
if (PREDICT_TRUE(tx_head > tx_tail))
{
+ int i; u32 bytes = 0;
+ struct rte_mbuf **pkts = &tx_vector[tx_tail];
+ for (i = 0; i < (tx_head - tx_tail); i++) {
+ struct rte_mbuf *buff = pkts[i];
+ bytes += rte_pktmbuf_data_len(buff);
+ }
+
/* no wrap, transmit in one burst */
rv = rte_vhost_enqueue_burst(&xd->vu_vhost_dev, offset + VIRTIO_RXQ,
&tx_vector[tx_tail],
(uint16_t) (tx_head-tx_tail));
if (PREDICT_TRUE(rv > 0))
{
+ dpdk_vu_vring *vring = &(xd->vu_intf->vrings[offset + VIRTIO_RXQ]);
+ vring->packets += rv;
+ vring->bytes += bytes;
+
if (dpdk_vhost_user_want_interrupt(xd, offset + VIRTIO_RXQ)) {
- dpdk_vu_vring *vring = &(xd->vu_intf->vrings[offset + VIRTIO_RXQ]);
vring->n_since_last_int += rv;
f64 now = vlib_time_now (vm);
* so we can try to transmit the rest. If we didn't transmit
* everything, stop now.
*/
+ int i; u32 bytes = 0;
+ struct rte_mbuf **pkts = &tx_vector[tx_tail];
+ for (i = 0; i < (DPDK_TX_RING_SIZE - tx_tail); i++) {
+ struct rte_mbuf *buff = pkts[i];
+ bytes += rte_pktmbuf_data_len(buff);
+ }
rv = rte_vhost_enqueue_burst(&xd->vu_vhost_dev, offset + VIRTIO_RXQ,
&tx_vector[tx_tail],
(uint16_t) (DPDK_TX_RING_SIZE - tx_tail));
if (PREDICT_TRUE(rv > 0))
{
+ dpdk_vu_vring *vring = &(xd->vu_intf->vrings[offset + VIRTIO_RXQ]);
+ vring->packets += rv;
+ vring->bytes += bytes;
+
if (dpdk_vhost_user_want_interrupt(xd, offset + VIRTIO_RXQ)) {
- dpdk_vu_vring *vring = &(xd->vu_intf->vrings[offset + VIRTIO_RXQ]);
vring->n_since_last_int += rv;
f64 now = vlib_time_now (vm);
memset (&xd->last_stats, 0, sizeof (xd->last_stats));
}
rte_eth_xstats_reset(xd->device_index);
+
+ if (PREDICT_FALSE(xd->dev_type == VNET_DPDK_DEV_VHOST_USER)) {
+ int i;
+ for (i = 0; i < xd->rx_q_used * VIRTIO_QNUM; i++) {
+ xd->vu_intf->vrings[i].packets = 0;
+ xd->vu_intf->vrings[i].bytes = 0;
+ }
+ }
}
#ifdef RTE_LIBRTE_KNI
u32 callfd_idx;
u32 n_since_last_int;
f64 int_deadline;
+ u64 packets;
+ u64 bytes;
} dpdk_vu_vring;
typedef struct {
bm->pktmbuf_pools[socket_id],
xd->rx_vectors[queue_id], VLIB_FRAME_SIZE);
+ int i; u32 bytes = 0;
+ struct rte_mbuf **pkts = xd->rx_vectors[queue_id];
+ for (i = 0; i < n_buffers; i++) {
+ struct rte_mbuf *buff = pkts[i];
+ bytes += rte_pktmbuf_data_len(buff);
+ }
+
f64 now = vlib_time_now (vm);
+ dpdk_vu_vring *vring = &(xd->vu_intf->vrings[offset + VIRTIO_TXQ]);
+ vring->packets += n_buffers;
+ vring->bytes += bytes;
+
/* send pending interrupts if needed */
if (dpdk_vhost_user_want_interrupt(xd, offset + VIRTIO_TXQ)) {
- dpdk_vu_vring *vring = &(xd->vu_intf->vrings[offset + VIRTIO_TXQ]);
vring->n_since_last_int += n_buffers;
if ((vring->n_since_last_int && (vring->int_deadline < now))
}
if (dpdk_vhost_user_want_interrupt(xd, offset + VIRTIO_RXQ)) {
- dpdk_vu_vring *vring = &(xd->vu_intf->vrings[offset + VIRTIO_RXQ]);
+ vring = &(xd->vu_intf->vrings[offset + VIRTIO_RXQ]);
if (vring->n_since_last_int && (vring->int_deadline < now))
dpdk_vhost_user_send_interrupt(vm, xd, offset + VIRTIO_RXQ);
}
format_dpdk_rss_hf_name, di.flow_type_rss_offloads);
}
+ if (verbose && xd->dev_type == VNET_DPDK_DEV_VHOST_USER) {
+ s = format(s, "%Uqueue size (max): rx %d (%d) tx %d (%d)\n",
+ format_white_space, indent + 2,
+ xd->rx_q_used, xd->rx_q_used,
+ xd->tx_q_used, xd->tx_q_used);
+ }
+
if (xd->cpu_socket > -1)
s = format (s, "%Ucpu socket %d",
format_white_space, indent + 2,
vec_foreach(xstat, xd->xstats)
{
- if (xstat->value)
+ if (verbose == 2 || (verbose && xstat->value))
{
/* format_c_identifier don't like c strings inside vector */
u8 * name = format(0,"%s", xstat->name);
}
}
+ if (verbose && xd->dev_type == VNET_DPDK_DEV_VHOST_USER) {
+ int i;
+ for (i = 0; i < xd->rx_q_used * VIRTIO_QNUM; i++) {
+ u8 * name;
+ if (verbose == 2 || xd->vu_intf->vrings[i].packets) {
+ if (i & 1) {
+ name = format(NULL, "tx q%d packets", i >> 1);
+ } else {
+ name = format(NULL, "rx q%d packets", i >> 1);
+ }
+ xs = format(xs, "\n%U%-38U%16Ld",
+ format_white_space, indent + 4,
+ format_c_identifier, name, xd->vu_intf->vrings[i].packets);
+ vec_free(name);
+
+ if (i & 1) {
+ name = format(NULL, "tx q%d bytes", i >> 1);
+ } else {
+ name = format(NULL, "rx q%d bytes", i >> 1);
+ }
+ xs = format(xs, "\n%U%-38U%16Ld",
+ format_white_space, indent + 4,
+ format_c_identifier, name, xd->vu_intf->vrings[i].bytes);
+ vec_free(name);
+ }
+ }
+ }
+
if (xs)
{
s = format(s, "\n%Uextended stats:%v",
clib_error_t * error;
dpdk_device_and_queue_t * dq;
int num_qpairs = 1;
+ dpdk_vu_intf_t *vui = NULL;
#if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0)
num_qpairs = dm->use_rss < 1 ? 1 : tm->n_vlib_mains;
xd->vu_if_id = if_id;
// reset virtqueues
+ vui = xd->vu_intf;
for (j = 0; j < num_qpairs * VIRTIO_QNUM; j++) {
memset(xd->vu_vhost_dev.virtqueue[j], 0, sizeof(struct vhost_virtqueue));
xd->vu_vhost_dev.virtqueue[j]->kickfd = -1;
xd->vu_vhost_dev.virtqueue[j]->callfd = -1;
xd->vu_vhost_dev.virtqueue[j]->backend = -1;
+ vui->vrings[j].packets = 0;
+ vui->vrings[j].bytes = 0;
}
// reset lockp
xd->device_index = xd - dm->devices;
xd->per_interface_next_index = ~0;
- xd->vu_intf = NULL;
+ xd->vu_intf = clib_mem_alloc (sizeof(*(xd->vu_intf)));
xd->vu_vhost_dev.mem = clib_mem_alloc (sizeof(struct virtio_memory) +
VHOST_MEMORY_MAX_NREGIONS *
* New virtqueue structure is an array of VHOST_MAX_QUEUE_PAIRS * 2
* We need to allocate numq pairs.
*/
+ vui = xd->vu_intf;
for (j = 0; j < num_qpairs * VIRTIO_QNUM; j++) {
xd->vu_vhost_dev.virtqueue[j] = clib_mem_alloc (sizeof(struct vhost_virtqueue));
memset(xd->vu_vhost_dev.virtqueue[j], 0, sizeof(struct vhost_virtqueue));
xd->vu_vhost_dev.virtqueue[j]->kickfd = -1;
xd->vu_vhost_dev.virtqueue[j]->callfd = -1;
xd->vu_vhost_dev.virtqueue[j]->backend = -1;
+ vui->vrings[j].packets = 0;
+ vui->vrings[j].bytes = 0;
}
dpdk_device_lock_init(xd);
sw = vnet_get_hw_sw_interface (dm->vnet_main, xd->vlib_hw_if_index);
xd->vlib_sw_if_index = sw->sw_if_index;
- if (!xd->vu_intf)
- xd->vu_intf = clib_mem_alloc (sizeof(*(xd->vu_intf)));
-
*hw_if_index = xd->vlib_hw_if_index;
DBG_SOCK("xd->device_index: %d, dm->input_cpu_count: %d, "