aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Åstrand <per.astrand@arm.com>2020-10-23 21:25:05 +0200
committerPer Åstrand <per.astrand@arm.com>2020-11-16 13:57:35 +0100
commitf7e407a0fe58d76d54e3d1f9d2cb117036cd095b (patch)
tree8726e753f14c5a95d64312004c5117cf0e75b6d2
parentf8ae5e1f5ca090b37a701f9dd75ee57106d30dc8 (diff)
downloadethos-u-linux-driver-stack-f7e407a0fe58d76d54e3d1f9d2cb117036cd095b.tar.gz
Add PMU config to inference creation
Add PMU configuration information to inference creation. Change-Id: Id8a69517a5d3e4822dbaf46f76cadb2700b3d981
-rw-r--r--kernel/ethosu_core_interface.h9
-rw-r--r--kernel/ethosu_inference.c68
-rw-r--r--kernel/ethosu_inference.h26
-rw-r--r--kernel/ethosu_mailbox.c16
-rw-r--r--kernel/ethosu_mailbox.h5
-rw-r--r--kernel/uapi/ethosu.h49
6 files changed, 153 insertions, 20 deletions
diff --git a/kernel/ethosu_core_interface.h b/kernel/ethosu_core_interface.h
index 0dd1996..86e10ac 100644
--- a/kernel/ethosu_core_interface.h
+++ b/kernel/ethosu_core_interface.h
@@ -30,6 +30,9 @@
/** Maximum number of IFM/OFM buffers per inference */
#define ETHOSU_CORE_BUFFER_MAX 16
+/** Maximum number of PMU counters to be returned for inference */
+#define ETHOSU_CORE_PMU_MAX 4
+
/**
* enum ethosu_core_msg_type - Message types
*
@@ -87,6 +90,8 @@ struct ethosu_core_inference_req {
uint32_t ofm_count;
struct ethosu_core_buffer ofm[ETHOSU_CORE_BUFFER_MAX];
struct ethosu_core_buffer network;
+ uint8_t pmu_event_config[ETHOSU_CORE_PMU_MAX];
+ uint32_t pmu_cycle_counter_enable;
};
struct ethosu_core_inference_rsp {
@@ -94,6 +99,10 @@ struct ethosu_core_inference_rsp {
uint32_t ofm_count;
uint32_t ofm_size[ETHOSU_CORE_BUFFER_MAX];
uint32_t status;
+ uint8_t pmu_event_config[ETHOSU_CORE_PMU_MAX];
+ uint32_t pmu_event_count[ETHOSU_CORE_PMU_MAX];
+ uint32_t pmu_cycle_counter_enable;
+ uint64_t pmu_cycle_counter_count;
};
#endif
diff --git a/kernel/ethosu_inference.c b/kernel/ethosu_inference.c
index e9530cf..586ffca 100644
--- a/kernel/ethosu_inference.c
+++ b/kernel/ethosu_inference.c
@@ -89,7 +89,10 @@ static int ethosu_inference_send(struct ethosu_inference *inf)
ret = ethosu_mailbox_inference(&inf->edev->mailbox, inf,
inf->ifm_count, inf->ifm,
inf->ofm_count, inf->ofm,
- inf->net->buf);
+ inf->net->buf,
+ inf->pmu_event_config,
+ ETHOSU_PMU_EVENT_MAX,
+ inf->pmu_cycle_counter_enable);
if (ret)
return ret;
@@ -172,7 +175,8 @@ static long ethosu_inference_ioctl(struct file *file,
unsigned long arg)
{
struct ethosu_inference *inf = file->private_data;
- int ret = -EINVAL;
+ void __user *udata = (void __user *)arg;
+ int ret;
ret = mutex_lock_interruptible(&inf->edev->mutex);
if (ret)
@@ -182,11 +186,27 @@ static long ethosu_inference_ioctl(struct file *file,
switch (cmd) {
case ETHOSU_IOCTL_INFERENCE_STATUS: {
- ret = inf->status;
+ struct ethosu_uapi_result_status uapi;
+ int i;
+
+ uapi.status = inf->status;
+
+ for (i = 0; i < ETHOSU_PMU_EVENT_MAX; i++) {
+ uapi.pmu_config.events[i] =
+ inf->pmu_event_config[i];
+ uapi.pmu_count.events[i] =
+ inf->pmu_event_count[i];
+ }
+
+ uapi.pmu_config.cycle_count = inf->pmu_cycle_counter_enable;
+ uapi.pmu_count.cycle_count = inf->pmu_cycle_counter_count;
dev_info(inf->edev->dev,
"Ioctl: Inference status. status=%s (%d)\n",
- status_to_string(ret), ret);
+ status_to_string(uapi.status), uapi.status);
+
+ ret = copy_to_user(udata, &uapi, sizeof(uapi)) ? -EFAULT : 0;
+
break;
}
default: {
@@ -243,6 +263,25 @@ int ethosu_inference_create(struct ethosu_device *edev,
inf->ofm_count++;
}
+ /* Configure PMU and cycle counter */
+ dev_info(inf->edev->dev,
+ "Configuring events for PMU. events=[%u, %u, %u, %u]\n",
+ uapi->pmu_config.events[0], uapi->pmu_config.events[1],
+ uapi->pmu_config.events[2], uapi->pmu_config.events[3]);
+
+ /* Configure events and reset count for all events */
+ for (i = 0; i < ETHOSU_PMU_EVENT_MAX; i++) {
+ inf->pmu_event_config[i] = uapi->pmu_config.events[i];
+ inf->pmu_event_count[i] = 0;
+ }
+
+ if (uapi->pmu_config.cycle_count)
+ dev_info(inf->edev->dev, "Enabling cycle counter\n");
+
+ /* Configure cycle counter and reset any previous count */
+ inf->pmu_cycle_counter_enable = uapi->pmu_config.cycle_count;
+ inf->pmu_cycle_counter_count = 0;
+
/* Increment network reference count */
ethosu_network_get(net);
@@ -321,6 +360,7 @@ void ethosu_inference_rsp(struct ethosu_device *edev,
struct ethosu_inference *inf =
(struct ethosu_inference *)rsp->user_arg;
int ret;
+ int i;
ret = ethosu_inference_find(inf, &edev->inference_list);
if (ret) {
@@ -352,6 +392,26 @@ void ethosu_inference_rsp(struct ethosu_device *edev,
inf->status = ETHOSU_UAPI_STATUS_ERROR;
}
+ for (i = 0; i < ETHOSU_CORE_PMU_MAX; i++) {
+ inf->pmu_event_config[i] = rsp->pmu_event_config[i];
+ inf->pmu_event_count[i] = rsp->pmu_event_count[i];
+ }
+
+ inf->pmu_cycle_counter_enable = rsp->pmu_cycle_counter_enable;
+ inf->pmu_cycle_counter_count = rsp->pmu_cycle_counter_count;
+
+ dev_info(edev->dev,
+ "PMU events. config=[%u, %u %u, %u], count=[%u, %u, %u, %u]\n",
+ inf->pmu_event_config[0], inf->pmu_event_count[0],
+ inf->pmu_event_config[1], inf->pmu_event_count[1],
+ inf->pmu_event_config[2], inf->pmu_event_count[2],
+ inf->pmu_event_config[3], inf->pmu_event_count[3]
+ );
+
+ dev_info(edev->dev,
+ "PMU cycle counter. enable=%u, count=%llu\n",
+ inf->pmu_cycle_counter_enable,
+ inf->pmu_cycle_counter_count);
wake_up_interruptible(&inf->waitq);
ethosu_inference_put(inf);
diff --git a/kernel/ethosu_inference.h b/kernel/ethosu_inference.h
index c0d8461..07370ca 100644
--- a/kernel/ethosu_inference.h
+++ b/kernel/ethosu_inference.h
@@ -44,15 +44,19 @@ struct file;
/**
* struct ethosu_inference - Inference struct
- * @edev: Arm Ethos-U device
- * @file: File handle
- * @kref: Reference counter
- * @waitq: Wait queue
- * @ifm: Pointer to IFM buffer
- * @ofm: Pointer to OFM buffer
- * @net: Pointer to network
- * @pending: Pending response from the firmware
- * @status: Inference status
+ * @edev: Arm Ethos-U device
+ * @file: File handle
+ * @kref: Reference counter
+ * @waitq: Wait queue
+ * @ifm: Pointer to IFM buffer
+ * @ofm: Pointer to OFM buffer
+ * @net: Pointer to network
+ * @pending: Pending response from the firmware
+ * @status: Inference status
+ * @pmu_event_config: PMU event configuration
+ * @pmu_event_count: PMU event count after inference
+ * @pmu_cycle_counter_enable: PMU cycle counter config
+ * @pmu_cycle_counter_count: PMU cycle counter count after inference
*/
struct ethosu_inference {
struct ethosu_device *edev;
@@ -66,6 +70,10 @@ struct ethosu_inference {
struct ethosu_network *net;
bool pending;
enum ethosu_uapi_status status;
+ uint8_t pmu_event_config[ETHOSU_PMU_EVENT_MAX];
+ uint32_t pmu_event_count[ETHOSU_PMU_EVENT_MAX];
+ uint32_t pmu_cycle_counter_enable;
+ uint64_t pmu_cycle_counter_count;
struct list_head list;
};
diff --git a/kernel/ethosu_mailbox.c b/kernel/ethosu_mailbox.c
index 47c4698..77b9614 100644
--- a/kernel/ethosu_mailbox.c
+++ b/kernel/ethosu_mailbox.c
@@ -175,14 +175,25 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
struct ethosu_buffer **ifm,
uint32_t ofm_count,
struct ethosu_buffer **ofm,
- struct ethosu_buffer *network)
+ struct ethosu_buffer *network,
+ uint8_t *pmu_event_config,
+ uint8_t pmu_event_config_count,
+ uint8_t pmu_cycle_counter_enable)
{
struct ethosu_core_inference_req inf;
uint32_t i;
+ /* Verify that the uapi and core has the same number of pmus */
+ if (pmu_event_config_count != ETHOSU_CORE_PMU_MAX) {
+ dev_err(mbox->dev, "PMU count misconfigured.\n");
+
+ return -EINVAL;
+ }
+
inf.user_arg = (ptrdiff_t)user_arg;
inf.ifm_count = ifm_count;
inf.ofm_count = ofm_count;
+ inf.pmu_cycle_counter_enable = pmu_cycle_counter_enable;
for (i = 0; i < ifm_count; i++)
ethosu_core_set_size(ifm[i], &inf.ifm[i]);
@@ -190,6 +201,9 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
for (i = 0; i < ofm_count; i++)
ethosu_core_set_capacity(ofm[i], &inf.ofm[i]);
+ for (i = 0; i < ETHOSU_CORE_PMU_MAX; i++)
+ inf.pmu_event_config[i] = pmu_event_config[i];
+
ethosu_core_set_size(network, &inf.network);
return ethosu_queue_write_msg(mbox, ETHOSU_CORE_MSG_INFERENCE_REQ,
diff --git a/kernel/ethosu_mailbox.h b/kernel/ethosu_mailbox.h
index 5a77b54..8f539ee 100644
--- a/kernel/ethosu_mailbox.h
+++ b/kernel/ethosu_mailbox.h
@@ -104,6 +104,9 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
struct ethosu_buffer **ifm,
uint32_t ofm_count,
struct ethosu_buffer **ofm,
- struct ethosu_buffer *network);
+ struct ethosu_buffer *network,
+ uint8_t *pmu_event_config,
+ uint8_t pmu_event_config_count,
+ uint8_t pmu_cycle_counter_enable);
#endif /* ETHOSU_MAILBOX_H */
diff --git a/kernel/uapi/ethosu.h b/kernel/uapi/ethosu.h
index d790db4..8f870c9 100644
--- a/kernel/uapi/ethosu.h
+++ b/kernel/uapi/ethosu.h
@@ -49,11 +49,15 @@
struct ethosu_uapi_network_create)
#define ETHOSU_IOCTL_INFERENCE_CREATE ETHOSU_IOR(0x30, \
struct ethosu_uapi_inference_create)
-#define ETHOSU_IOCTL_INFERENCE_STATUS ETHOSU_IO(0x31)
+#define ETHOSU_IOCTL_INFERENCE_STATUS ETHOSU_IOR(0x31, \
+ struct ethosu_uapi_result_status)
/* Maximum number of IFM/OFM file descriptors per network */
#define ETHOSU_FD_MAX 16
+/* Maximum number of PMUs available */
+#define ETHOSU_PMU_EVENT_MAX 4
+
/****************************************************************************
* Types
****************************************************************************/
@@ -95,6 +99,27 @@ struct ethosu_uapi_network_create {
};
/**
+ * struct ethosu_uapi_pmu_config - Configure performance counters
+ * @events: Array of counters to configure, set to non-zero for
+ * each counter to enable corresponding event.
+ * @cycle_count: Set to enable the cycle counter.
+ */
+struct ethosu_uapi_pmu_config {
+ __u32 events[ETHOSU_PMU_EVENT_MAX];
+ __u32 cycle_count;
+};
+
+/**
+ * struct ethosu_uapi_pmu_counts - Status of performance counters
+ * @events: Count for respective configured events.
+ * @cycle_count: Count for cycle counter.
+ */
+struct ethosu_uapi_pmu_counts {
+ __u32 events[ETHOSU_PMU_EVENT_MAX];
+ __u64 cycle_count;
+};
+
+/**
* struct ethosu_uapi_inference_create - Create network request
* @ifm_count: Number of IFM file descriptors
* @ifm_fd: IFM buffer file descriptors
@@ -102,10 +127,24 @@ struct ethosu_uapi_network_create {
* @ofm_fd: OFM buffer file descriptors
*/
struct ethosu_uapi_inference_create {
- __u32 ifm_count;
- __u32 ifm_fd[ETHOSU_FD_MAX];
- __u32 ofm_count;
- __u32 ofm_fd[ETHOSU_FD_MAX];
+ __u32 ifm_count;
+ __u32 ifm_fd[ETHOSU_FD_MAX];
+ __u32 ofm_count;
+ __u32 ofm_fd[ETHOSU_FD_MAX];
+ struct ethosu_uapi_pmu_config pmu_config;
+};
+
+/**
+ * struct ethosu_uapi_result_status - Status of inference
+ * @status Status of run inference.
+ * @pmu_config Configured performance counters.
+ * @pmu_count Perfomance counters values, when status is
+ * ETHOSU_UAPI_STATUS_OK.
+ */
+struct ethosu_uapi_result_status {
+ enum ethosu_uapi_status status;
+ struct ethosu_uapi_pmu_config pmu_config;
+ struct ethosu_uapi_pmu_counts pmu_count;
};
#endif