-
Notifications
You must be signed in to change notification settings - Fork 168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dev dpdk new counters #82
base: master
Are you sure you want to change the base?
Changes from 4 commits
4abc5e1
b28a23e
b8d1f76
ad3c05a
6a0e6df
87e58c6
62cc1fa
74eee1d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1806,12 +1806,14 @@ vr_interface_add(vr_interface_req *req, bool need_response) | |
} | ||
|
||
static void | ||
vr_interface_make_req(vr_interface_req *req, struct vr_interface *intf) | ||
vr_interface_make_req(vr_interface_req *req, struct vr_interface *intf, short core) | ||
{ | ||
unsigned int i; | ||
struct vr_interface_stats *stats; | ||
struct vr_interface_settings settings; | ||
short real_core; | ||
|
||
req->vifr_core = core; | ||
req->vifr_type = intf->vif_type; | ||
req->vifr_flags = intf->vif_flags; | ||
req->vifr_vrf = intf->vif_vrf; | ||
|
@@ -1860,15 +1862,50 @@ vr_interface_make_req(vr_interface_req *req, struct vr_interface *intf) | |
req->vifr_obytes = 0; | ||
req->vifr_opackets = 0; | ||
req->vifr_oerrors = 0; | ||
|
||
for (i = 0; i < vr_num_cpus; i++) { | ||
stats = vif_get_stats(intf, i); | ||
req->vifr_ibytes += stats->vis_ibytes; | ||
req->vifr_ipackets += stats->vis_ipackets; | ||
req->vifr_ierrors += stats->vis_ierrors; | ||
req->vifr_obytes += stats->vis_obytes; | ||
req->vifr_opackets += stats->vis_opackets; | ||
req->vifr_oerrors += stats->vis_oerrors; | ||
req->vifr_ifenqpkts = 0; | ||
req->vifr_ifenqdrops = 0; | ||
req->vifr_iftxrngenqpkts = 0; | ||
req->vifr_iftxrngenqdrops = 0; | ||
req->vifr_ifdeqpkts = 0; | ||
req->vifr_ifdeqdrops = 0; | ||
req->vifr_ifrxenqpkts = 0; | ||
req->vifr_ifrxenqdrops = 0; | ||
|
||
if (req->vifr_core == 0) { | ||
for (i = 0; i < vr_num_cpus; i++) { | ||
stats = vif_get_stats(intf, i); | ||
req->vifr_ibytes += stats->vis_ibytes; | ||
req->vifr_ipackets += stats->vis_ipackets; | ||
req->vifr_ierrors += stats->vis_ierrors; | ||
req->vifr_obytes += stats->vis_obytes; | ||
req->vifr_opackets += stats->vis_opackets; | ||
req->vifr_oerrors += stats->vis_oerrors; | ||
req->vifr_ifenqpkts += stats->vis_ifenqpkts; | ||
req->vifr_ifenqdrops += stats->vis_ifenqdrops; | ||
req->vifr_iftxrngenqpkts += stats->vis_iftxrngenqpkts; | ||
req->vifr_iftxrngenqdrops += stats->vis_iftxrngenqdrops; | ||
req->vifr_ifdeqpkts += stats->vis_ifdeqpkts; | ||
req->vifr_ifdeqdrops += stats->vis_ifdeqdrops; | ||
req->vifr_ifrxenqpkts += stats->vis_ifrxenqpkts; | ||
req->vifr_ifrxenqdrops += stats->vis_ifrxenqdrops; | ||
} | ||
} else if (req->vifr_core > 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to be safe, also check for vifr_core <= MAX. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can get to vr_interface_make_req() either from vr_interface_get() or vr_interface_dump(). They both perform validation for vifr_core not to exceed maximum value. vr_interface_make_req() itself checks only if we want summed up stats or per-core. The vifr_core value is always sane there. |
||
real_core = req->vifr_core - 1; | ||
stats = vif_get_stats(intf, real_core); | ||
req->vifr_ibytes = stats->vis_ibytes; | ||
req->vifr_ipackets = stats->vis_ipackets; | ||
req->vifr_ierrors = stats->vis_ierrors; | ||
req->vifr_obytes = stats->vis_obytes; | ||
req->vifr_opackets = stats->vis_opackets; | ||
req->vifr_oerrors = stats->vis_oerrors; | ||
req->vifr_ifenqpkts += stats->vis_ifenqpkts; | ||
req->vifr_ifenqdrops += stats->vis_ifenqdrops; | ||
req->vifr_iftxrngenqpkts += stats->vis_iftxrngenqpkts; | ||
req->vifr_iftxrngenqdrops += stats->vis_iftxrngenqdrops; | ||
req->vifr_ifdeqpkts += stats->vis_ifdeqpkts; | ||
req->vifr_ifdeqdrops += stats->vis_ifdeqdrops; | ||
req->vifr_ifrxenqpkts += stats->vis_ifrxenqpkts; | ||
req->vifr_ifrxenqdrops += stats->vis_ifrxenqdrops; | ||
} | ||
|
||
req->vifr_speed = -1; | ||
|
@@ -1935,6 +1972,13 @@ vr_interface_get(vr_interface_req *req) | |
struct vr_interface *vif = NULL; | ||
struct vrouter *router; | ||
vr_interface_req *resp = NULL; | ||
short core; | ||
|
||
if (req->vifr_core <= vr_num_cpus) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also check for vifr_core > 0 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
core = req->vifr_core; | ||
else | ||
core = 0; | ||
|
||
|
||
router = vrouter_get(req->vifr_rid); | ||
if (!router) { | ||
|
@@ -1954,7 +1998,7 @@ vr_interface_get(vr_interface_req *req) | |
goto generate_response; | ||
} | ||
|
||
vr_interface_make_req(resp, vif); | ||
vr_interface_make_req(resp, vif, core); | ||
} else | ||
ret = -ENOENT; | ||
|
||
|
@@ -1974,8 +2018,12 @@ vr_interface_dump(vr_interface_req *r) | |
vr_interface_req *resp = NULL; | ||
struct vr_interface *vif; | ||
struct vrouter *router = vrouter_get(r->vifr_vrf); | ||
short core = r->vifr_core; | ||
struct vr_message_dumper *dumper = NULL; | ||
|
||
if ((unsigned int)core > vr_num_cpus) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be conststeny, change to "if ((core < 0) || (core > vr_num_cpus)) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did it like this: if (r->vifr_core > 0 && r->vifr_core <= (int)vr_num_cpus) => sane; else => core = 0; The same in vr_interface_get(). |
||
goto generate_response; | ||
|
||
if (!router && (ret = -ENODEV)) | ||
goto generate_response; | ||
|
||
|
@@ -1998,7 +2046,7 @@ vr_interface_dump(vr_interface_req *r) | |
i < router->vr_max_interfaces; i++) { | ||
vif = router->vr_interfaces[i]; | ||
if (vif) { | ||
vr_interface_make_req(resp, vif); | ||
vr_interface_make_req(resp, vif, core); | ||
ret = vr_message_dump_object(dumper, VR_INTERFACE_OBJECT_ID, resp); | ||
if (ret <= 0) | ||
break; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,10 @@ | |
#include <rte_errno.h> | ||
#include <rte_ethdev.h> | ||
#include <rte_ip.h> | ||
#include <rte_port_ring.h> | ||
|
||
extern struct vr_interface_stats *vif_get_stats(struct vr_interface *, | ||
unsigned short); | ||
|
||
/* | ||
* dpdk_virtual_if_add - add a virtual (virtio) interface to vrouter. | ||
|
@@ -830,6 +834,8 @@ dpdk_if_tx(struct vr_interface *vif, struct vr_packet *pkt) | |
struct vr_dpdk_queue *tx_queue = &lcore->lcore_tx_queues[vif_idx]; | ||
struct vr_dpdk_queue *monitoring_tx_queue; | ||
struct vr_packet *p_clone; | ||
struct rte_port_out_stats port_stats; | ||
struct vr_interface_stats *vr_stats; | ||
int ret; | ||
|
||
RTE_LOG(DEBUG, VROUTER,"%s: TX packet to interface %s\n", __func__, | ||
|
@@ -854,10 +860,14 @@ dpdk_if_tx(struct vr_interface *vif, struct vr_packet *pkt) | |
|
||
if (unlikely(vif->vif_type == VIF_TYPE_AGENT)) { | ||
ret = rte_ring_mp_enqueue(vr_dpdk.packet_ring, m); | ||
vr_stats = vif_get_stats(vif, lcore_id); | ||
if (ret != 0) { | ||
/* TODO: a separate counter for this drop */ | ||
vif_drop_pkt(vif, vr_dpdk_mbuf_to_pkt(m), 0); | ||
vr_stats->vis_iftxrngenqdrops++; | ||
return -1; | ||
} else { | ||
vr_stats->vis_iftxrngenqpkts++; | ||
} | ||
#ifdef VR_DPDK_TX_PKT_DUMP | ||
#ifdef VR_DPDK_PKT_DUMP_VIF_FILTER | ||
|
@@ -927,13 +937,34 @@ dpdk_if_tx(struct vr_interface *vif, struct vr_packet *pkt) | |
rte_pktmbuf_dump(stdout, m, 0x60); | ||
#endif | ||
|
||
vr_stats = vif_get_stats(tx_queue->q_vif, lcore_id); | ||
if (likely(tx_queue->txq_ops.f_tx != NULL)) { | ||
tx_queue->txq_ops.f_tx(tx_queue->q_queue_h, m); | ||
if (lcore_id == VR_DPDK_PACKET_LCORE_ID) | ||
tx_queue->txq_ops.f_flush(tx_queue->q_queue_h); | ||
|
||
/** | ||
* Update counters for: | ||
* - packets enqueued to the interface successfully. | ||
* - packets which have been dropped when .f_tx() could not send. | ||
* If we write to ring instead of NIC's queue, count it as a ring | ||
* enqueue. | ||
*/ | ||
if (likely(tx_queue->txq_ops.f_stats != NULL)) { | ||
tx_queue->txq_ops.f_stats(tx_queue->q_queue_h, &port_stats, 0); | ||
|
||
if (tx_queue->txq_ops.f_tx == rte_port_ring_writer_ops.f_tx) { | ||
vr_stats->vis_iftxrngenqpkts = port_stats.n_pkts_in; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. n_pkts_out would be better (instead of n_pkts_in), but it looks like this is what the DPDK patch has... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, currently n_pkts_in is in both reader and writer stats structures. |
||
vr_stats->vis_iftxrngenqdrops = port_stats.n_pkts_drop; | ||
} else { | ||
vr_stats->vis_ifenqpkts = port_stats.n_pkts_in; | ||
vr_stats->vis_ifenqdrops = port_stats.n_pkts_drop; | ||
} | ||
} | ||
} else { | ||
RTE_LOG(DEBUG, VROUTER,"%s: error TXing to interface %s: no queue for lcore %u\n", | ||
__func__, vif->vif_name, lcore_id); | ||
vr_stats->vis_ifenqdrops++; | ||
vif_drop_pkt(vif, vr_dpdk_mbuf_to_pkt(m), 0); | ||
return -1; | ||
} | ||
|
@@ -951,6 +982,8 @@ dpdk_if_rx(struct vr_interface *vif, struct vr_packet *pkt) | |
struct vr_dpdk_queue *tx_queue = &lcore->lcore_tx_queues[vif_idx]; | ||
struct vr_dpdk_queue *monitoring_tx_queue; | ||
struct vr_packet *p_clone; | ||
struct rte_port_out_stats port_stats; | ||
struct vr_interface_stats *vr_stats; | ||
|
||
RTE_LOG(DEBUG, VROUTER,"%s: TX packet to interface %s\n", __func__, | ||
vif->vif_name); | ||
|
@@ -979,11 +1012,30 @@ dpdk_if_rx(struct vr_interface *vif, struct vr_packet *pkt) | |
rte_pktmbuf_dump(stdout, m, 0x60); | ||
#endif | ||
|
||
vr_stats = vif_get_stats(tx_queue->q_vif, lcore_id); | ||
if (likely(tx_queue->txq_ops.f_tx != NULL)) { | ||
tx_queue->txq_ops.f_tx(tx_queue->q_queue_h, m); | ||
|
||
/** | ||
* Update counters for: | ||
* - packets enqueued to the interface successfully. | ||
* - packets which have been dropped when .f_tx() could not send. | ||
*/ | ||
if (likely(tx_queue->txq_ops.f_stats != NULL)) { | ||
tx_queue->txq_ops.f_stats(tx_queue->q_queue_h, &port_stats, 0); | ||
|
||
if (tx_queue->txq_ops.f_tx == rte_port_ring_writer_ops.f_tx) { | ||
vr_stats->vis_iftxrngenqpkts = port_stats.n_pkts_in; | ||
vr_stats->vis_iftxrngenqdrops = port_stats.n_pkts_drop; | ||
} else { | ||
vr_stats->vis_ifenqpkts = port_stats.n_pkts_in; | ||
vr_stats->vis_ifenqdrops = port_stats.n_pkts_drop; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MIght be good to put the above code in an inline function as it is called in multiple places. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. Two functions: one to work with rte_port_out_stats, the other with rte_port_in_stats. Put them in vr_dpdk.h (not sure if good place). |
||
} else { | ||
RTE_LOG(DEBUG, VROUTER,"%s: error TXing to interface %s: no queue for lcore %u\n", | ||
__func__, vif->vif_name, lcore_id); | ||
vr_stats->vis_ifenqdrops++; | ||
vif_drop_pkt(vif, vr_dpdk_mbuf_to_pkt(m), 0); | ||
return -1; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to vifr_ifrxrng as you suggested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.