Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
integrate Idol-generated API client counters (#1642)
As of oxidecomputer/idolatry#43, Idol code-generation has grown the ability to automatically generate counters of IPC operations when generating client and server stubs. This branch integrates this feature with Hubris' existing IPC APIs. Idolatry codegen is capable of generating counters in both IPC client stubs and server stubs. This branch enables client-side counter generation only, because after experimenting with this feature, I've realized that generating counters on the client side lets us do substantially more interesting things with IPC count data: we can break down the total number of IPC requests by client, without requiring complex dynamic tracking of client IDs in the server task. Instead, when clients count their IPC requests, each client has its own version of the counters. We can sum them to determine the total number of IPCs, but we can also break them down per-client very easily, because...they're already broken down per-client. Because counting IPC operations and their return values requires a bit of RAM in each client task, I've exposed it as a feature flag in the client tasks, so it can be enabled or disabled in an `app.toml`, rather than in the client task's dependency on the API crate. This way, the boards with more RAM can enable counters, but we can leave them disabled in the small demo apps. This feature flag controls whether `idol` generates the counters or not, so adding feature flags to the client tasks required some of them to add their own build deps on `idol` to enable the feature. All the counters added in this branch can be read using the existing `humility counters` command. An upcoming Humility PR will also add a `humility counters --ipc` option, for grouping counters by IPC interface rather than displaying each client's IPC counters separately. Here's an example of the cool new `humility counters --ipc` command (coming soon to a Humility near you!), from a Gimlet `rev-c-lab` dump: ```console $ humility counters --ipc sys_api humility: attached to dump drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS 135574 Sys::gpio_set_reset() 135316 +---> [spi2_driver] 220 +---> [i2c_driver] 15 +---> [gimlet_seq] 10 +---> [hf] 8 +---> [net] 3 +---> [host_sp_comms] 1 +---> [sprot] 1 +---> [user_leds] 16832 Sys::gpio_read_input() 16796 +---> [gimlet_seq] 36 +---> [i2c_driver] 6351 Sys::gpio_configure_raw() 6284 +---> [i2c_driver] 24 +---> [spi2_driver] 14 +---> [gimlet_seq] 13 +---> [net] 6 +---> [hf] 4 +---> [sprot] 2 +---> [spd] 2 +---> [host_sp_comms] 1 +---> [control_plane_agent] 1 +---> [user_leds] 14 Sys::enable_clock_raw() 14 +---> Ok 4 | +---> [net] 3 | +---> [i2c_driver] 1 | +---> [spi2_driver] 1 | +---> [spd] 1 | +---> [hash_driver] 1 | +---> [hf] 1 | +---> [host_sp_comms] 1 | +---> [control_plane_agent] 1 | +---> [sprot] 12 Sys::leave_reset_raw() 12 +---> Ok 3 | +---> [i2c_driver] 2 | +---> [net] 1 | +---> [spi2_driver] 1 | +---> [spd] 1 | +---> [hash_driver] 1 | +---> [hf] 1 | +---> [host_sp_comms] 1 | +---> [control_plane_agent] 1 | +---> [sprot] 5 Sys::enter_reset_raw() 5 +---> Ok 2 | +---> [net] 1 | +---> [spi2_driver] 1 | +---> [hash_driver] 1 | +---> [sprot] 1 Sys::disable_clock_raw() 1 +---> Ok [hash_driver] 1 Sys::read_uid() 1 +---> [host_sp_comms] ``` And, some longer samples of humility output, hidden for conciseness: <details> <summary>`humility counters --list`</summary> ```console $ humility -d hubris.c12.autocounts.core.4 counters --list humility: attached to dump control_plane_agent: ADDR SIZE VARIABLE 0x240343d8 616 drv_gimlet_hf_api::__HOSTFLASH_CLIENT_COUNTERS 0x24034640 248 drv_gimlet_seq_api::__SEQUENCER_CLIENT_COUNTERS 0x24034738 4836 drv_sprot_api::__SPROT_CLIENT_COUNTERS 0x24035a1c 580 drv_stm32h7_update_api::__UPDATE_CLIENT_COUNTERS 0x24035c60 56 drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS 0x24035c98 32 drv_user_leds_api::__USERLEDS_CLIENT_COUNTERS 0x24033940 664 task_control_plane_agent::CRITICAL 0x24031000 1280 task_control_plane_agent::__RINGBUF 0x24035cb8 576 task_jefe_api::__JEFE_CLIENT_COUNTERS 0x24035ef8 220 task_net_api::__NET_CLIENT_COUNTERS 0x24035fd4 56 task_packrat_api::__PACKRAT_CLIENT_COUNTERS 0x2403600c 160 task_sensor_api::__SENSOR_CLIENT_COUNTERS 0x240360ac 32 task_validate_api::__VALIDATE_CLIENT_COUNTERS 0x240360cc 344 task_vpd_api::__VPD_CLIENT_COUNTERS dump_agent: ADDR SIZE VARIABLE 0x240413b4 4836 drv_sprot_api::__SPROT_CLIENT_COUNTERS 0x24042698 576 task_jefe_api::__JEFE_CLIENT_COUNTERS 0x240428d8 220 task_net_api::__NET_CLIENT_COUNTERS gimlet_inspector: ADDR SIZE VARIABLE 0x2405464c 248 drv_gimlet_seq_api::__SEQUENCER_CLIENT_COUNTERS 0x24054640 12 task_gimlet_inspector::__COUNTERS 0x24054744 220 task_net_api::__NET_CLIENT_COUNTERS gimlet_seq: ADDR SIZE VARIABLE 0x2404b43c 616 drv_gimlet_hf_api::__HOSTFLASH_CLIENT_COUNTERS 0x2404a640 3472 drv_gimlet_seq_server::__RINGBUF 0x2404b8f0 100 drv_spi_api::__SPI_CLIENT_COUNTERS 0x2404b954 56 drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS 0x2404b98c 576 task_jefe_api::__JEFE_CLIENT_COUNTERS 0x2404bbcc 56 task_packrat_api::__PACKRAT_CLIENT_COUNTERS hash_driver: ADDR SIZE VARIABLE 0x24053800 56 drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS hf: ADDR SIZE VARIABLE 0x24052bb8 96 drv_hash_api::__HASH_CLIENT_COUNTERS 0x24052c18 56 drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS hiffy: ADDR SIZE VARIABLE 0x2400ec20 616 drv_gimlet_hf_api::__HOSTFLASH_CLIENT_COUNTERS 0x2400ee88 96 drv_hash_api::__HASH_CLIENT_COUNTERS 0x2400eee8 100 drv_spi_api::__SPI_CLIENT_COUNTERS 0x2400ef4c 56 drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS host_sp_comms: ADDR SIZE VARIABLE 0x24027c9c 616 drv_gimlet_hf_api::__HOSTFLASH_CLIENT_COUNTERS 0x24027f04 248 drv_gimlet_seq_api::__SEQUENCER_CLIENT_COUNTERS 0x24027ffc 100 drv_spi_api::__SPI_CLIENT_COUNTERS 0x24028060 56 drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS 0x240281a4 180 task_control_plane_agent_api::__CONTROLPLANEAGENT_CLIENT_COUNTERS 0x24028258 220 task_net_api::__NET_CLIENT_COUNTERS 0x24028334 56 task_packrat_api::__PACKRAT_CLIENT_COUNTERS i2c_driver: ADDR SIZE VARIABLE 0x24056ec0 56 drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS net: ADDR SIZE VARIABLE 0x24019628 100 drv_spi_api::__SPI_CLIENT_COUNTERS 0x2401968c 56 drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS 0x240197d0 576 task_jefe_api::__JEFE_CLIENT_COUNTERS 0x24019a10 56 task_packrat_api::__PACKRAT_CLIENT_COUNTERS power: ADDR SIZE VARIABLE 0x24045f1c 248 drv_gimlet_seq_api::__SEQUENCER_CLIENT_COUNTERS 0x24046014 160 task_sensor_api::__SENSOR_CLIENT_COUNTERS spd: ADDR SIZE VARIABLE 0x24057798 56 drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS 0x240577d0 576 task_jefe_api::__JEFE_CLIENT_COUNTERS 0x24057a10 56 task_packrat_api::__PACKRAT_CLIENT_COUNTERS spi2_driver: ADDR SIZE VARIABLE 0x24055774 56 drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS sprot: ADDR SIZE VARIABLE 0x2403d318 56 drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS sys: ADDR SIZE VARIABLE 0x24059b80 576 task_jefe_api::__JEFE_CLIENT_COUNTERS thermal: ADDR SIZE VARIABLE 0x24003d70 248 drv_gimlet_seq_api::__SEQUENCER_CLIENT_COUNTERS 0x24003e68 160 task_sensor_api::__SENSOR_CLIENT_COUNTERS 0x240039e0 912 task_thermal::__RINGBUF udpbroadcast: ADDR SIZE VARIABLE 0x24058800 220 task_net_api::__NET_CLIENT_COUNTERS 0x240588dc 56 task_packrat_api::__PACKRAT_CLIENT_COUNTERS udpecho: ADDR SIZE VARIABLE 0x2404d004 220 task_net_api::__NET_CLIENT_COUNTERS user_leds: ADDR SIZE VARIABLE 0x2405ab80 56 drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS ``` </details> <details> <summary>`humility counters __SYS_CLIENT_COUNTERS`</summary> ```console $ humility -d hubris.c12.autocounts.core.4 counters __SYS_CLIENT_COUNTERS humility: attached to dump control_plane_agent | +---> drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS: 1 enable_clock_raw(Ok) 1 leave_reset_raw(Ok) 1 gpio_configure_raw gimlet_seq | +---> drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS: 16796 gpio_read_input 15 gpio_set_reset 14 gpio_configure_raw hash_driver | +---> drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS: 1 enable_clock_raw(Ok) 1 disable_clock_raw(Ok) 1 enter_reset_raw(Ok) 1 leave_reset_raw(Ok) hf | +---> drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS: 10 gpio_set_reset 6 gpio_configure_raw 1 enable_clock_raw(Ok) 1 leave_reset_raw(Ok) hiffy | +---> drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS: <no counts recorded> host_sp_comms | +---> drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS: 3 gpio_set_reset 2 gpio_configure_raw 1 enable_clock_raw(Ok) 1 leave_reset_raw(Ok) 1 read_uid i2c_driver | +---> drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS: 6284 gpio_configure_raw 220 gpio_set_reset 36 gpio_read_input 3 enable_clock_raw(Ok) 3 leave_reset_raw(Ok) net | +---> drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS: 13 gpio_configure_raw 8 gpio_set_reset 4 enable_clock_raw(Ok) 2 enter_reset_raw(Ok) 2 leave_reset_raw(Ok) spd | +---> drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS: 2 gpio_configure_raw 1 enable_clock_raw(Ok) 1 leave_reset_raw(Ok) spi2_driver | +---> drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS: 135316 gpio_set_reset 24 gpio_configure_raw 1 enable_clock_raw(Ok) 1 enter_reset_raw(Ok) 1 leave_reset_raw(Ok) sprot | +---> drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS: 4 gpio_configure_raw 1 enable_clock_raw(Ok) 1 enter_reset_raw(Ok) 1 leave_reset_raw(Ok) 1 gpio_set_reset user_leds | +---> drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS: 1 gpio_configure_raw 1 gpio_set_reset ``` </details> <details> <summary>`humility counters --ipc`</summary> ```console $ humility counters --ipc humility: attached to dump drv_gimlet_hf_api::__HOSTFLASH_CLIENT_COUNTERS 6 HostFlash::get_mux() 6 +---> Ok [host_sp_comms] 2 HostFlash::set_mux() 2 +---> Ok 1 | +---> [gimlet_seq] 1 | +---> [host_sp_comms] 1 HostFlash::get_dev() 1 +---> Ok [host_sp_comms] drv_gimlet_seq_api::__SEQUENCER_CLIENT_COUNTERS 2017 Sequencer::get_state() 2017 +---> Ok 1386 | +---> [thermal] 626 | +---> [power] 5 | +---> [host_sp_comms] drv_spi_api::__SPI_CLIENT_COUNTERS 67589 Spi::exchange() 67589 +---> Ok 67580 | +---> [gimlet_seq] 8 | +---> [net] 1 | +---> [host_sp_comms] 592 Spi::write() 592 +---> Ok 530 | +---> [gimlet_seq] 62 | +---> [net] 4 Spi::lock() 4 +---> Ok [gimlet_seq] 1 Spi::release() 1 +---> Ok [gimlet_seq] drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS 135574 Sys::gpio_set_reset() 135316 +---> [spi2_driver] 220 +---> [i2c_driver] 15 +---> [gimlet_seq] 10 +---> [hf] 8 +---> [net] 3 +---> [host_sp_comms] 1 +---> [sprot] 1 +---> [user_leds] 16832 Sys::gpio_read_input() 16796 +---> [gimlet_seq] 36 +---> [i2c_driver] 6351 Sys::gpio_configure_raw() 6284 +---> [i2c_driver] 24 +---> [spi2_driver] 14 +---> [gimlet_seq] 13 +---> [net] 6 +---> [hf] 4 +---> [sprot] 2 +---> [spd] 2 +---> [host_sp_comms] 1 +---> [control_plane_agent] 1 +---> [user_leds] 14 Sys::enable_clock_raw() 14 +---> Ok 4 | +---> [net] 3 | +---> [i2c_driver] 1 | +---> [spi2_driver] 1 | +---> [spd] 1 | +---> [hash_driver] 1 | +---> [hf] 1 | +---> [host_sp_comms] 1 | +---> [control_plane_agent] 1 | +---> [sprot] 12 Sys::leave_reset_raw() 12 +---> Ok 3 | +---> [i2c_driver] 2 | +---> [net] 1 | +---> [spi2_driver] 1 | +---> [spd] 1 | +---> [hash_driver] 1 | +---> [hf] 1 | +---> [host_sp_comms] 1 | +---> [control_plane_agent] 1 | +---> [sprot] 5 Sys::enter_reset_raw() 5 +---> Ok 2 | +---> [net] 1 | +---> [spi2_driver] 1 | +---> [hash_driver] 1 | +---> [sprot] 1 Sys::disable_clock_raw() 1 +---> Ok [hash_driver] 1 Sys::read_uid() 1 +---> [host_sp_comms] task_jefe_api::__JEFE_CLIENT_COUNTERS 5 Jefe::set_state() 5 +---> [gimlet_seq] 4 Jefe::get_state() 2 +---> [net] 2 +---> [spd] 1 Jefe::set_reset_reason() 1 +---> [sys] task_net_api::__NET_CLIENT_COUNTERS 1380 Net::send_packet() 1380 +---> Ok [udpbroadcast] 3 Net::recv_packet() 3 +---> Err(QueueEmpty) 1 | +---> [gimlet_inspector] 1 | +---> [udpecho] 1 | +---> [dump_agent] 2 Net::get_mac_address() 1 +---> [udpbroadcast] 1 +---> [control_plane_agent] 1 Net::get_spare_mac_addresses() 1 +---> [host_sp_comms] task_packrat_api::__PACKRAT_CLIENT_COUNTERS 9280 Packrat::get_spd_data() 9280 +---> [spd] 4656 Packrat::get_spd_present() 4640 +---> [spd] 16 +---> [host_sp_comms] 32 Packrat::set_spd_eeprom() 32 +---> [gimlet_seq] 16 Packrat::get_full_spd_data() 16 +---> [host_sp_comms] 8 Packrat::get_identity() 8 +---> Ok 7 | +---> [host_sp_comms] 1 | +---> [udpbroadcast] 1 Packrat::get_mac_address_block() 1 +---> Ok [net] 1 Packrat::set_mac_address_block() 1 +---> Ok [gimlet_seq] 1 Packrat::set_identity() 1 +---> Ok [gimlet_seq] 1 Packrat::get_next_boot_host_startup_options() 1 +---> [host_sp_comms] task_sensor_api::__SENSOR_CLIENT_COUNTERS 76717 Sensor::post() 76717 +---> Ok 50300 | +---> [power] 26417 | +---> [thermal] 19804 Sensor::get_reading() 18101 +---> Ok [thermal] 1703 +---> Err(_) 1701 | +---> Err(NotPresent) [thermal] 2 | +---> Err(DeviceError) [thermal] 6225 Sensor::nodata() 6225 +---> Ok 3536 | +---> [power] 2689 | +---> [thermal] ``` </details> <details> <summary>`humility counters --ipc --full sys_api</summary> ```console $ humility counters --ipc --full sys_api humility: attached to dump drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS 14 Sys::enable_clock_raw() 14 +---> Ok 4 | +---> [net] 1 | +---> [spi2_driver] 3 | +---> [i2c_driver] 1 | +---> [spd] 0 | +---> [hiffy] 0 | +---> [gimlet_seq] 1 | +---> [hash_driver] 1 | +---> [hf] 1 | +---> [host_sp_comms] 1 | +---> [control_plane_agent] 1 | +---> [sprot] 0 | +---> [user_leds] 0 | +---> Err(NoSuchPeripheral) 0 | | +---> [net] 0 | | +---> [spi2_driver] 0 | | +---> [i2c_driver] 0 | | +---> [spd] 0 | | +---> [hiffy] 0 | | +---> [gimlet_seq] 0 | | +---> [hash_driver] 0 | | +---> [hf] 0 | | +---> [host_sp_comms] 0 | | +---> [control_plane_agent] 0 | | +---> [sprot] 0 | | +---> [user_leds] 1 Sys::disable_clock_raw() 1 +---> Ok 0 | +---> [net] 0 | +---> [spi2_driver] 0 | +---> [i2c_driver] 0 | +---> [spd] 0 | +---> [hiffy] 0 | +---> [gimlet_seq] 1 | +---> [hash_driver] 0 | +---> [hf] 0 | +---> [host_sp_comms] 0 | +---> [control_plane_agent] 0 | +---> [sprot] 0 | +---> [user_leds] 0 | +---> Err(NoSuchPeripheral) 0 | | +---> [net] 0 | | +---> [spi2_driver] 0 | | +---> [i2c_driver] 0 | | +---> [spd] 0 | | +---> [hiffy] 0 | | +---> [gimlet_seq] 0 | | +---> [hash_driver] 0 | | +---> [hf] 0 | | +---> [host_sp_comms] 0 | | +---> [control_plane_agent] 0 | | +---> [sprot] 0 | | +---> [user_leds] 5 Sys::enter_reset_raw() 5 +---> Ok 2 | +---> [net] 1 | +---> [spi2_driver] 0 | +---> [i2c_driver] 0 | +---> [spd] 0 | +---> [hiffy] 0 | +---> [gimlet_seq] 1 | +---> [hash_driver] 0 | +---> [hf] 0 | +---> [host_sp_comms] 0 | +---> [control_plane_agent] 1 | +---> [sprot] 0 | +---> [user_leds] 0 | +---> Err(NoSuchPeripheral) 0 | | +---> [net] 0 | | +---> [spi2_driver] 0 | | +---> [i2c_driver] 0 | | +---> [spd] 0 | | +---> [hiffy] 0 | | +---> [gimlet_seq] 0 | | +---> [hash_driver] 0 | | +---> [hf] 0 | | +---> [host_sp_comms] 0 | | +---> [control_plane_agent] 0 | | +---> [sprot] 0 | | +---> [user_leds] 12 Sys::leave_reset_raw() 12 +---> Ok 2 | +---> [net] 1 | +---> [spi2_driver] 3 | +---> [i2c_driver] 1 | +---> [spd] 0 | +---> [hiffy] 0 | +---> [gimlet_seq] 1 | +---> [hash_driver] 1 | +---> [hf] 1 | +---> [host_sp_comms] 1 | +---> [control_plane_agent] 1 | +---> [sprot] 0 | +---> [user_leds] 0 | +---> Err(NoSuchPeripheral) 0 | | +---> [net] 0 | | +---> [spi2_driver] 0 | | +---> [i2c_driver] 0 | | +---> [spd] 0 | | +---> [hiffy] 0 | | +---> [gimlet_seq] 0 | | +---> [hash_driver] 0 | | +---> [hf] 0 | | +---> [host_sp_comms] 0 | | +---> [control_plane_agent] 0 | | +---> [sprot] 0 | | +---> [user_leds] 6351 Sys::gpio_configure_raw() 13 +---> [net] 24 +---> [spi2_driver] 6284 +---> [i2c_driver] 2 +---> [spd] 0 +---> [hiffy] 14 +---> [gimlet_seq] 0 +---> [hash_driver] 6 +---> [hf] 2 +---> [host_sp_comms] 1 +---> [control_plane_agent] 4 +---> [sprot] 1 +---> [user_leds] 135574 Sys::gpio_set_reset() 8 +---> [net] 135316 +---> [spi2_driver] 220 +---> [i2c_driver] 0 +---> [spd] 0 +---> [hiffy] 15 +---> [gimlet_seq] 0 +---> [hash_driver] 10 +---> [hf] 3 +---> [host_sp_comms] 0 +---> [control_plane_agent] 1 +---> [sprot] 1 +---> [user_leds] 16832 Sys::gpio_read_input() 0 +---> [net] 0 +---> [spi2_driver] 36 +---> [i2c_driver] 0 +---> [spd] 0 +---> [hiffy] 16796 +---> [gimlet_seq] 0 +---> [hash_driver] 0 +---> [hf] 0 +---> [host_sp_comms] 0 +---> [control_plane_agent] 0 +---> [sprot] 0 +---> [user_leds] 1 Sys::read_uid() 0 +---> [net] 0 +---> [spi2_driver] 0 +---> [i2c_driver] 0 +---> [spd] 0 +---> [hiffy] 0 +---> [gimlet_seq] 0 +---> [hash_driver] 0 +---> [hf] 1 +---> [host_sp_comms] 0 +---> [control_plane_agent] 0 +---> [sprot] 0 +---> [user_leds] ``` </details>
- Loading branch information