diff --git a/dp-core/vr_bridge.c b/dp-core/vr_bridge.c index 222f8e273..afe64508f 100644 --- a/dp-core/vr_bridge.c +++ b/dp-core/vr_bridge.c @@ -297,7 +297,7 @@ bridge_entry_make_req(struct vr_route_req *resp, struct vr_bridge_entry *ent) { memset(resp, 0, sizeof(struct vr_route_req)); resp->rtr_req.rtr_mac_size = VR_ETHER_ALEN; - resp->rtr_req.rtr_mac = vr_zalloc(VR_ETHER_ALEN); + resp->rtr_req.rtr_mac = vr_zalloc(VR_ETHER_ALEN, VR_ROUTE_REQ_MAC_OBJECT); if (!resp->rtr_req.rtr_mac) return -ENOMEM; VR_MAC_COPY(resp->rtr_req.rtr_mac, ent->be_key.be_mac); @@ -316,7 +316,7 @@ static void bridge_entry_req_destroy(struct vr_route_req *resp) { if (resp->rtr_req.rtr_mac) - vr_free(resp->rtr_req.rtr_mac); + vr_free(resp->rtr_req.rtr_mac, VR_ROUTE_REQ_MAC_OBJECT); } static int diff --git a/dp-core/vr_btable.c b/dp-core/vr_btable.c index 429ba7671..7f949ed4b 100644 --- a/dp-core/vr_btable.c +++ b/dp-core/vr_btable.c @@ -82,7 +82,7 @@ vr_btable_free(struct vr_btable *table) } } - vr_free(table); + vr_free(table, VR_BTABLE_OBJECT); return; } @@ -126,7 +126,7 @@ vr_btable_alloc(unsigned int num_entries, unsigned int entry_size) alloc_size = sizeof(*table) + (total_parts * (sizeof(void *))) + (total_parts * sizeof(struct vr_btable_partition)); - table = vr_zalloc(alloc_size); + table = vr_zalloc(alloc_size, VR_BTABLE_OBJECT); if (!table) return NULL; @@ -186,7 +186,7 @@ vr_btable_attach(struct iovec *iov, unsigned int iov_len, alloc_size += (sizeof(struct vr_btable_partition) * iov_len); - table = (struct vr_btable *)vr_zalloc(alloc_size); + table = (struct vr_btable *)vr_zalloc(alloc_size, VR_BTABLE_OBJECT); if (!table) return NULL; diff --git a/dp-core/vr_flow.c b/dp-core/vr_flow.c index d8fcf67d0..15c2a6db7 100644 --- a/dp-core/vr_flow.c +++ b/dp-core/vr_flow.c @@ -312,7 +312,7 @@ vr_flow_queue_free(struct vrouter *router, void *arg) vr_flow_set_forwarding_md(router, fe, vfq->vfq_index, &fmd); vr_flush_flow_queue(router, fe, &fmd, vfq); } - vr_free(vfq); + vr_free(vfq, VR_FLOW_QUEUE_OBJECT); return; } @@ -322,7 +322,7 @@ vr_flow_queue_free_defer(struct vr_flow_md *flmd, struct vr_flow_queue *vfq) struct vr_defer_data *vdd = flmd->flmd_defer_data; if (!vdd) { - vr_free(vfq); + vr_free(vfq, VR_FLOW_QUEUE_OBJECT); return; } @@ -377,7 +377,8 @@ vr_find_free_entry(struct vrouter *router, struct vr_flow *key, uint8_t type, if (fe) { *fe_index += index; if (need_hold) { - fe->fe_hold_list = vr_zalloc(sizeof(struct vr_flow_queue)); + fe->fe_hold_list = vr_zalloc(sizeof(struct vr_flow_queue), + VR_FLOW_QUEUE_OBJECT); if (!fe->fe_hold_list) { vr_reset_flow_entry(router, fe, *fe_index); fe = NULL; @@ -1126,7 +1127,7 @@ vr_flow_flush(void *arg) } exit_flush: - vr_free(flmd); + vr_free(flmd, VR_FLOW_METADATA_OBJECT); return; } @@ -1292,7 +1293,8 @@ vr_flow_schedule_transition(struct vrouter *router, vr_flow_req *req, struct vr_flow_md *flmd; struct vr_defer_data *defer = NULL; - flmd = (struct vr_flow_md *)vr_malloc(sizeof(*flmd)); + flmd = (struct vr_flow_md *)vr_malloc(sizeof(*flmd), + VR_FLOW_METADATA_OBJECT); if (!flmd) return -ENOMEM; @@ -1302,7 +1304,7 @@ vr_flow_schedule_transition(struct vrouter *router, vr_flow_req *req, if (fe->fe_hold_list) { defer = vr_get_defer_data(sizeof(*defer)); if (!defer) { - vr_free(flmd); + vr_free(flmd, VR_FLOW_METADATA_OBJECT); return -ENOMEM; } } @@ -1409,7 +1411,8 @@ vr_flow_set(struct vrouter *router, vr_flow_req *req) if ((req->fr_action == VR_FLOW_ACTION_HOLD) && (fe->fe_action != req->fr_action)) { if (!fe->fe_hold_list) { - fe->fe_hold_list = vr_zalloc(sizeof(struct vr_flow_queue)); + fe->fe_hold_list = vr_zalloc(sizeof(struct vr_flow_queue), + VR_FLOW_QUEUE_OBJECT); if (!fe->fe_hold_list) return -ENOMEM; } @@ -1479,17 +1482,17 @@ vr_flow_req_destroy(vr_flow_req *req) return; if (req->fr_file_path) { - vr_free(req->fr_file_path); + vr_free(req->fr_file_path, VR_FLOW_REQ_PATH_OBJECT); req->fr_file_path = NULL; } if (req->fr_hold_stat && req->fr_hold_stat_size) { - vr_free(req->fr_hold_stat); + vr_free(req->fr_hold_stat, VR_FLOW_HOLD_STAT_OBJECT); req->fr_hold_stat = NULL; req->fr_hold_stat_size = 0; } - vr_free(req); + vr_free(req, VR_FLOW_REQ_OBJECT); return; } @@ -1499,7 +1502,7 @@ vr_flow_req_get(vr_flow_req *ref_req) { unsigned int hold_stat_size; unsigned int num_cpus = vr_num_cpus; - vr_flow_req *req = vr_zalloc(sizeof(*req)); + vr_flow_req *req = vr_zalloc(sizeof(*req), VR_FLOW_REQ_OBJECT); if (!req) return NULL; @@ -1512,9 +1515,10 @@ vr_flow_req_get(vr_flow_req *ref_req) } if (vr_flow_path) { - req->fr_file_path = vr_zalloc(VR_UNIX_PATH_MAX); + req->fr_file_path = vr_zalloc(VR_UNIX_PATH_MAX, + VR_FLOW_REQ_PATH_OBJECT); if (!req->fr_file_path) { - vr_free(req); + vr_free(req, VR_FLOW_REQ_OBJECT); return NULL; } } @@ -1523,14 +1527,14 @@ vr_flow_req_get(vr_flow_req *ref_req) num_cpus = VR_FLOW_MAX_CPUS; hold_stat_size = num_cpus * sizeof(uint32_t); - req->fr_hold_stat = vr_zalloc(hold_stat_size); + req->fr_hold_stat = vr_zalloc(hold_stat_size, VR_FLOW_HOLD_STAT_OBJECT); if (!req->fr_hold_stat) { if (vr_flow_path && req->fr_file_path) { - vr_free(req->fr_file_path); + vr_free(req->fr_file_path, VR_FLOW_REQ_PATH_OBJECT); req->fr_file_path = NULL; } - vr_free(req); + vr_free(req, VR_FLOW_REQ_OBJECT); return NULL; } req->fr_hold_stat_size = num_cpus; @@ -1613,7 +1617,7 @@ vr_flow_table_info_destroy(struct vrouter *router) if (!router->vr_flow_table_info) return; - vr_free(router->vr_flow_table_info); + vr_free(router->vr_flow_table_info, VR_FLOW_TABLE_INFO_OBJECT); router->vr_flow_table_info = NULL; router->vr_flow_table_info_size = 0; @@ -1640,7 +1644,8 @@ vr_flow_table_info_init(struct vrouter *router) return 0; size = sizeof(struct vr_flow_table_info) + sizeof(uint32_t) * vr_num_cpus; - infop = (struct vr_flow_table_info *)vr_zalloc(size); + infop = (struct vr_flow_table_info *)vr_zalloc(size, + VR_FLOW_TABLE_INFO_OBJECT); if (!infop) return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, size); @@ -1758,7 +1763,7 @@ static void vr_link_local_ports_exit(struct vrouter *router) { if (router->vr_link_local_ports) { - vr_free(router->vr_link_local_ports); + vr_free(router->vr_link_local_ports, VR_FLOW_LINK_LOCAL_OBJECT); router->vr_link_local_ports = NULL; router->vr_link_local_ports_size = 0; } @@ -1779,7 +1784,7 @@ vr_link_local_ports_init(struct vrouter *router) /* Bits to Bytes */ bytes /= 8; - router->vr_link_local_ports = vr_zalloc(bytes); + router->vr_link_local_ports = vr_zalloc(bytes, VR_FLOW_LINK_LOCAL_OBJECT); if (!router->vr_link_local_ports) return -1; router->vr_link_local_ports_size = bytes; diff --git a/dp-core/vr_fragment.c b/dp-core/vr_fragment.c index 6618b83c9..364d9fe9f 100644 --- a/dp-core/vr_fragment.c +++ b/dp-core/vr_fragment.c @@ -151,7 +151,7 @@ vr_fragment_queue_element_free(struct vr_fragment_queue_element *vfqe, vr_pfree(vfqe->fqe_pnode.pl_packet, drop_reason); } - vr_free(vfqe); + vr_free(vfqe, VR_FRAGMENT_QUEUE_ELEMENT_OBJECT); return; } @@ -165,7 +165,7 @@ fragment_free_frag(struct vr_fragment *frag) vr_fragment_queue_element_free(fqe, VP_DROP_FRAGMENTS); } - vr_free(frag); + vr_free(frag, VR_FRAGMENT_OBJECT); return; } @@ -217,7 +217,7 @@ vr_assembler_table_scan_exit(void) { if (vr_assembler_table_scan_timer) { vr_delete_timer(vr_assembler_table_scan_timer); - vr_free(vr_assembler_table_scan_timer); + vr_free(vr_assembler_table_scan_timer, VR_TIMER_OBJECT); vr_assembler_table_scan_timer = NULL; } @@ -229,7 +229,7 @@ vr_assembler_table_scan_init(void (*scanner)(void *)) { struct vr_timer *vtimer; - vr_assembler_table_scan_timer = vr_zalloc(sizeof(*vtimer)); + vr_assembler_table_scan_timer = vr_zalloc(sizeof(*vtimer), VR_TIMER_OBJECT); if (!vr_assembler_table_scan_timer) return -ENOMEM; @@ -239,7 +239,7 @@ vr_assembler_table_scan_init(void (*scanner)(void *)) vtimer->vt_msecs = (VR_ASSEMBLER_TIMEOUT_TIME * 1000) / VR_LINUX_ASSEMBLER_BUCKETS; if (vr_create_timer(vtimer)) { - vr_free(vtimer); + vr_free(vtimer, VR_TIMER_OBJECT); vr_assembler_table_scan_timer = NULL; } @@ -288,7 +288,7 @@ vr_fragment_assembler(struct vr_fragment **head_p, (list_length > VR_MAX_FRAGMENTS_PER_ASSEMBLER_QUEUE)) goto exit_assembly; - frag = vr_zalloc(sizeof(*frag)); + frag = vr_zalloc(sizeof(*frag), VR_FRAGMENT_OBJECT); if (!frag) { ret = -ENOMEM; goto exit_assembly; @@ -398,7 +398,7 @@ vr_fragment_enqueue(struct vrouter *router, goto fail; } - fqe = vr_malloc(sizeof(*fqe)); + fqe = vr_malloc(sizeof(*fqe), VR_FRAGMENT_QUEUE_ELEMENT_OBJECT); if (!fqe) { goto fail; } @@ -439,7 +439,7 @@ vr_fragment_enqueue(struct vrouter *router, fail: if (fqe) - vr_free(fqe); + vr_free(fqe, VR_FRAGMENT_QUEUE_ELEMENT_OBJECT); vr_pfree(pkt, VP_DROP_FRAGMENTS); return -1; @@ -592,7 +592,7 @@ fragment_table_scanner_init(struct vrouter *router, struct vr_btable *table) num_entries = vr_btable_entries(table); - scanner = vr_zalloc(sizeof(*scanner)); + scanner = vr_zalloc(sizeof(*scanner), VR_FRAGMENT_SCANNER_OBJECT); if (!scanner) { vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, num_entries); return NULL; @@ -603,7 +603,7 @@ fragment_table_scanner_init(struct vrouter *router, struct vr_btable *table) scanner->sp_num_entries = num_entries; scanner->sp_last_scanned_entry = -1; - vtimer = vr_malloc(sizeof(*vtimer)); + vtimer = vr_malloc(sizeof(*vtimer), VR_TIMER_OBJECT); if (!vtimer) { vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, num_entries); goto fail_init; @@ -622,7 +622,7 @@ fragment_table_scanner_init(struct vrouter *router, struct vr_btable *table) fail_init: if (scanner) - vr_free(scanner); + vr_free(scanner, VR_FRAGMENT_SCANNER_OBJECT); return NULL; } @@ -632,15 +632,17 @@ vr_fragment_table_scanner_exit(struct vrouter *router) { if (router->vr_fragment_table_scanner) { vr_delete_timer(router->vr_fragment_table_scanner); - vr_free(router->vr_fragment_table_scanner->vt_vr_arg); - vr_free(router->vr_fragment_table_scanner); + vr_free(router->vr_fragment_table_scanner->vt_vr_arg, + VR_FRAGMENT_SCANNER_OBJECT); + vr_free(router->vr_fragment_table_scanner, VR_TIMER_OBJECT); router->vr_fragment_table_scanner = NULL; } if (router->vr_fragment_otable_scanner) { vr_delete_timer(router->vr_fragment_otable_scanner); - vr_free(router->vr_fragment_otable_scanner->vt_vr_arg); - vr_free(router->vr_fragment_otable_scanner); + vr_free(router->vr_fragment_otable_scanner->vt_vr_arg, + VR_FRAGMENT_SCANNER_OBJECT); + vr_free(router->vr_fragment_otable_scanner, VR_TIMER_OBJECT); router->vr_fragment_otable_scanner = NULL; } diff --git a/dp-core/vr_htable.c b/dp-core/vr_htable.c index 758036d56..6c564b3ec 100644 --- a/dp-core/vr_htable.c +++ b/dp-core/vr_htable.c @@ -203,7 +203,7 @@ vr_htable_delete(vr_htable_t htable) if (table->otable) vr_btable_free(table->otable); - vr_free(table); + vr_free(table, VR_HTABLE_OBJECT); } vr_htable_t @@ -222,7 +222,7 @@ vr_htable_create(unsigned int entries, unsigned int oentries, return NULL; } - table = vr_zalloc(sizeof(struct vr_htable)); + table = vr_zalloc(sizeof(struct vr_htable), VR_HTABLE_OBJECT); if (!table) { vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, sizeof(struct vr_htable)); diff --git a/dp-core/vr_index_table.c b/dp-core/vr_index_table.c index 7e30f55ce..bbbeb9047 100644 --- a/dp-core/vr_index_table.c +++ b/dp-core/vr_index_table.c @@ -74,7 +74,7 @@ __vr_itable_del(struct vr_itbl *table, unsigned int index, if (*old) { ptr[id] = NULL; if (vr_stride_empty(ptr, table->stride_len[cnt]) == 1) { - vr_free(ptr); + vr_free(ptr, VR_ITABLE_OBJECT); return 1; } } @@ -92,7 +92,7 @@ __vr_itable_del(struct vr_itbl *table, unsigned int index, */ ptr[id] = NULL; if (vr_stride_empty(ptr, table->stride_len[cnt]) == 1) { - vr_free(ptr); + vr_free(ptr, VR_ITABLE_OBJECT); /* If the stride deleted is first, mark the head null */ if (cnt == 0) { @@ -178,7 +178,7 @@ __vr_itable_exit(struct vr_itbl *table, vr_itable_del_cb_t func, } /* All stride entries are delete invoked. Delete the stride now */ - vr_free(ptr); + vr_free(ptr, VR_ITABLE_OBJECT); return; } @@ -189,13 +189,13 @@ __vr_itable_exit(struct vr_itbl *table, vr_itable_del_cb_t func, /* Upper strides are deleted. Delete the current */ ptr[i] = NULL; - vr_free(ptr[i]); + vr_free(ptr[i], VR_ITABLE_OBJECT); } } /* Destruct the head as well*/ if (cnt == 0) { - vr_free(table->data); + vr_free(table->data, VR_ITABLE_OBJECT); table->data = NULL; } @@ -304,7 +304,8 @@ vr_itable_set(vr_itable_t t, unsigned int index, void *data) } if (!table->data) { - table->data = vr_zalloc(table->stride_len[0] * sizeof(void *)); + table->data = vr_zalloc(table->stride_len[0] * sizeof(void *), + VR_ITABLE_OBJECT); if (!table->data) { return VR_ITABLE_ERR_PTR; } @@ -315,7 +316,8 @@ vr_itable_set(vr_itable_t t, unsigned int index, void *data) id = (index >> table->stride_shift[i]) & (table->stride_len[i] - 1); if (!ptr[id]) { - ptr[id] = vr_zalloc(table->stride_len[i + 1] * sizeof(void *)); + ptr[id] = vr_zalloc(table->stride_len[i + 1] * sizeof(void *), + VR_ITABLE_OBJECT); /* To fix: We might return with some empty strides */ if (!ptr[id]) { return VR_ITABLE_ERR_PTR; @@ -351,9 +353,9 @@ vr_itable_delete(vr_itable_t t, vr_itable_del_cb_t func) __vr_itable_exit(table, func, table->data, 0, 0); /* Free the table itself */ - vr_free(table->stride_len); - vr_free(table->stride_shift); - vr_free(table); + vr_free(table->stride_len, VR_ITABLE_OBJECT); + vr_free(table->stride_shift, VR_ITABLE_OBJECT); + vr_free(table, VR_ITABLE_OBJECT); return; } @@ -386,7 +388,7 @@ vr_itable_create(unsigned int index_len, unsigned int stride_cnt, ...) goto fail; } - table = vr_zalloc(sizeof(struct vr_itbl)); + table = vr_zalloc(sizeof(struct vr_itbl), VR_ITABLE_OBJECT); if (!table) { goto fail; } @@ -394,12 +396,14 @@ vr_itable_create(unsigned int index_len, unsigned int stride_cnt, ...) table->index_len = index_len; table->stride_cnt = stride_cnt; - table->stride_shift = vr_zalloc(table->stride_cnt * sizeof(unsigned int)); + table->stride_shift = vr_zalloc(table->stride_cnt * sizeof(unsigned int), + VR_ITABLE_OBJECT); if (!table->stride_shift) { goto fail; } - table->stride_len = vr_zalloc(table->stride_cnt * sizeof(unsigned int)); + table->stride_len = vr_zalloc(table->stride_cnt * sizeof(unsigned int), + VR_ITABLE_OBJECT); if (!table->stride_len) { goto fail; } @@ -435,14 +439,14 @@ vr_itable_create(unsigned int index_len, unsigned int stride_cnt, ...) if (table) { if (table->stride_shift) { - vr_free(table->stride_shift); + vr_free(table->stride_shift, VR_ITABLE_OBJECT); } if (table->stride_len) { - vr_free(table->stride_len); + vr_free(table->stride_len, VR_ITABLE_OBJECT); } - vr_free(table); + vr_free(table, VR_ITABLE_OBJECT); } return NULL; diff --git a/dp-core/vr_interface.c b/dp-core/vr_interface.c index e9e7819ff..d4f728dd8 100644 --- a/dp-core/vr_interface.c +++ b/dp-core/vr_interface.c @@ -122,7 +122,7 @@ vr_interface_service_enable(struct vr_interface *vif) */ if (!vif->vif_vrf_table) { vif->vif_vrf_table = vr_malloc(sizeof(struct vr_vrf_assign) * - VIF_VRF_TABLE_ENTRIES); + VIF_VRF_TABLE_ENTRIES, VR_INTERFACE_VRF_TABLE_OBJECT); if (!vif->vif_vrf_table) return -ENOMEM; @@ -165,7 +165,7 @@ vr_interface_service_disable(struct vr_interface *vif) * takes care of freeing the memory */ if (vif->vif_vrf_table && !vif->vif_vrf_table_users) { - vr_free(vif->vif_vrf_table); + vr_free(vif->vif_vrf_table, VR_INTERFACE_VRF_TABLE_OBJECT); vif->vif_vrf_table = NULL; } @@ -780,16 +780,26 @@ vlan_tx(struct vr_interface *vif, struct vr_packet *pkt, static int vlan_drv_del(struct vr_interface *vif) { + int ret = 0; struct vr_interface *pvif; pvif = vif->vif_parent; if (!pvif) return 0; - if (pvif->vif_driver->drv_delete_sub_interface) - pvif->vif_driver->drv_delete_sub_interface(pvif, vif); + if (pvif->vif_driver->drv_delete_sub_interface) { + ret = pvif->vif_driver->drv_delete_sub_interface(pvif, vif); + if (ret) + goto exit_del; + } - return 0; +exit_del: + if (vif->vif_src_mac) { + vr_free(vif->vif_src_mac, VR_INTERFACE_MAC_OBJECT); + vif->vif_src_mac = NULL; + } + + return ret; } static int @@ -808,7 +818,7 @@ vlan_drv_add(struct vr_interface *vif, vr_interface_req *vifr) if (vifr->vifr_src_mac_size != VR_ETHER_ALEN) return -EINVAL; - vif->vif_src_mac = vr_malloc(VR_ETHER_ALEN); + vif->vif_src_mac = vr_malloc(VR_ETHER_ALEN, VR_INTERFACE_MAC_OBJECT); if (!vif->vif_src_mac) return -ENOMEM; @@ -1152,7 +1162,7 @@ eth_drv_add_sub_interface(struct vr_interface *pvif, struct vr_interface *vif) } else { if(!pvif->vif_sub_interfaces) { pvif->vif_sub_interfaces = vr_zalloc(VLAN_ID_MAX * - sizeof(struct vr_interface *)); + sizeof(struct vr_interface *), VR_INTERFACE_OBJECT); if (!pvif->vif_sub_interfaces) return -ENOMEM; /* @@ -1290,15 +1300,15 @@ vif_free(struct vr_interface *vif) return; if (vif->vif_stats) - vr_free(vif->vif_stats); + vr_free(vif->vif_stats, VR_INTERFACE_STATS_OBJECT); if (vif->vif_vrf_table) { - vr_free(vif->vif_vrf_table); + vr_free(vif->vif_vrf_table, VR_INTERFACE_VRF_TABLE_OBJECT); vif->vif_vrf_table = NULL; } if (vif->vif_sub_interfaces) { - vr_free(vif->vif_sub_interfaces); + vr_free(vif->vif_sub_interfaces, VR_INTERFACE_OBJECT); vif->vif_sub_interfaces = NULL; } @@ -1306,7 +1316,12 @@ vif_free(struct vr_interface *vif) vif_bridge_deinit(vif); } - vr_free(vif); + if (vif->vif_src_mac) { + vr_free(vif->vif_src_mac, VR_INTERFACE_MAC_OBJECT); + vif->vif_src_mac = NULL; + } + + vr_free(vif, VR_INTERFACE_OBJECT); return; } @@ -1725,14 +1740,14 @@ vr_interface_add(vr_interface_req *req, bool need_response) goto generate_resp; } - vif = vr_zalloc(sizeof(*vif)); + vif = vr_zalloc(sizeof(*vif), VR_INTERFACE_OBJECT); if (!vif) { ret = -ENOMEM; goto generate_resp; } vif->vif_stats = vr_zalloc(vr_num_cpus * - sizeof(struct vr_interface_stats)); + sizeof(struct vr_interface_stats), VR_INTERFACE_STATS_OBJECT); if (!vif->vif_stats) { ret = -ENOMEM; goto generate_resp; @@ -1956,18 +1971,19 @@ vr_interface_req_get(void) { vr_interface_req *req; - req = vr_zalloc(sizeof(*req)); + req = vr_zalloc(sizeof(*req), VR_INTERFACE_REQ_OBJECT); if (!req) return req; - req->vifr_mac = vr_zalloc(VR_ETHER_ALEN); + req->vifr_mac = vr_zalloc(VR_ETHER_ALEN, VR_INTERFACE_REQ_MAC_OBJECT); if (req->vifr_mac) req->vifr_mac_size = VR_ETHER_ALEN; - req->vifr_src_mac = vr_zalloc(VR_ETHER_ALEN); + req->vifr_src_mac = vr_zalloc(VR_ETHER_ALEN, VR_INTERFACE_REQ_MAC_OBJECT); if (req->vifr_src_mac) req->vifr_src_mac_size = 0; - req->vifr_name = vr_zalloc(VR_INTERFACE_NAME_LEN); + req->vifr_name = vr_zalloc(VR_INTERFACE_NAME_LEN, + VR_INTERFACE_REQ_NAME_OBJECT); return req; } @@ -1980,19 +1996,19 @@ vr_interface_req_destroy(vr_interface_req *req) return; if (req->vifr_mac) { - vr_free(req->vifr_mac); + vr_free(req->vifr_mac, VR_INTERFACE_REQ_MAC_OBJECT); req->vifr_mac_size = 0; } if (req->vifr_src_mac) { - vr_free(req->vifr_src_mac); + vr_free(req->vifr_src_mac, VR_INTERFACE_REQ_MAC_OBJECT); req->vifr_src_mac_size = 0; } if (req->vifr_name) - vr_free(req->vifr_name); + vr_free(req->vifr_name, VR_INTERFACE_REQ_NAME_OBJECT); - vr_free(req); + vr_free(req, VR_INTERFACE_REQ_OBJECT); return; } @@ -2229,7 +2245,7 @@ vif_vrf_table_set(struct vr_interface *vif, unsigned int vlan, */ if (!(vif->vif_flags & VIF_FLAG_SERVICE_IF) && !vif->vif_vrf_table_users) { - vr_free(vif->vif_vrf_table); + vr_free(vif->vif_vrf_table, VR_INTERFACE_VRF_TABLE_OBJECT); vif->vif_vrf_table = NULL; } @@ -2317,7 +2333,7 @@ vr_interface_exit(struct vrouter *router, bool soft_reset) } if (!soft_reset && router->vr_interfaces) { - vr_free(router->vr_interfaces); + vr_free(router->vr_interfaces, VR_INTERFACE_TABLE_OBJECT); router->vr_interfaces = NULL; router->vr_max_interfaces = 0; } @@ -2335,7 +2351,8 @@ vr_interface_init(struct vrouter *router) router->vr_max_interfaces = VR_MAX_INTERFACES; table_memory = router->vr_max_interfaces * sizeof(struct vr_interface *); - router->vr_interfaces = vr_zalloc(table_memory); + router->vr_interfaces = vr_zalloc(table_memory, + VR_INTERFACE_TABLE_OBJECT); if (!router->vr_interfaces && (ret = -ENOMEM)) return vr_module_error(ret, __FUNCTION__, __LINE__, table_memory); @@ -2355,7 +2372,7 @@ vr_interface_init(struct vrouter *router) cleanup: if (router->vr_interfaces) { - vr_free(router->vr_interfaces); + vr_free(router->vr_interfaces, VR_INTERFACE_TABLE_OBJECT); router->vr_interfaces = NULL; router->vr_max_interfaces = 0; } diff --git a/dp-core/vr_ip_mtrie.c b/dp-core/vr_ip_mtrie.c index 0fe33f783..6936bf5db 100644 --- a/dp-core/vr_ip_mtrie.c +++ b/dp-core/vr_ip_mtrie.c @@ -189,7 +189,8 @@ mtrie_alloc_bucket(struct mtrie_bkt_info *ip_bkt_info, unsigned char level, stru bkt_size = ip_bkt_info[level].bi_size; bkt = vr_zalloc(sizeof(struct ip_bucket) - + sizeof(struct ip_bucket_entry) * bkt_size); + + sizeof(struct ip_bucket_entry) * bkt_size, + VR_MTRIE_BUCKET_OBJECT); if (!bkt) return NULL; @@ -264,7 +265,7 @@ mtrie_free_entry(struct ip_bucket_entry *entry, unsigned int level) } entry->entry_bkt_p = NULL; - vr_free(bkt); + vr_free(bkt, VR_MTRIE_BUCKET_OBJECT); return; } @@ -414,7 +415,7 @@ ip_bucket_sched_for_free(struct ip_bucket *bkt, int level) vrouter_put_nexthop(tmp_ent->entry_nh_p); } } - vr_free(bkt); + vr_free(bkt, VR_MTRIE_BUCKET_OBJECT); } static void @@ -530,7 +531,7 @@ mtrie_dumper_make_response(struct vr_message_dumper *dumper, vr_route_req *resp, resp->rtr_nh_id = ent->entry_nh_p->nh_id; resp->rtr_index = ent->entry_bridge_index; if (resp->rtr_index != VR_BE_INVALID_INDEX) { - resp->rtr_mac = vr_zalloc(VR_ETHER_ALEN); + resp->rtr_mac = vr_zalloc(VR_ETHER_ALEN, VR_ROUTE_REQ_MAC_OBJECT); resp->rtr_mac_size = VR_ETHER_ALEN; lreq.rtr_req.rtr_mac = resp->rtr_mac; lreq.rtr_req.rtr_index = resp->rtr_index; @@ -608,7 +609,7 @@ mtrie_dump_entry(struct vr_message_dumper *dumper, struct ip_bucket_entry *ent, ret = mtrie_dumper_route_encode(dumper, &dump_resp); if (dump_resp.rtr_mac_size) { - vr_free(dump_resp.rtr_mac); + vr_free(dump_resp.rtr_mac, VR_ROUTE_REQ_MAC_OBJECT); dump_resp.rtr_mac_size = 0; dump_resp.rtr_mac = NULL; } @@ -980,7 +981,7 @@ mtrie_alloc_vrf(unsigned int vrf_id, unsigned int family) if (family == AF_INET6) index = 1; - mtrie = vr_zalloc(sizeof(struct ip_mtrie)); + mtrie = vr_zalloc(sizeof(struct ip_mtrie), VR_MTRIE_OBJECT); if (mtrie) { mtrie->root.entry_nh_p = vrouter_get_nexthop(0, NH_DISCARD_ID); mtrie->root.entry_bridge_index = VR_BE_INVALID_INDEX; @@ -1007,7 +1008,7 @@ mtrie_free_vrf(struct vr_rtable *rtable, unsigned int vrf_id) mtrie_free_entry(&mtrie->root, 0); vrf_tables[vrf_id] = NULL; - vr_free(mtrie); + vr_free(mtrie, VR_MTRIE_OBJECT); } return; @@ -1027,18 +1028,18 @@ mtrie_stats_cleanup(struct vr_rtable *rtable, bool soft_reset) if (soft_reset) { memset(mtrie_vrf_stats[i], 0, stats_memory_size); } else { - vr_free(mtrie_vrf_stats[i]); + vr_free(mtrie_vrf_stats[i], VR_MTRIE_STATS_OBJECT); mtrie_vrf_stats[i] = NULL; } } } if (!soft_reset) { - vr_free(mtrie_vrf_stats); + vr_free(mtrie_vrf_stats, VR_MTRIE_STATS_OBJECT); rtable->vrf_stats = mtrie_vrf_stats = NULL; if (invalid_vrf_stats) { - vr_free(invalid_vrf_stats); + vr_free(invalid_vrf_stats, VR_MTRIE_STATS_OBJECT); invalid_vrf_stats = NULL; } } else { @@ -1063,7 +1064,7 @@ mtrie_algo_deinit(struct vr_rtable *rtable, struct rtable_fspec *fs, if (!soft_reset) { vn_rtable[0] = vn_rtable[1] = NULL; - vr_free(rtable->algo_data); + vr_free(rtable->algo_data, VR_MTRIE_TABLE_OBJECT); rtable->algo_data = NULL; } @@ -1081,13 +1082,14 @@ mtrie_stats_init(struct vr_rtable *rtable) if (!mtrie_vrf_stats) { stats_memory = sizeof(void *) * rtable->algo_max_vrfs; - mtrie_vrf_stats = vr_zalloc(stats_memory); + mtrie_vrf_stats = vr_zalloc(stats_memory, VR_MTRIE_STATS_OBJECT); if (!mtrie_vrf_stats) return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, stats_memory); for (i = 0; i < rtable->algo_max_vrfs; i++) { stats_memory = sizeof(struct vr_vrf_stats) * vr_num_cpus; - mtrie_vrf_stats[i] = vr_zalloc(stats_memory); + mtrie_vrf_stats[i] = vr_zalloc(stats_memory, + VR_MTRIE_STATS_OBJECT); if (!mtrie_vrf_stats[i] && (ret = -ENOMEM)) { vr_module_error(ret, __FUNCTION__, __LINE__, i); goto cleanup; @@ -1099,7 +1101,7 @@ mtrie_stats_init(struct vr_rtable *rtable) if (!invalid_vrf_stats) { invalid_vrf_stats = vr_zalloc(sizeof(struct vr_vrf_stats) * - vr_num_cpus); + vr_num_cpus, VR_MTRIE_STATS_OBJECT); if (!invalid_vrf_stats && (ret = -ENOMEM)) { vr_module_error(ret, __FUNCTION__, __LINE__, -1); goto cleanup; @@ -1115,18 +1117,18 @@ mtrie_stats_init(struct vr_rtable *rtable) for (--i; i >= 0; i--) { if (mtrie_vrf_stats[i]) { - vr_free(mtrie_vrf_stats[i]); + vr_free(mtrie_vrf_stats[i], VR_MTRIE_STATS_OBJECT); mtrie_vrf_stats[i] = NULL; } } if (mtrie_vrf_stats) { - vr_free(mtrie_vrf_stats); + vr_free(mtrie_vrf_stats, VR_MTRIE_STATS_OBJECT); mtrie_vrf_stats = NULL; } if (invalid_vrf_stats) { - vr_free(invalid_vrf_stats); + vr_free(invalid_vrf_stats, VR_MTRIE_STATS_OBJECT); invalid_vrf_stats = NULL; } @@ -1144,7 +1146,7 @@ mtrie_algo_init(struct vr_rtable *rtable, struct rtable_fspec *fs) if (!rtable->algo_data) { table_memory = 2 * sizeof(void *) * fs->rtb_max_vrfs; - rtable->algo_data = vr_zalloc(table_memory); + rtable->algo_data = vr_zalloc(table_memory, VR_MTRIE_TABLE_OBJECT); if (!rtable->algo_data) return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, table_memory); } @@ -1180,7 +1182,7 @@ mtrie_algo_init(struct vr_rtable *rtable, struct rtable_fspec *fs) init_fail: if (rtable->algo_data) { - vr_free(rtable->algo_data); + vr_free(rtable->algo_data, VR_MTRIE_TABLE_OBJECT); rtable->algo_data = NULL; } diff --git a/dp-core/vr_message.c b/dp-core/vr_message.c index 3394e8be1..b8a9b731d 100644 --- a/dp-core/vr_message.c +++ b/dp-core/vr_message.c @@ -11,14 +11,14 @@ static char * vr_message_default_malloc(unsigned int size) { - return vr_malloc(size); + return vr_malloc(size, VR_MESSAGE_OBJECT); } static void vr_message_default_free(char *buf) { if (buf) - vr_free(buf); + vr_free(buf, VR_MESSAGE_OBJECT); return; } @@ -76,7 +76,7 @@ vr_message_queue_response(char *buf, int len) { struct vr_message *response; - response = vr_zalloc(sizeof(*response)); + response = vr_zalloc(sizeof(*response), VR_MESSAGE_RESPONSE_OBJECT); if (!response) return -ENOMEM; @@ -112,7 +112,7 @@ vr_message_free(struct vr_message *message) if (message) { if (message->vr_message_buf) vr_mtrans_free(message->vr_message_buf); - vr_free(message); + vr_free(message, VR_MESSAGE_RESPONSE_OBJECT); } return; @@ -271,7 +271,7 @@ vr_message_dump_exit(void *context, int ret) vr_message_queue_response(dumper->dump_buffer, dumper->dump_offset); - vr_free(dumper); + vr_free(dumper, VR_MESSAGE_DUMP_OBJECT); } return; @@ -290,13 +290,13 @@ vr_message_dump_init(void *req) if (!proto || !trans) return NULL; - dumper = vr_zalloc(sizeof(*dumper)); + dumper = vr_zalloc(sizeof(*dumper), VR_MESSAGE_DUMP_OBJECT); if (!dumper) return NULL; buf = trans->mtrans_alloc(VR_MESSAGE_PAGE_SIZE); if (!buf) { - vr_free(dumper); + vr_free(dumper, VR_MESSAGE_DUMP_OBJECT); return NULL; } diff --git a/dp-core/vr_mirror.c b/dp-core/vr_mirror.c index 1f9e92fe2..7a16cc165 100644 --- a/dp-core/vr_mirror.c +++ b/dp-core/vr_mirror.c @@ -55,7 +55,7 @@ vrouter_put_mirror(struct vrouter *router, unsigned int index) vr_delay_op(); vrouter_put_nexthop(mirror->mir_nh); - vr_free(mirror); + vr_free(mirror, VR_MIRROR_OBJECT); } return 0; @@ -146,7 +146,7 @@ vr_mirror_add(vr_mirror_req *req) if (mirror) { vr_mirror_change(mirror, req, nh); } else { - mirror = vr_zalloc(sizeof(*mirror)); + mirror = vr_zalloc(sizeof(*mirror), VR_MIRROR_OBJECT); mirror->mir_users++; mirror->mir_nh = nh; mirror->mir_rid = req->mirr_rid; @@ -275,9 +275,9 @@ vr_mirror_meta_destroy(struct vr_mirror_meta_entry *me) return; if (me->mirror_md) - vr_free(me->mirror_md); + vr_free(me->mirror_md, VR_MIRROR_META_OBJECT); - vr_free(me); + vr_free(me, VR_MIRROR_META_OBJECT); return; } @@ -327,13 +327,13 @@ vr_mirror_meta_entry_set(struct vrouter *router, unsigned int index, char *buf; struct vr_mirror_meta_entry *me, *me_old; - me = vr_malloc(sizeof(*me)); + me = vr_malloc(sizeof(*me), VR_MIRROR_META_OBJECT); if (!me) return -ENOMEM; - buf = vr_malloc(meta_data_len); + buf = vr_malloc(meta_data_len, VR_MIRROR_META_OBJECT); if (!buf) { - vr_free(me); + vr_free(me, VR_MIRROR_META_OBJECT); return -ENOMEM; } @@ -492,7 +492,7 @@ vr_mirror_exit(struct vrouter *router, bool soft_reset) } if (!soft_reset) { - vr_free(router->vr_mirrors); + vr_free(router->vr_mirrors, VR_MIRROR_TABLE_OBJECT); router->vr_mirrors = NULL; router->vr_max_mirror_indices = 0; } @@ -509,7 +509,7 @@ vr_mirror_init(struct vrouter *router) if (!router->vr_mirrors) { router->vr_max_mirror_indices = VR_MAX_MIRROR_INDICES; size = sizeof(struct vr_mirror_entry *) * router->vr_max_mirror_indices; - router->vr_mirrors = vr_zalloc(size); + router->vr_mirrors = vr_zalloc(size, VR_MIRROR_TABLE_OBJECT); if (!router->vr_mirrors) return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, size); } @@ -526,7 +526,7 @@ vr_mirror_init(struct vrouter *router) cleanup: if (router->vr_mirrors) { - vr_free(router->vr_mirrors); + vr_free(router->vr_mirrors, VR_MIRROR_TABLE_OBJECT); router->vr_mirrors = NULL; } diff --git a/dp-core/vr_nexthop.c b/dp-core/vr_nexthop.c index 46a1b593f..553644ddc 100644 --- a/dp-core/vr_nexthop.c +++ b/dp-core/vr_nexthop.c @@ -94,12 +94,12 @@ vrouter_put_nexthop(struct vr_nexthop *nh) vrouter_put_nexthop(nh->nh_component_nh[i].cnh); } - vr_free(nh->nh_component_nh); + vr_free(nh->nh_component_nh, VR_NEXTHOP_COMPONENT_OBJECT); } if (nh->nh_dev) { vrouter_put_interface(nh->nh_dev); } - vr_free(nh); + vr_free(nh, VR_NEXTHOP_OBJECT); } return; @@ -1943,7 +1943,7 @@ nh_composite_add(struct vr_nexthop *nh, vr_nexthop_req *req) if (nh->nh_component_nh[i].cnh) vrouter_put_nexthop(nh->nh_component_nh[i].cnh); } - vr_free(nh->nh_component_nh); + vr_free(nh->nh_component_nh, VR_NEXTHOP_COMPONENT_OBJECT); nh->nh_component_nh = NULL; nh->nh_component_cnt = 0; } @@ -1956,7 +1956,7 @@ nh_composite_add(struct vr_nexthop *nh, vr_nexthop_req *req) return 0; nh->nh_component_nh = vr_zalloc(req->nhr_nh_list_size * - sizeof(struct vr_component_nh)); + sizeof(struct vr_component_nh), VR_NEXTHOP_COMPONENT_OBJECT); if (!nh->nh_component_nh) { return -ENOMEM; } @@ -1998,7 +1998,7 @@ nh_composite_add(struct vr_nexthop *nh, vr_nexthop_req *req) vrouter_put_nexthop(tmp_nh); } - vr_free(nh->nh_component_nh); + vr_free(nh->nh_component_nh, VR_NEXTHOP_COMPONENT_OBJECT); nh->nh_component_nh = NULL; nh->nh_component_cnt = 0; } @@ -2176,7 +2176,7 @@ vr_nexthop_add(vr_nexthop_req *req) goto generate_resp; len = ret; - nh = vr_zalloc(len); + nh = vr_zalloc(len, VR_NEXTHOP_OBJECT); if (!nh) { ret = -ENOMEM; goto generate_resp; @@ -2330,12 +2330,16 @@ vr_nexthop_make_req(vr_nexthop_req *req, struct vr_nexthop *nh) case NH_COMPOSITE: req->nhr_nh_list_size = nh->nh_component_cnt; if (nh->nh_component_cnt) { - req->nhr_nh_list = vr_zalloc(req->nhr_nh_list_size * sizeof(unsigned int)); + req->nhr_nh_list = + vr_zalloc(req->nhr_nh_list_size * sizeof(unsigned int), + VR_NEXTHOP_REQ_LIST_OBJECT); if (!req->nhr_nh_list) return -ENOMEM; req->nhr_label_list_size = nh->nh_component_cnt; - req->nhr_label_list = vr_zalloc(req->nhr_nh_list_size * sizeof(unsigned int)); + req->nhr_label_list = + vr_zalloc(req->nhr_nh_list_size * sizeof(unsigned int), + VR_NEXTHOP_REQ_LIST_OBJECT); /* don't bother about freeing. we will free it in req_destroy */ if (!req->nhr_label_list) return -ENOMEM; @@ -2394,7 +2398,8 @@ vr_nexthop_make_req(vr_nexthop_req *req, struct vr_nexthop *nh) } if (req->nhr_encap_size) { - req->nhr_encap = vr_zalloc(req->nhr_encap_size); + req->nhr_encap = vr_zalloc(req->nhr_encap_size, + VR_NEXTHOP_REQ_ENCAP_OBJECT); if (req->nhr_encap) { memcpy(req->nhr_encap, encap, req->nhr_encap_size); @@ -2410,7 +2415,7 @@ vr_nexthop_make_req(vr_nexthop_req *req, struct vr_nexthop *nh) static vr_nexthop_req * vr_nexthop_req_get(void) { - return vr_zalloc(sizeof(vr_nexthop_req)); + return vr_zalloc(sizeof(vr_nexthop_req), VR_NEXTHOP_REQ_OBJECT); } static void @@ -2420,24 +2425,24 @@ vr_nexthop_req_destroy(vr_nexthop_req *req) return; if (req->nhr_encap_size && req->nhr_encap) { - vr_free(req->nhr_encap); + vr_free(req->nhr_encap, VR_NEXTHOP_REQ_ENCAP_OBJECT); req->nhr_encap_size = 0; req->nhr_encap = NULL; } if (req->nhr_nh_list_size && req->nhr_nh_list) { - vr_free(req->nhr_nh_list); + vr_free(req->nhr_nh_list, VR_NEXTHOP_REQ_LIST_OBJECT); req->nhr_nh_list_size = 0; req->nhr_nh_list = NULL; } if (req->nhr_label_list_size && req->nhr_label_list) { - vr_free(req->nhr_label_list); + vr_free(req->nhr_label_list, VR_NEXTHOP_REQ_LIST_OBJECT); req->nhr_label_list = NULL; req->nhr_label_list_size = 0; } - vr_free(req); + vr_free(req, VR_NEXTHOP_REQ_OBJECT); return; } @@ -2584,7 +2589,7 @@ nh_table_exit(struct vrouter *router, bool soft_reset) static int nh_allocate_discard(void) { - ip4_default_nh = vr_zalloc(sizeof(struct vr_nexthop)); + ip4_default_nh = vr_zalloc(sizeof(struct vr_nexthop), VR_NEXTHOP_OBJECT); if (!ip4_default_nh) return -ENOMEM; diff --git a/dp-core/vr_route.c b/dp-core/vr_route.c index 34dc734a7..a0cdbd17c 100644 --- a/dp-core/vr_route.c +++ b/dp-core/vr_route.c @@ -428,7 +428,7 @@ inet_rtb_family_deinit(struct rtable_fspec *fs, struct vrouter *router, if (router->vr_inet_rtable) { fs->algo_deinit(router->vr_inet_rtable, fs, soft_reset); if (!soft_reset) { - vr_free(router->vr_inet_rtable); + vr_free(router->vr_inet_rtable, VR_ROUTE_TABLE_OBJECT); router->vr_inet_rtable = NULL; } } @@ -445,7 +445,8 @@ inet_rtb_family_init(struct rtable_fspec *fs, struct vrouter *router) return 1; if (!router->vr_inet_rtable) { - router->vr_inet_rtable = vr_zalloc(sizeof(struct vr_rtable)); + router->vr_inet_rtable = vr_zalloc(sizeof(struct vr_rtable), + VR_ROUTE_TABLE_OBJECT); if (!router->vr_inet_rtable) return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, 0); } @@ -504,7 +505,7 @@ bridge_rtb_family_init(struct rtable_fspec *fs, struct vrouter *router) return 0; if (fs->algo_init) { - table = vr_zalloc(sizeof(struct vr_rtable)); + table = vr_zalloc(sizeof(struct vr_rtable), VR_ROUTE_TABLE_OBJECT); if (!table) return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, 0); @@ -528,7 +529,7 @@ bridge_rtb_family_deinit(struct rtable_fspec *fs, struct vrouter *router, fs->algo_deinit(router->vr_bridge_rtable, fs, soft_reset); if (!soft_reset) { - vr_free(router->vr_bridge_rtable); + vr_free(router->vr_bridge_rtable, VR_ROUTE_TABLE_OBJECT); router->vr_bridge_rtable = NULL; } } diff --git a/dp-core/vr_sandesh.c b/dp-core/vr_sandesh.c index af72f5846..6ec20cd52 100644 --- a/dp-core/vr_sandesh.c +++ b/dp-core/vr_sandesh.c @@ -67,6 +67,10 @@ struct sandesh_object_md sandesh_md[] = { (VR_FLOW_MAX_CPUS * sizeof(unsigned int))), .obj_type_string = "vr_flow_req", }, + [VR_MEM_STATS_OBJECT_ID] = { + .obj_len = 4 * sizeof(vr_mem_stats_req), + .obj_type_string = "vr_mem_stats_req", + }, }; static unsigned int diff --git a/dp-core/vr_stats.c b/dp-core/vr_stats.c index 14018a791..e665654c2 100644 --- a/dp-core/vr_stats.c +++ b/dp-core/vr_stats.c @@ -81,11 +81,11 @@ vr_drop_stats_get(unsigned int core) if (!router && (ret = -ENOENT)) goto exit_get; - stats = vr_zalloc(sizeof(*stats)); + stats = vr_zalloc(sizeof(*stats), VR_DROP_STATS_REQ_OBJECT); if (!stats && (ret = -ENOMEM)) goto exit_get; - response = vr_zalloc(sizeof(*response)); + response = vr_zalloc(sizeof(*response), VR_DROP_STATS_REQ_OBJECT); if (!response && (ret = -ENOMEM)) goto exit_get; @@ -211,10 +211,10 @@ vr_drop_stats_get(unsigned int core) exit_get: vr_message_response(VR_DROP_STATS_OBJECT_ID, ret ? NULL : response, ret); if (stats != NULL) - vr_free(stats); + vr_free(stats, VR_DROP_STATS_REQ_OBJECT); if (response != NULL) - vr_free(response); + vr_free(response, VR_DROP_STATS_REQ_OBJECT); return; } @@ -243,6 +243,253 @@ vr_drop_stats_req_process(void *s_req) return; } +static void +vr_mem_stats_get(void) +{ + int ret = 0; + unsigned int cpu, i; + int64_t alloced = 0, freed = 0; + + struct vrouter *router = vrouter_get(0); + struct vr_malloc_stats *stats_block; + vr_mem_stats_req *response = NULL; + + if (!router && (ret = -ENOENT)) + goto exit_get; + + response = vr_zalloc(sizeof(*response), VR_MEM_STATS_REQ_OBJECT); + if (!response && (ret = -ENOMEM)) + goto exit_get; + + + for (cpu = 0; cpu < vr_num_cpus; cpu++) { + stats_block = (struct vr_malloc_stats *)router->vr_malloc_stats[cpu]; + response->vms_assembler_table_object += (stats_block[VR_ASSEMBLER_TABLE_OBJECT].ms_alloc - + stats_block[VR_ASSEMBLER_TABLE_OBJECT].ms_free); + response->vms_bridge_mac_object += (stats_block[VR_BRIDGE_MAC_OBJECT].ms_alloc - + stats_block[VR_BRIDGE_MAC_OBJECT].ms_free); + response->vms_btable_object += (stats_block[VR_BTABLE_OBJECT].ms_alloc - + stats_block[VR_BTABLE_OBJECT].ms_free); + response->vms_build_info_object += (stats_block[VR_BUILD_INFO_OBJECT].ms_alloc - + stats_block[VR_BUILD_INFO_OBJECT].ms_free); + response->vms_defer_object += (stats_block[VR_DEFER_OBJECT].ms_alloc - + stats_block[VR_DEFER_OBJECT].ms_free); + response->vms_drop_stats_object += (stats_block[VR_DROP_STATS_OBJECT].ms_alloc - + stats_block[VR_DROP_STATS_OBJECT].ms_free); + response->vms_drop_stats_req_object += (stats_block[VR_DROP_STATS_REQ_OBJECT].ms_alloc - + stats_block[VR_DROP_STATS_REQ_OBJECT].ms_free); + response->vms_flow_queue_object += (stats_block[VR_FLOW_QUEUE_OBJECT].ms_alloc - + stats_block[VR_FLOW_QUEUE_OBJECT].ms_free); + response->vms_flow_req_object += (stats_block[VR_FLOW_REQ_OBJECT].ms_alloc - + stats_block[VR_FLOW_REQ_OBJECT].ms_free); + response->vms_flow_req_path_object += (stats_block[VR_FLOW_REQ_PATH_OBJECT].ms_alloc - + stats_block[VR_FLOW_REQ_PATH_OBJECT].ms_free); + response->vms_flow_hold_stat_object += (stats_block[VR_FLOW_HOLD_STAT_OBJECT].ms_alloc - + stats_block[VR_FLOW_HOLD_STAT_OBJECT].ms_free); + response->vms_flow_link_local_object += (stats_block[VR_FLOW_LINK_LOCAL_OBJECT].ms_alloc - + stats_block[VR_FLOW_LINK_LOCAL_OBJECT].ms_free); + response->vms_flow_metadata_object += (stats_block[VR_FLOW_METADATA_OBJECT].ms_alloc - + stats_block[VR_FLOW_METADATA_OBJECT].ms_free); + response->vms_flow_table_info_object += (stats_block[VR_FLOW_TABLE_INFO_OBJECT].ms_alloc - + stats_block[VR_FLOW_TABLE_INFO_OBJECT].ms_free); + response->vms_fragment_object += (stats_block[VR_FRAGMENT_OBJECT].ms_alloc - + stats_block[VR_FRAGMENT_OBJECT].ms_free); + response->vms_fragment_queue_object += (stats_block[VR_FRAGMENT_QUEUE_OBJECT].ms_alloc - + stats_block[VR_FRAGMENT_QUEUE_OBJECT].ms_free); + response->vms_fragment_queue_element_object += (stats_block[VR_FRAGMENT_QUEUE_ELEMENT_OBJECT].ms_alloc - + stats_block[VR_FRAGMENT_QUEUE_ELEMENT_OBJECT].ms_free); + response->vms_fragment_scanner_object += (stats_block[VR_FRAGMENT_SCANNER_OBJECT].ms_alloc - + stats_block[VR_FRAGMENT_SCANNER_OBJECT].ms_free); + response->vms_hpacket_pool_object += (stats_block[VR_HPACKET_POOL_OBJECT].ms_alloc - + stats_block[VR_HPACKET_POOL_OBJECT].ms_free); + response->vms_htable_object += (stats_block[VR_HTABLE_OBJECT].ms_alloc - + stats_block[VR_HTABLE_OBJECT].ms_free); + response->vms_interface_object += (stats_block[VR_INTERFACE_OBJECT].ms_alloc - + stats_block[VR_INTERFACE_OBJECT].ms_free); + response->vms_interface_mac_object += (stats_block[VR_INTERFACE_MAC_OBJECT].ms_alloc - + stats_block[VR_INTERFACE_MAC_OBJECT].ms_free); + response->vms_interface_req_object += (stats_block[VR_INTERFACE_REQ_OBJECT].ms_alloc - + stats_block[VR_INTERFACE_REQ_OBJECT].ms_free); + response->vms_interface_req_mac_object += (stats_block[VR_INTERFACE_REQ_MAC_OBJECT].ms_alloc - + stats_block[VR_INTERFACE_REQ_MAC_OBJECT].ms_free); + response->vms_interface_req_name_object += (stats_block[VR_INTERFACE_REQ_NAME_OBJECT].ms_alloc - + stats_block[VR_INTERFACE_REQ_NAME_OBJECT].ms_free); + response->vms_interface_stats_object += (stats_block[VR_INTERFACE_STATS_OBJECT].ms_alloc - + stats_block[VR_INTERFACE_STATS_OBJECT].ms_free); + response->vms_interface_table_object += (stats_block[VR_INTERFACE_TABLE_OBJECT].ms_alloc - + stats_block[VR_INTERFACE_TABLE_OBJECT].ms_free); + response->vms_interface_vrf_table_object += (stats_block[VR_INTERFACE_VRF_TABLE_OBJECT].ms_alloc - + stats_block[VR_INTERFACE_VRF_TABLE_OBJECT].ms_free); + response->vms_itable_object += (stats_block[VR_ITABLE_OBJECT].ms_alloc - + stats_block[VR_ITABLE_OBJECT].ms_free); + response->vms_malloc_object += (stats_block[VR_MALLOC_OBJECT].ms_alloc - + stats_block[VR_MALLOC_OBJECT].ms_free); + response->vms_message_object += (stats_block[VR_MESSAGE_OBJECT].ms_alloc - + stats_block[VR_MESSAGE_OBJECT].ms_free); + response->vms_message_response_object += (stats_block[VR_MESSAGE_RESPONSE_OBJECT].ms_alloc - + stats_block[VR_MESSAGE_RESPONSE_OBJECT].ms_free); + response->vms_message_dump_object += (stats_block[VR_MESSAGE_DUMP_OBJECT].ms_alloc - + stats_block[VR_MESSAGE_DUMP_OBJECT].ms_free); + response->vms_mem_stats_req_object += (stats_block[VR_MEM_STATS_REQ_OBJECT].ms_alloc - + stats_block[VR_MEM_STATS_REQ_OBJECT].ms_free); + response->vms_mirror_object += (stats_block[VR_MIRROR_OBJECT].ms_alloc - + stats_block[VR_MIRROR_OBJECT].ms_free); + response->vms_mirror_table_object += (stats_block[VR_MIRROR_TABLE_OBJECT].ms_alloc - + stats_block[VR_MIRROR_TABLE_OBJECT].ms_free); + response->vms_mirror_meta_object += (stats_block[VR_MIRROR_META_OBJECT].ms_alloc - + stats_block[VR_MIRROR_META_OBJECT].ms_free); + response->vms_mtrie_object += (stats_block[VR_MTRIE_OBJECT].ms_alloc - + stats_block[VR_MTRIE_OBJECT].ms_free); + response->vms_mtrie_bucket_object += (stats_block[VR_MTRIE_BUCKET_OBJECT].ms_alloc - + stats_block[VR_MTRIE_BUCKET_OBJECT].ms_free); + response->vms_mtrie_stats_object += (stats_block[VR_MTRIE_STATS_OBJECT].ms_alloc - + stats_block[VR_MTRIE_STATS_OBJECT].ms_free); + response->vms_mtrie_table_object += (stats_block[VR_MTRIE_TABLE_OBJECT].ms_alloc - + stats_block[VR_MTRIE_TABLE_OBJECT].ms_free); + response->vms_nexthop_object += (stats_block[VR_NEXTHOP_OBJECT].ms_alloc - + stats_block[VR_NEXTHOP_OBJECT].ms_free); + response->vms_nexthop_component_object += (stats_block[VR_NEXTHOP_COMPONENT_OBJECT].ms_alloc - + stats_block[VR_NEXTHOP_COMPONENT_OBJECT].ms_free); + response->vms_nexthop_req_list_object += (stats_block[VR_NEXTHOP_REQ_LIST_OBJECT].ms_alloc - + stats_block[VR_NEXTHOP_REQ_LIST_OBJECT].ms_free); + response->vms_nexthop_req_encap_object += (stats_block[VR_NEXTHOP_REQ_ENCAP_OBJECT].ms_alloc - + stats_block[VR_NEXTHOP_REQ_ENCAP_OBJECT].ms_free); + response->vms_nexthop_req_object += (stats_block[VR_NEXTHOP_REQ_OBJECT].ms_alloc - + stats_block[VR_NEXTHOP_REQ_OBJECT].ms_free); + response->vms_route_table_object += (stats_block[VR_ROUTE_TABLE_OBJECT].ms_alloc - + stats_block[VR_ROUTE_TABLE_OBJECT].ms_free); + response->vms_route_req_mac_object += (stats_block[VR_ROUTE_REQ_MAC_OBJECT].ms_alloc - + stats_block[VR_ROUTE_REQ_MAC_OBJECT].ms_free); + response->vms_timer_object += (stats_block[VR_TIMER_OBJECT].ms_alloc - + stats_block[VR_TIMER_OBJECT].ms_free); + response->vms_usock_object += (stats_block[VR_USOCK_OBJECT].ms_alloc - + stats_block[VR_USOCK_OBJECT].ms_free); + response->vms_usock_poll_object += (stats_block[VR_USOCK_POLL_OBJECT].ms_alloc - + stats_block[VR_USOCK_POLL_OBJECT].ms_free); + response->vms_usock_buf_object += (stats_block[VR_USOCK_BUF_OBJECT].ms_alloc - + stats_block[VR_USOCK_BUF_OBJECT].ms_free); + response->vms_usock_iovec_object += (stats_block[VR_USOCK_IOVEC_OBJECT].ms_alloc - + stats_block[VR_USOCK_IOVEC_OBJECT].ms_free); + response->vms_vrouter_req_object += (stats_block[VR_VROUTER_REQ_OBJECT].ms_alloc - + stats_block[VR_VROUTER_REQ_OBJECT].ms_free); + for (i = 0; i < VR_VROUTER_MAX_OBJECT; i++) { + alloced += stats_block[i].ms_alloc; + freed += stats_block[i].ms_free; + } + } + + + response->vms_alloced = alloced; + response->vms_freed = freed; + +exit_get: + vr_message_response(VR_MEM_STATS_OBJECT_ID, ret ? NULL : response, ret); + if (response != NULL) + vr_free(response, VR_MEM_STATS_REQ_OBJECT); + + return; +} + +void +vr_mem_stats_req_process(void *s_req) +{ + int ret; + vr_mem_stats_req *req = (vr_mem_stats_req *)s_req; + + if ((req->h_op != SANDESH_OP_GET) && (ret = -EOPNOTSUPP)) + vr_send_response(ret); + + vr_mem_stats_get(); + return; +} + +void +vr_free_stats(unsigned int object) +{ + struct vrouter *router = vrouter_get(0); + unsigned int cpu; + + cpu = vr_get_cpu(); + if (router->vr_malloc_stats && router->vr_malloc_stats[cpu]) + router->vr_malloc_stats[cpu][object].ms_free++; + + return; +} + +void +vr_malloc_stats(unsigned int size, unsigned int object) +{ + struct vrouter *router = vrouter_get(0); + unsigned int cpu; + + cpu = vr_get_cpu(); + if (router->vr_malloc_stats) { + if (router->vr_malloc_stats[cpu]) { + router->vr_malloc_stats[cpu][object].ms_size += size; + router->vr_malloc_stats[cpu][object].ms_alloc++; + } + } + + return; +} + +static void +vr_malloc_stats_exit(struct vrouter *router) +{ + unsigned int i; + + if (!router->vr_malloc_stats) + return; + + for (i = 0; i < vr_num_cpus; i++) { + if (router->vr_malloc_stats[i]) { + vr_free(router->vr_malloc_stats[i], VR_MALLOC_OBJECT); + router->vr_malloc_stats[i] = NULL; + } + } + + vr_free(router->vr_malloc_stats, VR_MALLOC_OBJECT); + + return; +} + +static int +vr_malloc_stats_init(struct vrouter *router) +{ + unsigned int i, size, cpu, total_size = 0; + + if (router->vr_malloc_stats) + return 0; + + size = vr_num_cpus * sizeof(void *); + router->vr_malloc_stats = vr_zalloc(size, VR_MALLOC_OBJECT); + if (!router->vr_malloc_stats) + return -ENOMEM; + total_size += size; + + size = VR_VROUTER_MAX_OBJECT * sizeof(struct vr_malloc_stats); + /* + * align the allocation to cache line size so that per-cpu variable + * do not result in cache thrashing + */ + if (size % 64) { + size = size + (64 - (size % 64)); + } + + for (i = 0; i < vr_num_cpus; i++) { + router->vr_malloc_stats[i] = vr_zalloc(size, VR_MALLOC_OBJECT); + if (!router->vr_malloc_stats) + return -ENOMEM; + total_size += size; + } + + cpu = vr_get_cpu(); + router->vr_malloc_stats[cpu][VR_MALLOC_OBJECT].ms_alloc = vr_num_cpus + 1; + router->vr_malloc_stats[cpu][VR_MALLOC_OBJECT].ms_size = total_size; + + return 0; +} + static void vr_pkt_drop_stats_exit(struct vrouter *router) { @@ -254,11 +501,11 @@ vr_pkt_drop_stats_exit(struct vrouter *router) for (i = 0; i < vr_num_cpus; i++) { if (!router->vr_pdrop_stats[i]) break; - vr_free(router->vr_pdrop_stats[i]); + vr_free(router->vr_pdrop_stats[i], VR_DROP_STATS_OBJECT); router->vr_pdrop_stats[i] = NULL; } - vr_free(router->vr_pdrop_stats); + vr_free(router->vr_pdrop_stats, VR_DROP_STATS_OBJECT); router->vr_pdrop_stats = NULL; return; @@ -274,7 +521,7 @@ vr_pkt_drop_stats_init(struct vrouter *router) return 0; size = sizeof(void *) * vr_num_cpus; - router->vr_pdrop_stats = vr_zalloc(size); + router->vr_pdrop_stats = vr_zalloc(size, VR_DROP_STATS_OBJECT); if (!router->vr_pdrop_stats) { vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, size); @@ -283,7 +530,7 @@ vr_pkt_drop_stats_init(struct vrouter *router) size = VP_DROP_MAX * sizeof(uint64_t); for (i = 0; i < vr_num_cpus; i++) { - router->vr_pdrop_stats[i] = vr_zalloc(size); + router->vr_pdrop_stats[i] = vr_zalloc(size, VR_DROP_STATS_OBJECT); if (!router->vr_pdrop_stats[i]) { vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, i); @@ -322,6 +569,7 @@ vr_stats_exit(struct vrouter *router, bool soft_reset) return; } + vr_malloc_stats_exit(router); vr_pkt_drop_stats_exit(router); return; } @@ -329,5 +577,11 @@ vr_stats_exit(struct vrouter *router, bool soft_reset) int vr_stats_init(struct vrouter *router) { + int ret; + + ret = vr_malloc_stats_init(router); + if (ret) + return ret; + return vr_pkt_drop_stats_init(router); } diff --git a/dp-core/vrouter.c b/dp-core/vrouter.c index 22b3d7ac3..4bfaf6912 100644 --- a/dp-core/vrouter.c +++ b/dp-core/vrouter.c @@ -252,12 +252,10 @@ vrouter_ops_destroy(vrouter_ops *req) return; if (req->vo_build_info) { - vr_free(req->vo_build_info); + vr_free(req->vo_build_info, VR_BUILD_INFO_OBJECT); req->vo_build_info = NULL; } - vr_free(req->vo_build_info); - return; } @@ -266,13 +264,14 @@ vrouter_ops_get(void) { vrouter_ops *req; - req = vr_malloc(sizeof(*req)); + req = vr_malloc(sizeof(*req), VR_VROUTER_REQ_OBJECT); if (!req) return NULL; - req->vo_build_info = vr_zalloc(strlen(ContrailBuildInfo)); + req->vo_build_info = vr_zalloc(strlen(ContrailBuildInfo), + VR_BUILD_INFO_OBJECT); if (!req->vo_build_info) { - vr_free(req); + vr_free(req, VR_VROUTER_REQ_OBJECT); return NULL; } diff --git a/dpdk/vr_dpdk_host.c b/dpdk/vr_dpdk_host.c index e3cae5d6f..bad6e2f26 100644 --- a/dpdk/vr_dpdk_host.c +++ b/dpdk/vr_dpdk_host.c @@ -47,6 +47,9 @@ struct rcu_cb_data { unsigned char rcd_user_data[0]; }; +extern void vr_malloc_stats(unsigned int, unsigned int); +extern void vr_free_stats(unsigned int); + static void * dpdk_page_alloc(unsigned int size) { @@ -79,21 +82,28 @@ dpdk_printf(const char *format, ...) } static void * -dpdk_malloc(unsigned int size) +dpdk_malloc(unsigned int size, unsigned int object) { + vr_malloc_stats(size, object); return rte_malloc(NULL, size, 0); } static void * -dpdk_zalloc(unsigned int size) +dpdk_zalloc(unsigned int size, unsigned int object) { + vr_malloc_stats(size, object); return rte_calloc(NULL, size, 1, 0); } static void -dpdk_free(void *mem) +dpdk_free(void *mem, unsigned int object) { - rte_free(mem); + if (mem) { + vr_free_stats(object); + rte_free(mem); + } + + return; } static uint64_t @@ -499,7 +509,7 @@ dpdk_work_timer(struct rte_timer *timer, void *arg) dpdk_timer(timer, arg); dpdk_delete_timer(vtimer); - dpdk_free(vtimer); + dpdk_free(vtimer, VR_TIMER_OBJECT); return; } @@ -510,15 +520,15 @@ dpdk_schedule_work(unsigned int cpu, void (*fn)(void *), void *arg) struct rte_timer *timer; struct vr_timer *vtimer; - timer = dpdk_malloc(sizeof(struct rte_timer)); + timer = dpdk_malloc(sizeof(struct rte_timer), VR_TIMER_OBJECT); if (!timer) { RTE_LOG(ERR, VROUTER, "Error allocating RTE timer\n"); return; } - vtimer = dpdk_malloc(sizeof(*vtimer)); + vtimer = dpdk_malloc(sizeof(*vtimer), VR_TIMER_OBJECT); if (!vtimer) { - dpdk_free(timer); + dpdk_free(timer, VR_TIMER_OBJECT); RTE_LOG(ERR, VROUTER, "Error allocating VR timer for work\n"); return; } @@ -561,7 +571,7 @@ rcu_cb(struct rcu_head *rh) /* Call the user call back */ cb_data->rcd_user_cb(cb_data->rcd_router, cb_data->rcd_user_data); - dpdk_free(cb_data); + dpdk_free(cb_data, VR_DEFER_OBJECT); return; } @@ -587,7 +597,7 @@ dpdk_get_defer_data(unsigned int len) if (!len) return NULL; - cb_data = dpdk_malloc(sizeof(*cb_data) + len); + cb_data = dpdk_malloc(sizeof(*cb_data) + len, VR_DEFER_OBJECT); if (!cb_data) { return NULL; } @@ -604,7 +614,7 @@ dpdk_put_defer_data(void *data) return; cb_data = CONTAINER_OF(rcd_user_data, struct rcu_cb_data, data); - dpdk_free(cb_data); + dpdk_free(cb_data, VR_DEFER_OBJECT); return; } diff --git a/dpdk/vr_dpdk_netlink.c b/dpdk/vr_dpdk_netlink.c index c4456c3ad..09036836c 100644 --- a/dpdk/vr_dpdk_netlink.c +++ b/dpdk/vr_dpdk_netlink.c @@ -113,7 +113,7 @@ static void dpdk_nl_trans_free(char *buf) { buf -= HDR_LEN; - vr_free(buf); + vr_free(buf, VR_MESSAGE_OBJECT); return; } @@ -123,7 +123,7 @@ dpdk_nl_trans_alloc(unsigned int size) { char *buf; - buf = vr_malloc(size + HDR_LEN); + buf = vr_malloc(size + HDR_LEN, VR_MESSAGE_OBJECT); if (!buf) return NULL; diff --git a/dpdk/vr_dpdk_usocket.c b/dpdk/vr_dpdk_usocket.c index 2efae6ec8..af41d81dd 100644 --- a/dpdk/vr_dpdk_usocket.c +++ b/dpdk/vr_dpdk_usocket.c @@ -63,7 +63,7 @@ usock_deinit_poll(struct vr_usocket *usockp) RTE_LOG(DEBUG, USOCK, "%s[%lx]: FD %d\n", __func__, pthread_self(), usockp->usock_fd); if (usockp->usock_pfds) { - vr_free(usockp->usock_pfds); + vr_free(usockp->usock_pfds, VR_USOCK_POLL_OBJECT); usockp->usock_pfds = NULL; } @@ -103,7 +103,7 @@ usock_init_poll(struct vr_usocket *usockp) if (!usockp->usock_pfds) { usockp->usock_pfds = vr_zalloc(sizeof(struct pollfd) * - usockp->usock_max_cfds + 1); + usockp->usock_max_cfds + 1, VR_USOCK_POLL_OBJECT); if (!usockp->usock_pfds) { usock_set_error(usockp, -ENOMEM); goto error_return; @@ -161,7 +161,7 @@ usock_bind_usockets(struct vr_usocket *parent, struct vr_usocket *child) if (!parent->usock_children) { parent->usock_children = vr_zalloc(sizeof(struct vr_usocket *) * - USOCK_MAX_CHILD_FDS + 1); + USOCK_MAX_CHILD_FDS + 1, VR_USOCK_OBJECT); if (!parent->usock_children) { usock_set_error(parent, -ENOMEM); return -ENOMEM; @@ -209,13 +209,13 @@ usock_clone(struct vr_usocket *parent, int cfd) RTE_LOG(DEBUG, USOCK, "%s[%lx]: parent FD %d cfd %d\n", __func__, pthread_self(), parent->usock_fd, cfd); - child = vr_zalloc(sizeof(struct vr_usocket)); + child = vr_zalloc(sizeof(struct vr_usocket), VR_USOCK_OBJECT); if (!child) { usock_set_error(parent, -ENOMEM); goto error_return; } - child->usock_rx_buf = vr_malloc(USOCK_RX_BUF_LEN); + child->usock_rx_buf = vr_malloc(USOCK_RX_BUF_LEN, VR_USOCK_BUF_OBJECT); if (!child->usock_rx_buf) { usock_set_error(parent, -ENOMEM); goto error_return; @@ -234,8 +234,8 @@ usock_clone(struct vr_usocket *parent, int cfd) error_return: if (child) { if (child->usock_rx_buf) - vr_free(child->usock_rx_buf); - vr_free(child); + vr_free(child->usock_rx_buf, VR_USOCK_BUF_OBJECT); + vr_free(child, VR_USOCK_OBJECT); } return parent->usock_error; @@ -291,12 +291,12 @@ usock_close(struct vr_usocket *usockp) close(usockp->usock_fd); if (!usockp->usock_mbuf_pool && usockp->usock_rx_buf) { - vr_free(usockp->usock_rx_buf); + vr_free(usockp->usock_rx_buf, VR_USOCK_BUF_OBJECT); usockp->usock_rx_buf = NULL; } if (usockp->usock_iovec) { - vr_free(usockp->usock_iovec); + vr_free(usockp->usock_iovec, VR_USOCK_IOVEC_OBJECT); usockp->usock_iovec = NULL; } @@ -312,7 +312,7 @@ usock_close(struct vr_usocket *usockp) usockp->usock_io_in_progress = 0; - vr_free(usockp); + vr_free(usockp, VR_USOCK_OBJECT); return; } @@ -667,7 +667,8 @@ __usock_read(struct vr_usocket *usockp) } if (usockp->usock_buf_len < usockp->usock_read_len) { - usockp->usock_rx_buf = vr_malloc(usockp->usock_read_len); + usockp->usock_rx_buf = vr_malloc(usockp->usock_read_len, + VR_USOCK_BUF_OBJECT); if (!usockp->usock_rx_buf) { /* bad, but let's recover */ usockp->usock_rx_buf = buf; @@ -676,7 +677,7 @@ __usock_read(struct vr_usocket *usockp) usockp->usock_state = READING_FAULTY_DATA; } else { memcpy(usockp->usock_rx_buf, buf, usockp->usock_read_offset); - vr_free(buf); + vr_free(buf, VR_USOCK_BUF_OBJECT); usockp->usock_buf_len = usockp->usock_read_len; buf = usockp->usock_rx_buf; } @@ -736,7 +737,7 @@ usock_alloc(unsigned short proto, unsigned short type) return NULL; } - usockp = vr_zalloc(sizeof(*usockp)); + usockp = vr_zalloc(sizeof(*usockp), VR_USOCK_OBJECT); if (!usockp) goto error_exit; @@ -779,7 +780,7 @@ usock_alloc(unsigned short proto, unsigned short type) } if (buf_len) { - usockp->usock_rx_buf = vr_zalloc(buf_len); + usockp->usock_rx_buf = vr_zalloc(buf_len, VR_USOCK_BUF_OBJECT); if (!usockp->usock_rx_buf) goto error_exit; @@ -800,7 +801,7 @@ usock_alloc(unsigned short proto, unsigned short type) } usockp->usock_iovec = vr_zalloc(sizeof(struct iovec) * - PKT0_MAX_IOV_LEN); + PKT0_MAX_IOV_LEN, VR_USOCK_IOVEC_OBJECT); if (!usockp->usock_iovec) goto error_exit; diff --git a/freebsd/vrouter_mod.c b/freebsd/vrouter_mod.c index d3b24e165..259c591b8 100644 --- a/freebsd/vrouter_mod.c +++ b/freebsd/vrouter_mod.c @@ -412,7 +412,7 @@ fh_delete_timer(struct vr_timer *vtimer) vr_log(VR_DEBUG, "stop timer %p\n", callout); if (callout) { callout_drain(callout); - vr_free(vtimer->vt_os_arg); + vr_free(vtimer->vt_os_arg, VR_TIMER_OBJECT); vtimer->vt_os_arg = NULL; } @@ -424,7 +424,7 @@ fh_create_timer(struct vr_timer *vtimer) { struct callout *callout; - callout = vr_zalloc(sizeof(*callout)); + callout = vr_zalloc(sizeof(*callout), VR_TIMER_OBJECT); if (!callout) { vr_log(VR_ERR, "Failed to alloc callout\n"); return (-1); diff --git a/host/vr_host_packet.c b/host/vr_host_packet.c index 190c6018d..a23da6079 100644 --- a/host/vr_host_packet.c +++ b/host/vr_host_packet.c @@ -175,7 +175,7 @@ vr_hpacket_pool_destroy(struct vr_hpacket_pool *pool) vr_hpacket_free(hpkt); hpkt = n_hpkt; } - vr_free(pool); + vr_free(pool, VR_HPACKET_POOL_OBJECT); return; } @@ -190,7 +190,7 @@ vr_hpacket_pool_create(unsigned int pool_size, unsigned int psize) if (!pool_size) return NULL; - pool = vr_zalloc(sizeof(*pool)); + pool = vr_zalloc(sizeof(*pool), VR_HPACKET_POOL_OBJECT); if (!pool) goto cleanup; diff --git a/host/vrouter_host_mod.c b/host/vrouter_host_mod.c index e7c59a9d2..4161b0f91 100644 --- a/host/vrouter_host_mod.c +++ b/host/vrouter_host_mod.c @@ -29,7 +29,7 @@ vr_lib_create_timer(struct vr_timer *vtimer) { struct dummy_timer_list *timer; - timer = vr_zalloc(sizeof(*timer)); + timer = vr_zalloc(sizeof(*timer), VR_TIMER_OBJECT); if (!timer) return -1; init_timer(timer); @@ -46,7 +46,7 @@ vr_lib_create_timer(struct vr_timer *vtimer) static void vr_lib_delete_timer(struct vr_timer *vtimer) { - vr_free(vtimer->vt_os_arg); + vr_free(vtimer->vt_os_arg, VR_TIMER_OBJECT); } static void * @@ -82,19 +82,19 @@ vr_lib_printf(const char *format, ...) } static void * -vr_lib_malloc(unsigned int size) +vr_lib_malloc(unsigned int size, unsigned int object) { return malloc(size); } static void * -vr_lib_zalloc(unsigned int size) +vr_lib_zalloc(unsigned int size, unsigned int object) { return calloc(size, 1); } static void -vr_lib_free(void *mem) +vr_lib_free(void *mem, unsigned int object) { if (mem) free(mem); diff --git a/include/vr_message.h b/include/vr_message.h index 476394e1e..911bb9333 100644 --- a/include/vr_message.h +++ b/include/vr_message.h @@ -29,6 +29,7 @@ #define VR_VXLAN_OBJECT_ID 11 #define VR_VROUTER_OPS_OBJECT_ID 12 #define VR_FLOW_INFO_OBJECT_ID 13 +#define VR_MEM_STATS_OBJECT_ID 14 #define VR_MESSAGE_PAGE_SIZE (4096 - 128) diff --git a/include/vrouter.h b/include/vrouter.h index 627e701c1..4d02728e9 100644 --- a/include/vrouter.h +++ b/include/vrouter.h @@ -26,6 +26,64 @@ extern "C" { #define VR_CPU_MASK 0xff extern unsigned int vr_num_cpus; +enum vr_malloc_objects_t { + VR_ASSEMBLER_TABLE_OBJECT, + VR_BRIDGE_MAC_OBJECT, + VR_BTABLE_OBJECT, + VR_BUILD_INFO_OBJECT, + VR_DEFER_OBJECT, + VR_DROP_STATS_OBJECT, + VR_DROP_STATS_REQ_OBJECT, + VR_FLOW_QUEUE_OBJECT, + VR_FLOW_REQ_OBJECT, + VR_FLOW_REQ_PATH_OBJECT, + VR_FLOW_HOLD_STAT_OBJECT, + VR_FLOW_LINK_LOCAL_OBJECT, + VR_FLOW_METADATA_OBJECT, + VR_FLOW_TABLE_INFO_OBJECT, + VR_FRAGMENT_OBJECT, + VR_FRAGMENT_QUEUE_OBJECT, + VR_FRAGMENT_QUEUE_ELEMENT_OBJECT, + VR_FRAGMENT_SCANNER_OBJECT, + VR_HPACKET_POOL_OBJECT, + VR_HTABLE_OBJECT, + VR_INTERFACE_OBJECT, + VR_INTERFACE_MAC_OBJECT, + VR_INTERFACE_REQ_OBJECT, + VR_INTERFACE_REQ_MAC_OBJECT, + VR_INTERFACE_REQ_NAME_OBJECT, + VR_INTERFACE_STATS_OBJECT, + VR_INTERFACE_TABLE_OBJECT, + VR_INTERFACE_VRF_TABLE_OBJECT, + VR_ITABLE_OBJECT, + VR_MALLOC_OBJECT, + VR_MESSAGE_OBJECT, + VR_MESSAGE_RESPONSE_OBJECT, + VR_MESSAGE_DUMP_OBJECT, + VR_MEM_STATS_REQ_OBJECT, + VR_MIRROR_OBJECT, + VR_MIRROR_TABLE_OBJECT, + VR_MIRROR_META_OBJECT, + VR_MTRIE_OBJECT, + VR_MTRIE_BUCKET_OBJECT, + VR_MTRIE_STATS_OBJECT, + VR_MTRIE_TABLE_OBJECT, + VR_NEXTHOP_OBJECT, + VR_NEXTHOP_COMPONENT_OBJECT, + VR_NEXTHOP_REQ_LIST_OBJECT, + VR_NEXTHOP_REQ_ENCAP_OBJECT, + VR_NEXTHOP_REQ_OBJECT, + VR_ROUTE_TABLE_OBJECT, + VR_ROUTE_REQ_MAC_OBJECT, + VR_TIMER_OBJECT, + VR_USOCK_OBJECT, + VR_USOCK_POLL_OBJECT, + VR_USOCK_BUF_OBJECT, + VR_USOCK_IOVEC_OBJECT, + VR_VROUTER_REQ_OBJECT, + VR_VROUTER_MAX_OBJECT, +}; + extern int vr_perfr; extern int vr_mudp; extern int vr_perfs; @@ -58,9 +116,9 @@ struct vr_timer { struct host_os { int (*hos_printf)(const char *, ...); - void *(*hos_malloc)(unsigned int); - void *(*hos_zalloc)(unsigned int); - void (*hos_free)(void *); + void *(*hos_malloc)(unsigned int, unsigned int); + void *(*hos_zalloc)(unsigned int, unsigned int); + void (*hos_free)(void *, unsigned int); uint64_t (*hos_vtop)(void *); void *(*hos_page_alloc)(unsigned int); void (*hos_page_free)(void *, unsigned int); @@ -157,6 +215,12 @@ struct host_os { #define vr_gro_process vrouter_host->hos_gro_process #define vr_enqueue_to_assembler vrouter_host->hos_enqueue_to_assembler +struct vr_malloc_stats { + int64_t ms_size; + int64_t ms_alloc; + int64_t ms_free; +}; + struct vrouter { unsigned char vr_vrrp_mac[VR_ETHER_ALEN]; unsigned char vr_mac[VR_ETHER_ALEN]; @@ -192,6 +256,7 @@ struct vrouter { struct vr_timer *vr_fragment_otable_scanner; uint64_t **vr_pdrop_stats; + struct vr_malloc_stats **vr_malloc_stats; uint16_t vr_link_local_ports_size; unsigned char *vr_link_local_ports; diff --git a/linux/vr_fragment_assembler.c b/linux/vr_fragment_assembler.c index 93ded4877..f920afd0b 100644 --- a/linux/vr_fragment_assembler.c +++ b/linux/vr_fragment_assembler.c @@ -42,7 +42,7 @@ vr_linux_fragment_queue_free(struct vr_linux_fragment_queue *vlfq) if (vfqe->fqe_pnode.pl_packet) vr_pfree(vfqe->fqe_pnode.pl_packet, VP_DROP_MISC); vfqe->fqe_pnode.pl_packet = NULL; - vr_free(vfqe); + vr_free(vfqe, VR_FRAGMENT_QUEUE_ELEMENT_OBJECT); vfqe = next; } @@ -153,7 +153,7 @@ vr_linux_assembler_table_exit(void) vr_assembler_table_scan_exit(); if (vr_linux_assembler_table) { - vr_free(vr_linux_assembler_table); + vr_free(vr_linux_assembler_table, VR_ASSEMBLER_TABLE_OBJECT); vr_linux_assembler_table = NULL; } @@ -166,7 +166,7 @@ vr_linux_assembler_table_init(void) unsigned int i, size; size = sizeof(struct vr_linux_fragment_bucket) * VR_LINUX_ASSEMBLER_BUCKETS; - vr_linux_assembler_table = vr_zalloc(size); + vr_linux_assembler_table = vr_zalloc(size, VR_ASSEMBLER_TABLE_OBJECT); if (!vr_linux_assembler_table) { printk("%s:%d Allocation for %u failed\n", __FUNCTION__, __LINE__, size); @@ -200,7 +200,7 @@ vr_linux_fragment_queue_exit(void) for (i = 0; i < vr_num_cpus; i++) vr_linux_fragment_queue_free(&vr_lfq_pcpu_queues[i]); - vr_free(vr_lfq_pcpu_queues); + vr_free(vr_lfq_pcpu_queues, VR_FRAGMENT_QUEUE_OBJECT); vr_lfq_pcpu_queues = NULL; } @@ -213,7 +213,7 @@ vr_linux_fragment_queue_init(void) unsigned int i, size; size = sizeof(struct vr_linux_fragment_queue) * vr_num_cpus; - vr_lfq_pcpu_queues = vr_zalloc(size); + vr_lfq_pcpu_queues = vr_zalloc(size, VR_FRAGMENT_QUEUE_OBJECT); if (!vr_lfq_pcpu_queues) { printk("%s:%d Allocation for %u failed\n", __FUNCTION__, __LINE__, size); diff --git a/linux/vrouter_mod.c b/linux/vrouter_mod.c index ce7f4a0cf..b1931dad7 100644 --- a/linux/vrouter_mod.c +++ b/linux/vrouter_mod.c @@ -71,6 +71,8 @@ extern int vr_genetlink_init(void); extern void vr_genetlink_exit(void); extern int vr_mem_init(void); extern void vr_mem_exit(void); +extern void vr_malloc_stats(unsigned int, unsigned int); +extern void vr_free_stats(unsigned int); extern void vhost_exit(void); extern int lh_gro_process(struct vr_packet *, struct vr_interface *, bool); @@ -91,22 +93,26 @@ lh_printk(const char *format, ...) } static void * -lh_malloc(unsigned int size) +lh_malloc(unsigned int size, unsigned int object) { + vr_malloc_stats(size, object); return kmalloc(size, GFP_ATOMIC); } static void * -lh_zalloc(unsigned int size) +lh_zalloc(unsigned int size, unsigned int object) { + vr_malloc_stats(size, object); return kzalloc(size, GFP_ATOMIC); } static void -lh_free(void *mem) +lh_free(void *mem, unsigned int object) { - if (mem) + if (mem) { + vr_free_stats(object); kfree(mem); + } return; } @@ -465,7 +471,7 @@ rcu_cb(struct rcu_head *rh) /* Call the user call back */ cb_data->rcd_user_cb(cb_data->rcd_router, cb_data->rcd_user_data); - lh_free(cb_data); + lh_free(cb_data, VR_DEFER_OBJECT); return; } @@ -491,7 +497,7 @@ lh_get_defer_data(unsigned int len) if (!len) return NULL; - cb_data = lh_malloc(sizeof(*cb_data) + len); + cb_data = lh_malloc(sizeof(*cb_data) + len, VR_DEFER_OBJECT); if (!cb_data) { return NULL; } @@ -508,7 +514,7 @@ lh_put_defer_data(void *data) return; cb_data = container_of(data, struct rcu_cb_data, rcd_user_data); - lh_free(cb_data); + lh_free(cb_data, VR_DEFER_OBJECT); return; } @@ -2331,7 +2337,7 @@ lh_delete_timer(struct vr_timer *vtimer) if (timer) { del_timer_sync(timer); - vr_free(vtimer->vt_os_arg); + vr_free(vtimer->vt_os_arg, VR_TIMER_OBJECT); vtimer->vt_os_arg = NULL; } @@ -2343,7 +2349,7 @@ lh_create_timer(struct vr_timer *vtimer) { struct timer_list *timer; - timer = vr_zalloc(sizeof(*timer)); + timer = vr_zalloc(sizeof(*timer), VR_TIMER_OBJECT); if (!timer) return -ENOMEM; init_timer(timer); diff --git a/sandesh/vr.sandesh b/sandesh/vr.sandesh index d2a5ead00..c1f814455 100644 --- a/sandesh/vr.sandesh +++ b/sandesh/vr.sandesh @@ -231,6 +231,67 @@ buffer sandesh vrouter_ops { 12: string vo_build_info; } +buffer sandesh vr_mem_stats_req { + 1: sandesh_op h_op; + 2: i16 vms_rid; + 3: i64 vms_alloced; + 4: i64 vms_freed; + 5: i64 vms_assembler_table_object; + 6: i64 vms_bridge_mac_object; + 7: i64 vms_btable_object; + 8: i64 vms_build_info_object; + 9: i64 vms_defer_object; + 10: i64 vms_drop_stats_object; + 11: i64 vms_drop_stats_req_object; + 12: i64 vms_flow_queue_object; + 13: i64 vms_flow_req_object; + 14: i64 vms_flow_req_path_object; + 15: i64 vms_flow_hold_stat_object; + 16: i64 vms_flow_link_local_object; + 17: i64 vms_flow_metadata_object; + 18: i64 vms_flow_table_info_object; + 19: i64 vms_fragment_object; + 20: i64 vms_fragment_queue_object; + 21: i64 vms_fragment_queue_element_object; + 22: i64 vms_fragment_scanner_object; + 23: i64 vms_hpacket_pool_object; + 24: i64 vms_htable_object; + 25: i64 vms_interface_object; + 26: i64 vms_interface_mac_object; + 27: i64 vms_interface_req_object; + 28: i64 vms_interface_req_mac_object; + 29: i64 vms_interface_req_name_object; + 30: i64 vms_interface_stats_object; + 31: i64 vms_interface_table_object; + 32: i64 vms_interface_vrf_table_object; + 33: i64 vms_itable_object; + 34: i64 vms_malloc_object; + 35: i64 vms_message_object; + 36: i64 vms_message_response_object; + 37: i64 vms_message_dump_object; + 38: i64 vms_mem_stats_req_object; + 39: i64 vms_mirror_object; + 40: i64 vms_mirror_table_object; + 41: i64 vms_mirror_meta_object; + 42: i64 vms_mtrie_object; + 43: i64 vms_mtrie_bucket_object; + 44: i64 vms_mtrie_stats_object; + 45: i64 vms_mtrie_table_object; + 46: i64 vms_nexthop_object; + 47: i64 vms_nexthop_component_object; + 48: i64 vms_nexthop_req_list_object; + 49: i64 vms_nexthop_req_encap_object; + 50: i64 vms_nexthop_req_object; + 51: i64 vms_route_table_object; + 52: i64 vms_route_req_mac_object; + 53: i64 vms_timer_object; + 54: i64 vms_usock_object; + 55: i64 vms_usock_poll_object; + 56: i64 vms_usock_buf_object; + 57: i64 vms_usock_iovec_object; + 58: i64 vms_vrouter_req_object; +} + buffer sandesh vr_drop_stats_req { 1: sandesh_op h_op; 2: u32 vds_core; diff --git a/utils/SConscript b/utils/SConscript index 2c4e42f67..2a2ad93a6 100644 --- a/utils/SConscript +++ b/utils/SConscript @@ -65,8 +65,12 @@ vxlan = env.Program(target = 'vxlan', source = vxlan_sources) vrouter_sources = ['vrouter.c'] vrouter = env.Program(target = 'vrouter', source = vrouter_sources) +vrmemstats_sources = ['vrmemstats.c'] +vrmemstats = env.Program(target = 'vrmemstats', source = vrmemstats_sources) + # to make sure that all are built when you do 'scons' @ the top level -binaries = [vif, rt, nh, mirror, mpls, flow, vrfstats, dropstats, vxlan, vrouter] +binaries = [vif, rt, nh, mirror, mpls, flow, vrfstats, dropstats, + vxlan, vrouter, vrmemstats] scripts = ['vifdump'] env.Default(binaries) env.Alias('install', env.Install(env['INSTALL_BIN'], binaries + scripts)) diff --git a/utils/nl_util.c b/utils/nl_util.c index 2266a6cd6..569f65fb2 100644 --- a/utils/nl_util.c +++ b/utils/nl_util.c @@ -47,6 +47,7 @@ extern void vr_vrf_assign_req_process(void *s_req) __attribute__((weak)); extern void vr_vrf_stats_req_process(void *s_req) __attribute__((weak)); extern void vr_drop_stats_req_process(void *s_req) __attribute__((weak)); extern void vr_vxlan_req_process(void *s_req) __attribute__((weak)); +extern void vr_mem_stats_req_process(void *s_req) __attribute__((weak)); void vrouter_ops_process(void *s_req) @@ -122,6 +123,12 @@ vr_vxlan_req_process(void *s_req) return; } +void +vr_mem_stats_req_process(void *s_req) +{ + return; +} + struct nl_response * nl_parse_gen_ctrl(struct nl_client *cl) { diff --git a/utils/vrmemstats.c b/utils/vrmemstats.c new file mode 100644 index 000000000..3e77d8231 --- /dev/null +++ b/utils/vrmemstats.c @@ -0,0 +1,324 @@ +/* + * vrmemstats.c - vrouter memory statistics + * + * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#if defined(__linux__) +#include + +#include +#include +#include + +#include +#include +#elif defined(__FreeBSD__) +#include +#include +#endif + +#include "vr_types.h" +#include "vr_message.h" +#include "vr_nexthop.h" +#include "vr_genetlink.h" +#include "nl_util.h" +#include "vr_os.h" +#include "ini_parser.h" + +static struct nl_client *cl; +static int resp_code; +static vr_mem_stats_req stats_req; +static int help_set; + +void +vr_mem_stats_req_process(void *s_req) +{ + vr_mem_stats_req *stats = (vr_mem_stats_req *)s_req; + + + printf("vRouter memory usage statistics\n\n"); + + printf("Alloced %lu Freed %lu\n", stats->vms_alloced, stats->vms_freed); + printf("Outstanding memory/object:\n\n"); + + printf("Assembler Table %" PRIu64 "\n", + stats->vms_assembler_table_object); + printf("Bridge MAC %" PRIu64 "\n", + stats->vms_bridge_mac_object); + printf("Btable %" PRIu64 "\n", + stats->vms_btable_object); + printf("Build Info %" PRIu64 "\n", + stats->vms_build_info_object); + printf("Defer %" PRIu64 "\n", + stats->vms_defer_object); + printf("Drop Stats %" PRIu64 "\n", + stats->vms_drop_stats_object); + printf("Drop Stats Request %" PRIu64 "\n", + stats->vms_drop_stats_req_object); + printf("Flow queue %" PRIu64 "\n", + stats->vms_flow_queue_object); + printf("Flow Request %" PRIu64 "\n", + stats->vms_flow_req_object); + printf("Flow Request Path %" PRIu64 "\n", + stats->vms_flow_req_path_object); + printf("Flow Hold Stat %" PRIu64 "\n", + stats->vms_flow_hold_stat_object); + printf("Flow Link Local %" PRIu64 "\n", + stats->vms_flow_link_local_object); + printf("Flow Metadata %" PRIu64 "\n", + stats->vms_flow_metadata_object); + printf("Flow Table Info %" PRIu64 "\n", + stats->vms_flow_table_info_object); + printf("Fragment %" PRIu64 "\n", + stats->vms_fragment_object); + printf("Fragment Queue %" PRIu64 "\n", + stats->vms_fragment_queue_object); + printf("Fragment Queue Element %" PRIu64 "\n", + stats->vms_fragment_queue_element_object); + printf("Fragment Scanner %" PRIu64 "\n", + stats->vms_fragment_scanner_object); + printf("Host Packet Pool %" PRIu64 "\n", + stats->vms_hpacket_pool_object); + printf("Hash Table %" PRIu64 "\n", + stats->vms_htable_object); + printf("Interface %" PRIu64 "\n", + stats->vms_interface_object); + printf("Interface MAC %" PRIu64 "\n", + stats->vms_interface_mac_object); + printf("Interface Request %" PRIu64 "\n", + stats->vms_interface_req_object); + printf("Interface Request MAC %" PRIu64 "\n", + stats->vms_interface_req_mac_object); + printf("Interface Request Name %" PRIu64 "\n", + stats->vms_interface_req_name_object); + printf("Interface Stats %" PRIu64 "\n", + stats->vms_interface_stats_object); + printf("Interface Table %" PRIu64 "\n", + stats->vms_interface_table_object); + printf("VRF Table %" PRIu64 "\n", + stats->vms_interface_vrf_table_object); + printf("Index Table %" PRIu64 "\n", + stats->vms_itable_object); + printf("Malloc %" PRIu64 "\n", + stats->vms_malloc_object); + printf("Message %" PRIu64 "\n", + stats->vms_message_object); + printf("Message Response %" PRIu64 "\n", + stats->vms_message_response_object); + printf("Message Dump %" PRIu64 "\n", + stats->vms_message_dump_object); + printf("Memory Stats Request %" PRIu64 "\n", + stats->vms_mem_stats_req_object); + printf("Mirror %" PRIu64 "\n", + stats->vms_mirror_object); + printf("Mirror Table %" PRIu64 "\n", + stats->vms_mirror_table_object); + printf("Mirror MetMirror Meta %" PRIu64 "\n", + stats->vms_mirror_meta_object); + printf("MTRIE %" PRIu64 "\n", + stats->vms_mtrie_object); + printf("Mtrie Bucket %" PRIu64 "\n", + stats->vms_mtrie_bucket_object); + printf("Mtrie Stats %" PRIu64 "\n", + stats->vms_mtrie_stats_object); + printf("Mtrie Table %" PRIu64 "\n", + stats->vms_mtrie_table_object); + printf("Nexthop %" PRIu64 "\n", + stats->vms_nexthop_object); + printf("NextHop Component %" PRIu64 "\n", + stats->vms_nexthop_component_object); + printf("NextHop Request List %" PRIu64 "\n", + stats->vms_nexthop_req_list_object); + printf("NextHop Request Encap %" PRIu64 "\n", + stats->vms_nexthop_req_encap_object); + printf("NextHop Request %" PRIu64 "\n", + stats->vms_nexthop_req_object); + printf("Route Table %" PRIu64 "\n", + stats->vms_route_table_object); + printf("Timer %" PRIu64 "\n", + stats->vms_timer_object); + printf("Usock %" PRIu64 "\n", + stats->vms_usock_object); + printf("Usock Poll %" PRIu64 "\n", + stats->vms_usock_poll_object); + printf("Usock Buf %" PRIu64 "\n", + stats->vms_usock_buf_object); + printf("Usock Iovec %" PRIu64 "\n", + stats->vms_usock_iovec_object); + printf("Vrouter Request %" PRIu64 "\n", + stats->vms_vrouter_req_object); + return; +} + +void +vr_response_process(void *s) +{ + vr_response *stats_resp; + + stats_resp = (vr_response *)s; + resp_code = stats_resp->resp_code; + + if (stats_resp->resp_code < 0) { + printf("Error %s in kernel operation\n", strerror(stats_resp->resp_code)); + exit(-1); + } + + return; +} + + +static vr_mem_stats_req * +vr_build_mem_stats_request(void) +{ + stats_req.h_op = SANDESH_OP_GET; + stats_req.vms_rid = 0; + + return &stats_req; +} + +static int +vr_build_netlink_request(vr_mem_stats_req *req) +{ + int ret, error = 0, attr_len; + + /* nlmsg header */ + ret = nl_build_nlh(cl, cl->cl_genl_family_id, NLM_F_REQUEST); + if (ret) + return ret; + + /* Generic nlmsg header */ + ret = nl_build_genlh(cl, SANDESH_REQUEST, 0); + if (ret) + return ret; + + attr_len = nl_get_attr_hdr_size(); + ret = sandesh_encode(req, "vr_mem_stats_req", vr_find_sandesh_info, + (nl_get_buf_ptr(cl) + attr_len), + (nl_get_buf_len(cl) - attr_len), &error); + + if ((ret <= 0) || error) + return -1; + + /* Add sandesh attribute */ + nl_build_attr(cl, ret, NL_ATTR_VR_MESSAGE_PROTOCOL); + nl_update_nlh(cl); + + return 0; +} + +static int +vr_send_one_message(void) +{ + int ret; + struct nl_response *resp; + + ret = nl_sendmsg(cl); + if (ret <= 0) + return 0; + + if((ret = nl_recvmsg(cl)) > 0) { + resp = nl_parse_reply(cl); + if (resp->nl_op == SANDESH_REQUEST) + sandesh_decode(resp->nl_data, resp->nl_len, vr_find_sandesh_info, &ret); + } + + return resp_code; +} + +static void +vr_mem_stats_op(void) +{ + vr_send_one_message(); + return; +} + +static int +vr_get_mem_stats(void) +{ + int ret; + vr_mem_stats_req *req; + + req = vr_build_mem_stats_request(); + if (!req) + return -errno; + + ret = vr_build_netlink_request(req); + if (ret < 0) + return ret; + + vr_mem_stats_op(); + + return 0; +} + +enum opt_index { + HELP_OPT_INDEX, + MAX_OPT_INDEX, +}; + +static struct option long_options[] = { + [HELP_OPT_INDEX] = {"help", no_argument, &help_set, 1}, + [MAX_OPT_INDEX] = {"NULL", 0, 0, 0}, +}; + +static void +Usage() +{ + printf("Usage: memstats [--help]\n"); + exit(-EINVAL); +} + +int +main(int argc, char *argv[]) +{ + char opt; + int ret, option_index; + + while (((opt = getopt_long(argc, argv, "", + long_options, &option_index)) >= 0)) { + switch (opt) { + case 0: + break; + + default: + Usage(); + } + } + + cl = nl_register_client(); + if (!cl) { + exit(1); + } + + parse_ini_file(); + + ret = nl_socket(cl, get_domain(), get_type(), get_protocol()); + if (ret <= 0) { + exit(1); + } + + ret = nl_connect(cl, get_ip(), get_port()); + if (ret < 0) { + exit(1); + } + + if (vrouter_get_family_id(cl) <= 0) { + return -1; + } + + vr_get_mem_stats(); + + return 0; +}