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