Line data Source code
1 : /* 2 : * vr_stats.c -- catch all stats support. basically for stats which don't 3 : * go well in any other bucket, for eg: packet drop statistics 4 : * 5 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 6 : * Copyright Contributors to the OpenSDN project 7 : */ 8 : #include <vr_os.h> 9 : #include <vr_types.h> 10 : #include <vr_packet.h> 11 : #include <vr_offloads_dp.h> 12 : #include "vr_message.h" 13 : #include "vr_btable.h" 14 : 15 : void vr_stats_exit(struct vrouter *, bool); 16 : int vr_stats_init(struct vrouter *); 17 : int vr_pkt_drop_log_init(struct vrouter *); 18 : void vr_pkt_drop_log_exit(struct vrouter *router); 19 : void 20 : vr_drop_stats_get_vif_stats(vr_drop_stats_req *response, 21 : struct vr_interface *vif); 22 : void 23 : vr_free_stats(unsigned int object); 24 : void 25 : vr_malloc_stats(unsigned int size, unsigned int object); 26 : 27 : static void 28 132 : vr_drop_stats_make_response(vr_drop_stats_req *response, uint64_t *stats) 29 : { 30 132 : if (!response || !stats) 31 0 : return; 32 : 33 132 : response->vds_discard += stats[VP_DROP_DISCARD]; 34 132 : response->vds_pull += stats[VP_DROP_PULL]; 35 132 : response->vds_invalid_if += stats[VP_DROP_INVALID_IF]; 36 132 : response->vds_invalid_arp += stats[VP_DROP_INVALID_ARP]; 37 132 : response->vds_trap_no_if += stats[VP_DROP_TRAP_NO_IF]; 38 132 : response->vds_nowhere_to_go += stats[VP_DROP_NOWHERE_TO_GO]; 39 132 : response->vds_flow_queue_limit_exceeded += 40 132 : stats[VP_DROP_FLOW_QUEUE_LIMIT_EXCEEDED]; 41 132 : response->vds_flow_no_memory += stats[VP_DROP_FLOW_NO_MEMORY]; 42 132 : response->vds_flow_invalid_protocol += 43 132 : stats[VP_DROP_FLOW_INVALID_PROTOCOL]; 44 132 : response->vds_flow_nat_no_rflow += stats[VP_DROP_FLOW_NAT_NO_RFLOW]; 45 132 : response->vds_flow_action_drop += stats[VP_DROP_FLOW_ACTION_DROP]; 46 132 : response->vds_flow_action_invalid += stats[VP_DROP_FLOW_ACTION_INVALID]; 47 132 : response->vds_flow_unusable += stats[VP_DROP_FLOW_UNUSABLE]; 48 132 : response->vds_flow_table_full += stats[VP_DROP_FLOW_TABLE_FULL]; 49 132 : response->vds_interface_tx_discard += stats[VP_DROP_INTERFACE_TX_DISCARD]; 50 132 : response->vds_interface_drop += stats[VP_DROP_INTERFACE_DROP]; 51 132 : response->vds_duplicated += stats[VP_DROP_DUPLICATED]; 52 132 : response->vds_push += stats[VP_DROP_PUSH]; 53 132 : response->vds_ttl_exceeded += stats[VP_DROP_TTL_EXCEEDED]; 54 132 : response->vds_invalid_nh += stats[VP_DROP_INVALID_NH]; 55 132 : response->vds_invalid_label += stats[VP_DROP_INVALID_LABEL]; 56 132 : response->vds_invalid_protocol += stats[VP_DROP_INVALID_PROTOCOL]; 57 132 : response->vds_interface_rx_discard += stats[VP_DROP_INTERFACE_RX_DISCARD]; 58 132 : response->vds_invalid_mcast_source += stats[VP_DROP_INVALID_MCAST_SOURCE]; 59 132 : response->vds_pcow_fail += stats[VP_DROP_PCOW_FAIL]; 60 132 : response->vds_mcast_df_bit += stats[VP_DROP_MCAST_DF_BIT]; 61 132 : response->vds_mcast_clone_fail += stats[VP_DROP_MCAST_CLONE_FAIL]; 62 132 : response->vds_no_memory += stats[VP_DROP_NO_MEMORY]; 63 132 : response->vds_rewrite_fail += stats[VP_DROP_REWRITE_FAIL]; 64 132 : response->vds_misc += stats[VP_DROP_MISC]; 65 132 : response->vds_invalid_packet += stats[VP_DROP_INVALID_PACKET]; 66 132 : response->vds_cksum_err += stats[VP_DROP_CKSUM_ERR]; 67 132 : response->vds_no_fmd += stats[VP_DROP_NO_FMD]; 68 132 : response->vds_cloned_original += stats[VP_DROP_CLONED_ORIGINAL]; 69 132 : response->vds_invalid_vnid += stats[VP_DROP_INVALID_VNID]; 70 132 : response->vds_frag_err += stats[VP_DROP_FRAGMENTS]; 71 132 : response->vds_invalid_source += stats[VP_DROP_INVALID_SOURCE]; 72 132 : response->vds_l2_no_route += stats[VP_DROP_L2_NO_ROUTE]; 73 132 : response->vds_fragment_queue_fail += 74 132 : stats[VP_DROP_FRAGMENT_QUEUE_FAIL]; 75 132 : response->vds_vlan_fwd_tx += stats[VP_DROP_VLAN_FWD_TX]; 76 132 : response->vds_vlan_fwd_enq += stats[VP_DROP_VLAN_FWD_ENQ]; 77 132 : response->vds_drop_new_flow += stats[VP_DROP_NEW_FLOWS]; 78 132 : response->vds_flow_evict += stats[VP_DROP_FLOW_EVICT]; 79 132 : response->vds_trap_original += stats[VP_DROP_TRAP_ORIGINAL]; 80 132 : response->vds_leaf_to_leaf += stats[VP_DROP_LEAF_TO_LEAF]; 81 132 : response->vds_bmac_isid_mismatch += stats[VP_DROP_BMAC_ISID_MISMATCH]; 82 132 : response->vds_pkt_loop += stats[VP_DROP_PKT_LOOP]; 83 132 : response->vds_no_crypt_path += stats[VP_DROP_NO_CRYPT_PATH]; 84 132 : response->vds_invalid_hbs_pkt += stats[VP_DROP_INVALID_HBS_PKT]; 85 132 : response->vds_no_frag_entry += stats[VP_DROP_NO_FRAG_ENTRY]; 86 132 : response->vds_icmp_error += stats[VP_DROP_ICMP_ERROR]; 87 132 : response->vds_clone_fail += stats[VP_DROP_CLONE_FAIL]; 88 132 : response->vds_invalid_underlay_ecmp += stats[VP_DROP_INVALID_UNDERLAY_ECMP]; 89 132 : return; 90 : } 91 : 92 : 93 : void 94 0 : vr_drop_stats_get_vif_stats(vr_drop_stats_req *response, 95 : struct vr_interface *vif) 96 : { 97 : uint8_t *count; 98 : int stats_index, cpu; 99 : uint64_t stats[VP_DROP_MAX]; 100 : 101 0 : if (!vif || !vif->vif_drop_stats) 102 0 : return; 103 : 104 : /* 105 : * Collect all per cpu and full stats of this interface in local 106 : * stats before adding to response 107 : */ 108 0 : for (stats_index = 0; stats_index < VP_DROP_MAX; stats_index++) { 109 0 : stats[stats_index] = vif->vif_drop_stats[stats_index]; 110 0 : if (vif->vif_pcpu_drop_stats) { 111 0 : for (cpu = 0; cpu < vr_num_cpus; cpu++) { 112 0 : count = vr_btable_get(vif->vif_pcpu_drop_stats, 113 0 : ((cpu * VP_DROP_MAX) + stats_index)); 114 0 : stats[stats_index] += *count; 115 : } 116 : } else { 117 0 : response->vds_pcpu_stats_failure_status = 1; 118 : } 119 : } 120 : 121 : /* Now add add the stats to response message */ 122 0 : vr_drop_stats_make_response(response, stats); 123 : 124 0 : return; 125 : } 126 : 127 : static void 128 11 : vr_drop_stats_get(unsigned int rid, short core) 129 : { 130 11 : int ret = 0; 131 : unsigned int cpu; 132 11 : struct vrouter *router = vrouter_get(rid); 133 11 : vr_drop_stats_req *response = NULL; 134 : 135 11 : if (!router && (ret = -ENOENT)) 136 0 : goto exit_get; 137 : 138 11 : response = vr_zalloc(sizeof(*response), VR_DROP_STATS_REQ_OBJECT); 139 11 : if (!response && (ret = -ENOMEM)) 140 0 : goto exit_get; 141 : 142 11 : if (core == -1) { 143 : /* summed up stats */ 144 143 : for (cpu = 0; cpu < vr_num_cpus; cpu++) { 145 132 : vr_drop_stats_make_response(response, router->vr_pdrop_stats[cpu]); 146 : } 147 : /* offload gets added to summed stats */ 148 11 : vr_offload_drop_stats_get(response); 149 0 : } else if (core == (unsigned)-2) { 150 : /* this allows returning only offloaded stats without 151 : changing the current usage of this function */ 152 0 : vr_offload_drop_stats_get(response); 153 0 : } else if (core < vr_num_cpus) { 154 : /* stats for a specific core */ 155 0 : vr_drop_stats_make_response(response, router->vr_pdrop_stats[core]); 156 : } 157 : /* otherwise the counters will be zeros */ 158 : 159 0 : exit_get: 160 11 : vr_message_response(VR_DROP_STATS_OBJECT_ID, ret ? NULL : response, ret, false); 161 : 162 11 : if (response != NULL) 163 11 : vr_free(response, VR_DROP_STATS_REQ_OBJECT); 164 : 165 11 : return; 166 : } 167 : 168 : static void 169 0 : vr_drop_stats_clear(vr_drop_stats_req *req) 170 : { 171 : 172 0 : int i = 0, size = 0, ret = 0; 173 0 : struct vrouter *router = vrouter_get(0); 174 0 : vr_drop_stats_req *response = NULL; 175 : 176 0 : response = vr_zalloc(sizeof(*response), VR_DROP_STATS_REQ_OBJECT); 177 0 : if (!response && (ret = -ENOMEM)) 178 0 : goto exit_get; 179 : 180 0 : if (!router->vr_pdrop_stats) 181 0 : return; 182 : 183 0 : size = VP_DROP_MAX * sizeof(uint64_t); 184 0 : for (i = 0; i < vr_num_cpus; i++) { 185 0 : memset(router->vr_pdrop_stats[i], 0, size); 186 : } 187 0 : response->h_op = SANDESH_OP_RESET; 188 : 189 0 : exit_get: 190 0 : vr_message_response(VR_DROP_STATS_OBJECT_ID, ret ? NULL : response, ret, false); 191 : 192 0 : if (response != NULL) 193 0 : vr_free(response, VR_DROP_STATS_REQ_OBJECT); 194 : 195 0 : return; 196 : } 197 : 198 : void 199 11 : vr_drop_stats_req_process(void *s_req) 200 : { 201 11 : int ret = 0; 202 11 : vr_drop_stats_req *req = (vr_drop_stats_req *)s_req; 203 : 204 11 : if(req->h_op == SANDESH_OP_RESET) 205 : { 206 0 : vr_drop_stats_clear(req); 207 0 : return; 208 : } 209 : 210 11 : if ((req->h_op != SANDESH_OP_GET) && (ret = -EOPNOTSUPP)) 211 0 : vr_send_response(ret); 212 : 213 : /* zero vds_core means to sum up all the per-core stats */ 214 11 : vr_drop_stats_get(req->vds_rid, req->vds_core - 1); 215 11 : return; 216 : } 217 : 218 : static void 219 0 : vr_mem_stats_get(void) 220 : { 221 0 : int ret = 0; 222 : unsigned int cpu, i; 223 0 : int64_t alloced = 0, freed = 0; 224 : 225 0 : struct vrouter *router = vrouter_get(0); 226 : struct vr_malloc_stats *stats_block; 227 0 : vr_mem_stats_req *response = NULL; 228 : 229 0 : if (!router && (ret = -ENOENT)) 230 0 : goto exit_get; 231 : 232 0 : response = vr_zalloc(sizeof(*response), VR_MEM_STATS_REQ_OBJECT); 233 0 : if (!response && (ret = -ENOMEM)) 234 0 : goto exit_get; 235 : 236 : 237 0 : for (cpu = 0; cpu < vr_num_cpus; cpu++) { 238 0 : stats_block = (struct vr_malloc_stats *)router->vr_malloc_stats[cpu]; 239 0 : response->vms_assembler_table_object += (stats_block[VR_ASSEMBLER_TABLE_OBJECT].ms_alloc - 240 0 : stats_block[VR_ASSEMBLER_TABLE_OBJECT].ms_free); 241 0 : response->vms_bridge_mac_object += (stats_block[VR_BRIDGE_MAC_OBJECT].ms_alloc - 242 0 : stats_block[VR_BRIDGE_MAC_OBJECT].ms_free); 243 0 : response->vms_btable_object += (stats_block[VR_BTABLE_OBJECT].ms_alloc - 244 0 : stats_block[VR_BTABLE_OBJECT].ms_free); 245 0 : response->vms_build_info_object += (stats_block[VR_BUILD_INFO_OBJECT].ms_alloc - 246 0 : stats_block[VR_BUILD_INFO_OBJECT].ms_free); 247 0 : response->vms_defer_object += (stats_block[VR_DEFER_OBJECT].ms_alloc - 248 0 : stats_block[VR_DEFER_OBJECT].ms_free); 249 0 : response->vms_drop_stats_object += (stats_block[VR_DROP_STATS_OBJECT].ms_alloc - 250 0 : stats_block[VR_DROP_STATS_OBJECT].ms_free); 251 0 : response->vms_drop_stats_req_object += (stats_block[VR_DROP_STATS_REQ_OBJECT].ms_alloc - 252 0 : stats_block[VR_DROP_STATS_REQ_OBJECT].ms_free); 253 0 : response->vms_flow_queue_object += (stats_block[VR_FLOW_QUEUE_OBJECT].ms_alloc - 254 0 : stats_block[VR_FLOW_QUEUE_OBJECT].ms_free); 255 0 : response->vms_flow_req_object += (stats_block[VR_FLOW_REQ_OBJECT].ms_alloc - 256 0 : stats_block[VR_FLOW_REQ_OBJECT].ms_free); 257 0 : response->vms_flow_req_path_object += (stats_block[VR_FLOW_REQ_PATH_OBJECT].ms_alloc - 258 0 : stats_block[VR_FLOW_REQ_PATH_OBJECT].ms_free); 259 0 : response->vms_flow_hold_stat_object += (stats_block[VR_FLOW_HOLD_STAT_OBJECT].ms_alloc - 260 0 : stats_block[VR_FLOW_HOLD_STAT_OBJECT].ms_free); 261 0 : response->vms_flow_link_local_object += (stats_block[VR_FLOW_LINK_LOCAL_OBJECT].ms_alloc - 262 0 : stats_block[VR_FLOW_LINK_LOCAL_OBJECT].ms_free); 263 0 : response->vms_flow_metadata_object += (stats_block[VR_FLOW_METADATA_OBJECT].ms_alloc - 264 0 : stats_block[VR_FLOW_METADATA_OBJECT].ms_free); 265 0 : response->vms_flow_table_data_object += (stats_block[VR_FLOW_TABLE_DATA_OBJECT].ms_alloc - 266 0 : stats_block[VR_FLOW_TABLE_DATA_OBJECT].ms_free); 267 0 : response->vms_flow_table_info_object += (stats_block[VR_FLOW_TABLE_INFO_OBJECT].ms_alloc - 268 0 : stats_block[VR_FLOW_TABLE_INFO_OBJECT].ms_free); 269 0 : response->vms_fragment_object += (stats_block[VR_FRAGMENT_OBJECT].ms_alloc - 270 0 : stats_block[VR_FRAGMENT_OBJECT].ms_free); 271 0 : response->vms_fragment_queue_object += (stats_block[VR_FRAGMENT_QUEUE_OBJECT].ms_alloc - 272 0 : stats_block[VR_FRAGMENT_QUEUE_OBJECT].ms_free); 273 0 : response->vms_fragment_queue_element_object += (stats_block[VR_FRAGMENT_QUEUE_ELEMENT_OBJECT].ms_alloc - 274 0 : stats_block[VR_FRAGMENT_QUEUE_ELEMENT_OBJECT].ms_free); 275 0 : response->vms_fragment_scanner_object += (stats_block[VR_FRAGMENT_SCANNER_OBJECT].ms_alloc - 276 0 : stats_block[VR_FRAGMENT_SCANNER_OBJECT].ms_free); 277 0 : response->vms_hpacket_pool_object += (stats_block[VR_HPACKET_POOL_OBJECT].ms_alloc - 278 0 : stats_block[VR_HPACKET_POOL_OBJECT].ms_free); 279 0 : response->vms_htable_object += (stats_block[VR_HTABLE_OBJECT].ms_alloc - 280 0 : stats_block[VR_HTABLE_OBJECT].ms_free); 281 0 : response->vms_interface_object += (stats_block[VR_INTERFACE_OBJECT].ms_alloc - 282 0 : stats_block[VR_INTERFACE_OBJECT].ms_free); 283 0 : response->vms_interface_bridge_lock_object += 284 0 : (stats_block[VR_INTERFACE_BRIDGE_LOCK_OBJECT].ms_alloc - 285 0 : stats_block[VR_INTERFACE_BRIDGE_LOCK_OBJECT].ms_free); 286 0 : response->vms_interface_req_bridge_id_object += 287 0 : (stats_block[VR_INTERFACE_REQ_BRIDGE_ID_OBJECT].ms_alloc - 288 0 : stats_block[VR_INTERFACE_REQ_BRIDGE_ID_OBJECT].ms_free); 289 0 : response->vms_interface_fat_flow_config_object += 290 0 : (stats_block[VR_INTERFACE_FAT_FLOW_CONFIG_OBJECT].ms_alloc - 291 0 : stats_block[VR_INTERFACE_FAT_FLOW_CONFIG_OBJECT].ms_free); 292 0 : response->vms_interface_mac_object += (stats_block[VR_INTERFACE_MAC_OBJECT].ms_alloc - 293 0 : stats_block[VR_INTERFACE_MAC_OBJECT].ms_free); 294 0 : response->vms_interface_queue_object += (stats_block[VR_INTERFACE_QUEUE_OBJECT].ms_alloc - 295 0 : stats_block[VR_INTERFACE_QUEUE_OBJECT].ms_free); 296 0 : response->vms_interface_req_object += (stats_block[VR_INTERFACE_REQ_OBJECT].ms_alloc - 297 0 : stats_block[VR_INTERFACE_REQ_OBJECT].ms_free); 298 0 : response->vms_interface_req_mac_object += (stats_block[VR_INTERFACE_REQ_MAC_OBJECT].ms_alloc - 299 0 : stats_block[VR_INTERFACE_REQ_MAC_OBJECT].ms_free); 300 0 : response->vms_interface_req_name_object += (stats_block[VR_INTERFACE_REQ_NAME_OBJECT].ms_alloc - 301 0 : stats_block[VR_INTERFACE_REQ_NAME_OBJECT].ms_free); 302 0 : response->vms_interface_req_pbb_mac_object += 303 0 : (stats_block[VR_INTERFACE_REQ_PBB_MAC_OBJECT].ms_alloc - 304 0 : stats_block[VR_INTERFACE_REQ_PBB_MAC_OBJECT].ms_free); 305 0 : response->vms_interface_stats_object += (stats_block[VR_INTERFACE_STATS_OBJECT].ms_alloc - 306 0 : stats_block[VR_INTERFACE_STATS_OBJECT].ms_free); 307 0 : response->vms_interface_table_object += (stats_block[VR_INTERFACE_TABLE_OBJECT].ms_alloc - 308 0 : stats_block[VR_INTERFACE_TABLE_OBJECT].ms_free); 309 0 : response->vms_interface_vrf_table_object += (stats_block[VR_INTERFACE_VRF_TABLE_OBJECT].ms_alloc - 310 0 : stats_block[VR_INTERFACE_VRF_TABLE_OBJECT].ms_free); 311 0 : response->vms_itable_object += (stats_block[VR_ITABLE_OBJECT].ms_alloc - 312 0 : stats_block[VR_ITABLE_OBJECT].ms_free); 313 0 : response->vms_malloc_object += (stats_block[VR_MALLOC_OBJECT].ms_alloc - 314 0 : stats_block[VR_MALLOC_OBJECT].ms_free); 315 0 : response->vms_message_object += (stats_block[VR_MESSAGE_OBJECT].ms_alloc - 316 0 : stats_block[VR_MESSAGE_OBJECT].ms_free); 317 0 : response->vms_message_response_object += (stats_block[VR_MESSAGE_RESPONSE_OBJECT].ms_alloc - 318 0 : stats_block[VR_MESSAGE_RESPONSE_OBJECT].ms_free); 319 0 : response->vms_message_dump_object += (stats_block[VR_MESSAGE_DUMP_OBJECT].ms_alloc - 320 0 : stats_block[VR_MESSAGE_DUMP_OBJECT].ms_free); 321 0 : response->vms_mem_stats_req_object += (stats_block[VR_MEM_STATS_REQ_OBJECT].ms_alloc - 322 0 : stats_block[VR_MEM_STATS_REQ_OBJECT].ms_free); 323 0 : response->vms_mirror_object += (stats_block[VR_MIRROR_OBJECT].ms_alloc - 324 0 : stats_block[VR_MIRROR_OBJECT].ms_free); 325 0 : response->vms_mirror_table_object += (stats_block[VR_MIRROR_TABLE_OBJECT].ms_alloc - 326 0 : stats_block[VR_MIRROR_TABLE_OBJECT].ms_free); 327 0 : response->vms_mirror_meta_object += (stats_block[VR_MIRROR_META_OBJECT].ms_alloc - 328 0 : stats_block[VR_MIRROR_META_OBJECT].ms_free); 329 0 : response->vms_mtrie_object += (stats_block[VR_MTRIE_OBJECT].ms_alloc - 330 0 : stats_block[VR_MTRIE_OBJECT].ms_free); 331 0 : response->vms_mtrie_bucket_object += (stats_block[VR_MTRIE_BUCKET_OBJECT].ms_alloc - 332 0 : stats_block[VR_MTRIE_BUCKET_OBJECT].ms_free); 333 0 : response->vms_mtrie_stats_object += (stats_block[VR_MTRIE_STATS_OBJECT].ms_alloc - 334 0 : stats_block[VR_MTRIE_STATS_OBJECT].ms_free); 335 0 : response->vms_mtrie_table_object += (stats_block[VR_MTRIE_TABLE_OBJECT].ms_alloc - 336 0 : stats_block[VR_MTRIE_TABLE_OBJECT].ms_free); 337 0 : response->vms_network_address_object += (stats_block[VR_NETWORK_ADDRESS_OBJECT].ms_alloc - 338 0 : stats_block[VR_NETWORK_ADDRESS_OBJECT].ms_free); 339 0 : response->vms_nexthop_object += (stats_block[VR_NEXTHOP_OBJECT].ms_alloc - 340 0 : stats_block[VR_NEXTHOP_OBJECT].ms_free); 341 0 : response->vms_nexthop_component_object += (stats_block[VR_NEXTHOP_COMPONENT_OBJECT].ms_alloc - 342 0 : stats_block[VR_NEXTHOP_COMPONENT_OBJECT].ms_free); 343 0 : response->vms_nexthop_req_bmac_object += 344 0 : (stats_block[VR_NEXTHOP_REQ_BMAC_OBJECT].ms_alloc - 345 0 : stats_block[VR_NEXTHOP_REQ_BMAC_OBJECT].ms_free); 346 0 : response->vms_nexthop_req_list_object += (stats_block[VR_NEXTHOP_REQ_LIST_OBJECT].ms_alloc - 347 0 : stats_block[VR_NEXTHOP_REQ_LIST_OBJECT].ms_free); 348 0 : response->vms_nexthop_req_encap_object += (stats_block[VR_NEXTHOP_REQ_ENCAP_OBJECT].ms_alloc - 349 0 : stats_block[VR_NEXTHOP_REQ_ENCAP_OBJECT].ms_free); 350 0 : response->vms_nexthop_req_object += (stats_block[VR_NEXTHOP_REQ_OBJECT].ms_alloc - 351 0 : stats_block[VR_NEXTHOP_REQ_OBJECT].ms_free); 352 0 : response->vms_route_table_object += (stats_block[VR_ROUTE_TABLE_OBJECT].ms_alloc - 353 0 : stats_block[VR_ROUTE_TABLE_OBJECT].ms_free); 354 0 : response->vms_route_req_mac_object += (stats_block[VR_ROUTE_REQ_MAC_OBJECT].ms_alloc - 355 0 : stats_block[VR_ROUTE_REQ_MAC_OBJECT].ms_free); 356 0 : response->vms_timer_object += (stats_block[VR_TIMER_OBJECT].ms_alloc - 357 0 : stats_block[VR_TIMER_OBJECT].ms_free); 358 0 : response->vms_usock_object += (stats_block[VR_USOCK_OBJECT].ms_alloc - 359 0 : stats_block[VR_USOCK_OBJECT].ms_free); 360 0 : response->vms_usock_poll_object += (stats_block[VR_USOCK_POLL_OBJECT].ms_alloc - 361 0 : stats_block[VR_USOCK_POLL_OBJECT].ms_free); 362 0 : response->vms_usock_buf_object += (stats_block[VR_USOCK_BUF_OBJECT].ms_alloc - 363 0 : stats_block[VR_USOCK_BUF_OBJECT].ms_free); 364 0 : response->vms_usock_iovec_object += (stats_block[VR_USOCK_IOVEC_OBJECT].ms_alloc - 365 0 : stats_block[VR_USOCK_IOVEC_OBJECT].ms_free); 366 0 : response->vms_vrouter_req_object += (stats_block[VR_VROUTER_REQ_OBJECT].ms_alloc - 367 0 : stats_block[VR_VROUTER_REQ_OBJECT].ms_free); 368 0 : response->vms_qos_map_object += (stats_block[VR_QOS_MAP_OBJECT].ms_alloc - 369 0 : stats_block[VR_QOS_MAP_OBJECT].ms_free); 370 0 : response->vms_fc_object += (stats_block[VR_FC_OBJECT].ms_alloc - 371 0 : stats_block[VR_FC_OBJECT].ms_free); 372 0 : response->vms_interface_mirror_meta_object += 373 0 : (stats_block[VR_INTERFACE_MIRROR_META_OBJECT].ms_alloc - 374 0 : stats_block[VR_INTERFACE_MIRROR_META_OBJECT].ms_free); 375 0 : response->vms_interface_req_mirror_meta_object += 376 0 : (stats_block[VR_INTERFACE_REQ_MIRROR_META_OBJECT].ms_alloc - 377 0 : stats_block[VR_INTERFACE_REQ_MIRROR_META_OBJECT].ms_free); 378 0 : response->vms_interface_fat_flow_ipv4_exclude_list_object += 379 0 : (stats_block[VR_INTERFACE_FAT_FLOW_IPV4_EXCLUDE_LIST_OBJECT].ms_alloc - 380 0 : stats_block[VR_INTERFACE_FAT_FLOW_IPV4_EXCLUDE_LIST_OBJECT].ms_free); 381 0 : response->vms_interface_fat_flow_ipv6_exclude_list_object += 382 0 : (stats_block[VR_INTERFACE_FAT_FLOW_IPV6_EXCLUDE_LIST_OBJECT].ms_alloc - 383 0 : stats_block[VR_INTERFACE_FAT_FLOW_IPV6_EXCLUDE_LIST_OBJECT].ms_free); 384 0 : for (i = 0; i < VR_VROUTER_MAX_OBJECT; i++) { 385 0 : alloced += stats_block[i].ms_alloc; 386 0 : freed += stats_block[i].ms_free; 387 : } 388 : } 389 : 390 : 391 0 : response->vms_alloced = alloced; 392 0 : response->vms_freed = freed; 393 : 394 0 : exit_get: 395 0 : vr_message_response(VR_MEM_STATS_OBJECT_ID, ret ? NULL : response, ret, false); 396 0 : if (response != NULL) 397 0 : vr_free(response, VR_MEM_STATS_REQ_OBJECT); 398 : 399 0 : return; 400 : } 401 : 402 : void 403 0 : vr_mem_stats_req_process(void *s_req) 404 : { 405 : int ret; 406 0 : vr_mem_stats_req *req = (vr_mem_stats_req *)s_req; 407 : 408 0 : if ((req->h_op != SANDESH_OP_GET) && (ret = -EOPNOTSUPP)) 409 0 : vr_send_response(ret); 410 : 411 0 : vr_mem_stats_get(); 412 0 : return; 413 : } 414 : 415 : void 416 240821 : vr_free_stats(unsigned int object) 417 : { 418 240821 : struct vrouter *router = vrouter_get(0); 419 : unsigned int cpu; 420 : 421 240821 : cpu = vr_get_cpu(); 422 240821 : if (router->vr_malloc_stats && router->vr_malloc_stats[cpu]) 423 240185 : router->vr_malloc_stats[cpu][object].ms_free++; 424 : 425 240821 : return; 426 : } 427 : 428 : void 429 244129 : vr_malloc_stats(unsigned int size, unsigned int object) 430 : { 431 244129 : struct vrouter *router = vrouter_get(0); 432 : unsigned int cpu; 433 : 434 244129 : cpu = vr_get_cpu(); 435 244129 : if (router->vr_malloc_stats) { 436 244076 : if (router->vr_malloc_stats[cpu]) { 437 244023 : router->vr_malloc_stats[cpu][object].ms_size += size; 438 244023 : router->vr_malloc_stats[cpu][object].ms_alloc++; 439 : } 440 : } 441 : 442 244129 : return; 443 : } 444 : 445 : static void 446 53 : vr_malloc_stats_exit(struct vrouter *router) 447 : { 448 : unsigned int i; 449 : 450 53 : if (!router->vr_malloc_stats) 451 0 : return; 452 : 453 689 : for (i = 0; i < vr_num_cpus; i++) { 454 636 : if (router->vr_malloc_stats[i]) { 455 636 : vr_free(router->vr_malloc_stats[i], VR_MALLOC_OBJECT); 456 636 : router->vr_malloc_stats[i] = NULL; 457 : } 458 : } 459 : 460 53 : vr_free(router->vr_malloc_stats, VR_MALLOC_OBJECT); 461 53 : router->vr_malloc_stats = NULL; 462 : 463 53 : return; 464 : } 465 : 466 : static int 467 53 : vr_malloc_stats_init(struct vrouter *router) 468 : { 469 53 : unsigned int i, size, cpu, total_size = 0; 470 : 471 53 : if (router->vr_malloc_stats) 472 0 : return 0; 473 : 474 53 : size = vr_num_cpus * sizeof(void *); 475 53 : router->vr_malloc_stats = vr_zalloc(size, VR_MALLOC_OBJECT); 476 53 : if (!router->vr_malloc_stats) 477 0 : return -ENOMEM; 478 53 : total_size += size; 479 : 480 53 : size = VR_VROUTER_MAX_OBJECT * sizeof(struct vr_malloc_stats); 481 : /* 482 : * align the allocation to cache line size so that per-cpu variable 483 : * do not result in cache thrashing 484 : */ 485 53 : if (size % 64) { 486 53 : size = size + (64 - (size % 64)); 487 : } 488 : 489 689 : for (i = 0; i < vr_num_cpus; i++) { 490 636 : router->vr_malloc_stats[i] = vr_zalloc(size, VR_MALLOC_OBJECT); 491 636 : if (!router->vr_malloc_stats) 492 0 : return -ENOMEM; 493 636 : total_size += size; 494 : } 495 : 496 53 : cpu = vr_get_cpu(); 497 53 : router->vr_malloc_stats[cpu][VR_MALLOC_OBJECT].ms_alloc = vr_num_cpus + 1; 498 53 : router->vr_malloc_stats[cpu][VR_MALLOC_OBJECT].ms_size = total_size; 499 : 500 53 : return 0; 501 : } 502 : 503 : static void 504 53 : vr_pkt_drop_stats_exit(struct vrouter *router) 505 : { 506 : unsigned int i; 507 : 508 53 : if (!router->vr_pdrop_stats) 509 0 : return; 510 : 511 689 : for (i = 0; i < vr_num_cpus; i++) { 512 636 : if (!router->vr_pdrop_stats[i]) 513 0 : break; 514 636 : vr_free(router->vr_pdrop_stats[i], VR_DROP_STATS_OBJECT); 515 636 : router->vr_pdrop_stats[i] = NULL; 516 : } 517 : 518 53 : vr_free(router->vr_pdrop_stats, VR_DROP_STATS_OBJECT); 519 53 : router->vr_pdrop_stats = NULL; 520 : 521 53 : vr_pkt_drop_log_exit(router); 522 : 523 53 : return; 524 : } 525 : 526 : 527 : static int 528 53 : vr_pkt_drop_stats_init(struct vrouter *router) 529 : { 530 53 : unsigned int i = 0; 531 53 : unsigned int size = 0; 532 : 533 53 : if (router->vr_pdrop_stats) 534 0 : return 0; 535 : 536 53 : size = sizeof(void *) * vr_num_cpus; 537 53 : router->vr_pdrop_stats = vr_zalloc(size, VR_DROP_STATS_OBJECT); 538 53 : if (!router->vr_pdrop_stats) { 539 0 : vr_module_error(-ENOMEM, __FUNCTION__, 540 : __LINE__, size); 541 0 : goto cleanup; 542 : } 543 : 544 53 : size = VP_DROP_MAX * sizeof(uint64_t); 545 689 : for (i = 0; i < vr_num_cpus; i++) { 546 636 : router->vr_pdrop_stats[i] = vr_zalloc(size, VR_DROP_STATS_OBJECT); 547 636 : if (!router->vr_pdrop_stats[i]) { 548 0 : vr_module_error(-ENOMEM, __FUNCTION__, 549 : __LINE__, i); 550 0 : goto cleanup; 551 : } 552 : } 553 : 554 53 : vr_pkt_drop_log_init(router); 555 : 556 53 : return 0; 557 : 558 0 : cleanup: 559 0 : vr_pkt_drop_stats_exit(router); 560 0 : return -ENOMEM; 561 : } 562 : 563 : static void 564 0 : vr_pkt_drop_stats_reset(struct vrouter *router) 565 : { 566 : unsigned int i; 567 : 568 0 : if (!router->vr_pdrop_stats) 569 0 : return; 570 : 571 0 : for (i = 0; i < vr_num_cpus; i++) { 572 0 : if (router->vr_pdrop_stats[i]) 573 0 : memset(router->vr_pdrop_stats[i], 0, VP_DROP_MAX * sizeof(uint64_t)); 574 : } 575 : 576 0 : return; 577 : } 578 : 579 : void 580 53 : vr_stats_exit(struct vrouter *router, bool soft_reset) 581 : { 582 53 : if (soft_reset) { 583 0 : vr_pkt_drop_stats_reset(router); 584 0 : return; 585 : } 586 : 587 53 : vr_pkt_drop_stats_exit(router); 588 53 : vr_malloc_stats_exit(router); 589 53 : return; 590 : } 591 : 592 : int 593 53 : vr_stats_init(struct vrouter *router) 594 : { 595 : int ret; 596 : 597 53 : ret = vr_malloc_stats_init(router); 598 53 : if (ret) 599 0 : return ret; 600 : 601 53 : return vr_pkt_drop_stats_init(router); 602 : }