diff options
author | TeYuan Wang <kamewang@google.com> | 2021-08-05 22:30:03 +0800 |
---|---|---|
committer | TeYuan Wang <kamewang@google.com> | 2021-08-09 15:42:43 +0800 |
commit | 2d0d4e612e61743598241837bbc7912bc8b94474 (patch) | |
tree | a63d817ea82a671f084f33f1127d32fa581064de | |
parent | 23e7c6f5bebb9f80ab97bec076ee9ae626620af7 (diff) | |
download | edgetpu-2d0d4e612e61743598241837bbc7912bc8b94474.tar.gz |
edgetpu: add user_vote for user space request TPU throttling
For the current upstream design, userspace can request
cooling device via "cur_state" sysfs. However, the request
will be overwritten by other kernel governor or it will
overwrite other governor's request. So, create this user_vote
sysfs for userspace to request cooling device and vote with
other kernel governor's request.
Bug: 188701596
Test: build
Change-Id: I6ea5c1a5f5fdeb72f78f69fa7cc833f5f464d28e
Signed-off-by: TeYuan Wang <kamewang@google.com>
-rw-r--r-- | drivers/edgetpu/abrolhos-thermal.c | 45 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-thermal.h | 1 |
2 files changed, 45 insertions, 1 deletions
diff --git a/drivers/edgetpu/abrolhos-thermal.c b/drivers/edgetpu/abrolhos-thermal.c index a8a0016..6e7141f 100644 --- a/drivers/edgetpu/abrolhos-thermal.c +++ b/drivers/edgetpu/abrolhos-thermal.c @@ -78,6 +78,8 @@ static int edgetpu_set_cur_state(struct thermal_cooling_device *cdev, return -EINVAL; } + state_original = max(cooling->sysfs_req, state_original); + mutex_lock(&cooling->lock); pwr_state = state_pwr_map[state_original].state; if (state_original != cooling->cooling_state) { @@ -281,6 +283,46 @@ error: return -EINVAL; } +static ssize_t +user_vote_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct thermal_cooling_device *cdev = container_of(dev, struct thermal_cooling_device, device); + struct edgetpu_thermal *cooling = cdev->devdata; + + if (!cooling) + return -ENODEV; + + return sysfs_emit(buf, "%lu\n", cooling->sysfs_req); +} + +static ssize_t user_vote_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct thermal_cooling_device *cdev = container_of(dev, struct thermal_cooling_device, device); + struct edgetpu_thermal *cooling = cdev->devdata; + int ret; + unsigned long state; + + if (!cooling) + return -ENODEV; + + ret = kstrtoul(buf, 0, &state); + if (ret) + return ret; + + if (state >= cooling->tpu_num_states) + return -EINVAL; + + mutex_lock(&cdev->lock); + cooling->sysfs_req = state; + cdev->updated = false; + mutex_unlock(&cdev->lock); + thermal_cdev_update(cdev); + return count; +} + +static DEVICE_ATTR_RW(user_vote); + static int tpu_thermal_cooling_register(struct edgetpu_thermal *thermal, char *type) { @@ -304,7 +346,8 @@ tpu_thermal_cooling_register(struct edgetpu_thermal *thermal, char *type) cooling_node, type, thermal, &edgetpu_cooling_ops); if (IS_ERR(thermal->cdev)) return PTR_ERR(thermal->cdev); - return 0; + + return device_create_file(&thermal->cdev->device, &dev_attr_user_vote); } static int tpu_thermal_init(struct edgetpu_thermal *thermal, struct device *dev) diff --git a/drivers/edgetpu/edgetpu-thermal.h b/drivers/edgetpu/edgetpu-thermal.h index 8d4b23f..dbd283f 100644 --- a/drivers/edgetpu/edgetpu-thermal.h +++ b/drivers/edgetpu/edgetpu-thermal.h @@ -23,6 +23,7 @@ struct edgetpu_thermal { struct mutex lock; void *op_data; unsigned long cooling_state; + unsigned long sysfs_req; unsigned int tpu_num_states; struct edgetpu_dev *etdev; bool thermal_suspended; /* TPU thermal suspended state */ |