From c148a61b391289ee6e76d63d3ca0a2e2a17f3325 Mon Sep 17 00:00:00 2001 From: Whi copybara merger Date: Fri, 10 Mar 2023 07:03:19 +0000 Subject: [Copybara Auto Merge] Merge branch pro into android13-gs-pixel-5.10-udc edgetpu: usage_stats send metrics v2 requests with v1 fallback Bug: 271372136 edgetpu: usage stats: sync additional metrics v2 changes Bug: 271372136 (repeat) GitOrigin-RevId: af7a954e7f7903ae5c1dcdf6f24f48d9c1ae517c Change-Id: Ie8f815636eaaf818338a1573668725b37bc6de45 --- drivers/edgetpu/edgetpu-firmware.c | 10 ++++++--- drivers/edgetpu/edgetpu-kci.c | 13 +++++++++-- drivers/edgetpu/edgetpu-kci.h | 5 ++++- drivers/edgetpu/edgetpu-usage-stats.c | 42 ++++++++++++++++++++++++++--------- drivers/edgetpu/edgetpu-usage-stats.h | 16 ++++++++----- 5 files changed, 65 insertions(+), 21 deletions(-) diff --git a/drivers/edgetpu/edgetpu-firmware.c b/drivers/edgetpu/edgetpu-firmware.c index cf9009b..ad27ec9 100644 --- a/drivers/edgetpu/edgetpu-firmware.c +++ b/drivers/edgetpu/edgetpu-firmware.c @@ -478,20 +478,21 @@ int edgetpu_firmware_run_locked(struct edgetpu_firmware *et_fw, enum edgetpu_firmware_flags flags) { const struct edgetpu_firmware_chip_data *chip_fw = et_fw->p->chip_fw; + struct edgetpu_dev *etdev = et_fw->etdev; struct edgetpu_firmware_desc new_fw_desc; int ret; bool is_bl1_run = (flags & FW_BL1); edgetpu_firmware_set_loading(et_fw); if (!is_bl1_run) - edgetpu_sw_wdt_stop(et_fw->etdev); + edgetpu_sw_wdt_stop(etdev); memset(&new_fw_desc, 0, sizeof(new_fw_desc)); ret = edgetpu_firmware_load_locked(et_fw, &new_fw_desc, name, flags); if (ret) goto out_failed; - etdev_dbg(et_fw->etdev, "run fw %s flags=%#x", name, flags); + etdev_dbg(etdev, "run fw %s flags=%#x", name, flags); if (chip_fw->prepare_run) { /* Note this may recursively call us to run BL1 */ ret = chip_fw->prepare_run(et_fw, &new_fw_desc.buf); @@ -516,13 +517,16 @@ int edgetpu_firmware_run_locked(struct edgetpu_firmware *et_fw, /* Don't start wdt if loaded firmware is second stage bootloader. */ if (!ret && !is_bl1_run && et_fw->p->fw_info.fw_flavor != FW_FLAVOR_BL1) - edgetpu_sw_wdt_start(et_fw->etdev); + edgetpu_sw_wdt_start(etdev); if (!ret && !is_bl1_run && chip_fw->launch_complete) chip_fw->launch_complete(et_fw); else if (ret && chip_fw->launch_failed) chip_fw->launch_failed(et_fw, ret); edgetpu_firmware_set_state(et_fw, ret); + /* If previous firmware was metrics v1-only reset that flag and probe this again. */ + if (etdev->usage_stats) + etdev->usage_stats->use_metrics_v1 = false; return ret; out_unload_new_fw: diff --git a/drivers/edgetpu/edgetpu-kci.c b/drivers/edgetpu/edgetpu-kci.c index 65c16ec..fd52c3c 100644 --- a/drivers/edgetpu/edgetpu-kci.c +++ b/drivers/edgetpu/edgetpu-kci.c @@ -934,7 +934,7 @@ int edgetpu_kci_update_usage_locked(struct edgetpu_dev *etdev) { #define EDGETPU_USAGE_BUFFER_SIZE 4096 struct edgetpu_command_element cmd = { - .code = KCI_CODE_GET_USAGE, + .code = KCI_CODE_GET_USAGE_V2, .dma = { .address = 0, .size = 0, @@ -954,13 +954,22 @@ int edgetpu_kci_update_usage_locked(struct edgetpu_dev *etdev) return ret; } + /* TODO(b/271372136): remove v1 when v1 firmware no longer in use. */ +retry_v1: + if (etdev->usage_stats && etdev->usage_stats->use_metrics_v1) + cmd.code = KCI_CODE_GET_USAGE_V1; cmd.dma.address = mem.tpu_addr; cmd.dma.size = EDGETPU_USAGE_BUFFER_SIZE; memset(mem.vaddr, 0, sizeof(struct edgetpu_usage_header)); ret = edgetpu_kci_send_cmd_return_resp(etdev->kci, &cmd, &resp); - if (ret == KCI_ERROR_UNIMPLEMENTED || ret == KCI_ERROR_UNAVAILABLE) + if (ret == KCI_ERROR_UNIMPLEMENTED || ret == KCI_ERROR_UNAVAILABLE) { + if (etdev->usage_stats && !etdev->usage_stats->use_metrics_v1) { + etdev->usage_stats->use_metrics_v1 = true; + goto retry_v1; + } etdev_dbg(etdev, "firmware does not report usage\n"); + } else if (ret == KCI_ERROR_OK) edgetpu_usage_stats_process_buffer(etdev, mem.vaddr); else if (ret != -ETIMEDOUT) diff --git a/drivers/edgetpu/edgetpu-kci.h b/drivers/edgetpu/edgetpu-kci.h index b32b097..4d2f4b0 100644 --- a/drivers/edgetpu/edgetpu-kci.h +++ b/drivers/edgetpu/edgetpu-kci.h @@ -112,11 +112,14 @@ enum edgetpu_kci_code { KCI_CODE_OPEN_DEVICE = 9, KCI_CODE_CLOSE_DEVICE = 10, KCI_CODE_FIRMWARE_INFO = 11, - KCI_CODE_GET_USAGE = 12, + /* TODO(b/271372136): remove v1 when v1 firmware no longer in use. */ + KCI_CODE_GET_USAGE_V1 = 12, KCI_CODE_NOTIFY_THROTTLING = 13, KCI_CODE_BLOCK_BUS_SPEED_CONTROL = 14, /* 15..18 not implemented in this branch */ KCI_CODE_FIRMWARE_TRACING_LEVEL = 19, + /* 20 not implemented in this branch */ + KCI_CODE_GET_USAGE_V2 = 21, KCI_CODE_RKCI_ACK = 256, }; diff --git a/drivers/edgetpu/edgetpu-usage-stats.c b/drivers/edgetpu/edgetpu-usage-stats.c index e7b224c..60751dd 100644 --- a/drivers/edgetpu/edgetpu-usage-stats.c +++ b/drivers/edgetpu/edgetpu-usage-stats.c @@ -241,23 +241,44 @@ out: void edgetpu_usage_stats_process_buffer(struct edgetpu_dev *etdev, void *buf) { - struct edgetpu_usage_header_v1 *header = buf; - struct edgetpu_usage_metric *metric = - (struct edgetpu_usage_metric *)(header + 1); + struct edgetpu_usage_stats *ustats = etdev->usage_stats; + struct edgetpu_usage_metric *metric; + uint metric_size; + uint num_metrics; + uint version; int i; - etdev_dbg(etdev, "%s: n=%u sz=%u", __func__, - header->num_metrics, header->metric_size); - if (header->metric_size < EDGETPU_USAGE_METRIC_SIZE_V1) { + if (!ustats) + return; + + /* TODO(b/271372136): remove v1 when v1 firmware no longer in use. */ + if (ustats->use_metrics_v1) { + struct edgetpu_usage_header_v1 *header = buf; + + metric_size = header->metric_size; + num_metrics = header->num_metrics; + version = 1; + metric = (struct edgetpu_usage_metric *)(header + 1); + } else { + struct edgetpu_usage_header *header = buf; + + metric_size = header->metric_size; + num_metrics = header->num_metrics; + version = header->version; + metric = (struct edgetpu_usage_metric *)((char *)header + header->header_bytes); + } + + etdev_dbg(etdev, "%s: v=%u n=%u sz=%u", __func__, version, num_metrics, metric_size); + if (metric_size < EDGETPU_USAGE_METRIC_SIZE_V1) { etdev_warn_once(etdev, "fw metric size %u less than minimum %u", - header->metric_size, EDGETPU_USAGE_METRIC_SIZE_V1); + metric_size, EDGETPU_USAGE_METRIC_SIZE_V1); return; } - if (header->metric_size > sizeof(struct edgetpu_usage_metric)) + if (metric_size > sizeof(struct edgetpu_usage_metric)) etdev_dbg(etdev, "fw metrics are later version with unknown fields"); - for (i = 0; i < header->num_metrics; i++) { + for (i = 0; i < num_metrics; i++) { switch (metric->type) { case EDGETPU_METRIC_TYPE_TPU_USAGE: edgetpu_usage_add(etdev, &metric->tpu_usage); @@ -287,7 +308,7 @@ void edgetpu_usage_stats_process_buffer(struct edgetpu_dev *etdev, void *buf) break; } - metric = (struct edgetpu_usage_metric *)((char *)metric + header->metric_size); + metric = (struct edgetpu_usage_metric *)((char *)metric + metric_size); } } @@ -915,6 +936,7 @@ static struct attribute *usage_stats_dev_attrs[] = { static const struct attribute_group usage_stats_attr_group = { .attrs = usage_stats_dev_attrs, }; + void edgetpu_usage_stats_init(struct edgetpu_dev *etdev) { struct edgetpu_usage_stats *ustats; diff --git a/drivers/edgetpu/edgetpu-usage-stats.h b/drivers/edgetpu/edgetpu-usage-stats.h index 9d93122..ee908e1 100644 --- a/drivers/edgetpu/edgetpu-usage-stats.h +++ b/drivers/edgetpu/edgetpu-usage-stats.h @@ -11,7 +11,7 @@ #include /* The highest version of usage metrics handled by this driver. */ -#define EDGETPU_USAGE_METRIC_VERSION 1 +#define EDGETPU_USAGE_METRIC_VERSION 2 /* * Size in bytes of usage metric v1. @@ -66,9 +66,12 @@ struct tpu_usage { enum edgetpu_usage_component { /* The device as a whole */ EDGETPU_USAGE_COMPONENT_DEVICE = 0, - /* Just the TPU core */ + /* Just the TPU core (scalar core and tiles) */ EDGETPU_USAGE_COMPONENT_TPU = 1, - EDGETPU_USAGE_COMPONENT_COUNT = 2, /* number of components above */ + /* Control core (ARM Cortex-R52 CPU) */ + EDGETPU_USAGE_COMPONENT_CONTROLCORE = 2, + + EDGETPU_USAGE_COMPONENT_COUNT = 3, /* number of components above */ }; /* @@ -169,10 +172,11 @@ struct __packed edgetpu_usage_max_watermark { /* An enum to identify the tracked firmware threads. */ /* Must be kept in sync with firmware enum class UsageTrackerThreadId. */ enum edgetpu_usage_threadid { - /* Individual thread IDs are not tracked. */ + /* Individual thread IDs do not have identifiers assigned. */ + /* Thread ID 14, used for other IP, is not used for TPU */ /* Number of task identifiers. */ - EDGETPU_FW_THREAD_COUNT = 12, + EDGETPU_FW_THREAD_COUNT = 14, }; /* Statistics related to a single thread in firmware. */ @@ -216,6 +220,8 @@ struct edgetpu_usage_metric { #define UID_HASH_BITS 3 struct edgetpu_usage_stats { + /* if true the current firmware only implements metrics V1 */ + bool use_metrics_v1; DECLARE_HASHTABLE(uid_hash_table, UID_HASH_BITS); /* component utilization values reported by firmware */ int32_t component_utilization[EDGETPU_USAGE_COMPONENT_COUNT]; -- cgit v1.2.3