qos.c (17567B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Power Management Quality of Service (PM QoS) support base. 4 * 5 * Copyright (C) 2020 Intel Corporation 6 * 7 * Authors: 8 * Mark Gross <mgross@linux.intel.com> 9 * Rafael J. Wysocki <rafael.j.wysocki@intel.com> 10 * 11 * Provided here is an interface for specifying PM QoS dependencies. It allows 12 * entities depending on QoS constraints to register their requests which are 13 * aggregated as appropriate to produce effective constraints (target values) 14 * that can be monitored by entities needing to respect them, either by polling 15 * or through a built-in notification mechanism. 16 * 17 * In addition to the basic functionality, more specific interfaces for managing 18 * global CPU latency QoS requests and frequency QoS requests are provided. 19 */ 20 21/*#define DEBUG*/ 22 23#include <linux/pm_qos.h> 24#include <linux/sched.h> 25#include <linux/spinlock.h> 26#include <linux/slab.h> 27#include <linux/time.h> 28#include <linux/fs.h> 29#include <linux/device.h> 30#include <linux/miscdevice.h> 31#include <linux/string.h> 32#include <linux/platform_device.h> 33#include <linux/init.h> 34#include <linux/kernel.h> 35#include <linux/debugfs.h> 36#include <linux/seq_file.h> 37 38#include <linux/uaccess.h> 39#include <linux/export.h> 40#include <trace/events/power.h> 41 42/* 43 * locking rule: all changes to constraints or notifiers lists 44 * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock 45 * held, taken with _irqsave. One lock to rule them all 46 */ 47static DEFINE_SPINLOCK(pm_qos_lock); 48 49/** 50 * pm_qos_read_value - Return the current effective constraint value. 51 * @c: List of PM QoS constraint requests. 52 */ 53s32 pm_qos_read_value(struct pm_qos_constraints *c) 54{ 55 return READ_ONCE(c->target_value); 56} 57 58static int pm_qos_get_value(struct pm_qos_constraints *c) 59{ 60 if (plist_head_empty(&c->list)) 61 return c->no_constraint_value; 62 63 switch (c->type) { 64 case PM_QOS_MIN: 65 return plist_first(&c->list)->prio; 66 67 case PM_QOS_MAX: 68 return plist_last(&c->list)->prio; 69 70 default: 71 WARN(1, "Unknown PM QoS type in %s\n", __func__); 72 return PM_QOS_DEFAULT_VALUE; 73 } 74} 75 76static void pm_qos_set_value(struct pm_qos_constraints *c, s32 value) 77{ 78 WRITE_ONCE(c->target_value, value); 79} 80 81/** 82 * pm_qos_update_target - Update a list of PM QoS constraint requests. 83 * @c: List of PM QoS requests. 84 * @node: Target list entry. 85 * @action: Action to carry out (add, update or remove). 86 * @value: New request value for the target list entry. 87 * 88 * Update the given list of PM QoS constraint requests, @c, by carrying an 89 * @action involving the @node list entry and @value on it. 90 * 91 * The recognized values of @action are PM_QOS_ADD_REQ (store @value in @node 92 * and add it to the list), PM_QOS_UPDATE_REQ (remove @node from the list, store 93 * @value in it and add it to the list again), and PM_QOS_REMOVE_REQ (remove 94 * @node from the list, ignore @value). 95 * 96 * Return: 1 if the aggregate constraint value has changed, 0 otherwise. 97 */ 98int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, 99 enum pm_qos_req_action action, int value) 100{ 101 int prev_value, curr_value, new_value; 102 unsigned long flags; 103 104 spin_lock_irqsave(&pm_qos_lock, flags); 105 106 prev_value = pm_qos_get_value(c); 107 if (value == PM_QOS_DEFAULT_VALUE) 108 new_value = c->default_value; 109 else 110 new_value = value; 111 112 switch (action) { 113 case PM_QOS_REMOVE_REQ: 114 plist_del(node, &c->list); 115 break; 116 case PM_QOS_UPDATE_REQ: 117 /* 118 * To change the list, atomically remove, reinit with new value 119 * and add, then see if the aggregate has changed. 120 */ 121 plist_del(node, &c->list); 122 fallthrough; 123 case PM_QOS_ADD_REQ: 124 plist_node_init(node, new_value); 125 plist_add(node, &c->list); 126 break; 127 default: 128 /* no action */ 129 ; 130 } 131 132 curr_value = pm_qos_get_value(c); 133 pm_qos_set_value(c, curr_value); 134 135 spin_unlock_irqrestore(&pm_qos_lock, flags); 136 137 trace_pm_qos_update_target(action, prev_value, curr_value); 138 139 if (prev_value == curr_value) 140 return 0; 141 142 if (c->notifiers) 143 blocking_notifier_call_chain(c->notifiers, curr_value, NULL); 144 145 return 1; 146} 147 148/** 149 * pm_qos_flags_remove_req - Remove device PM QoS flags request. 150 * @pqf: Device PM QoS flags set to remove the request from. 151 * @req: Request to remove from the set. 152 */ 153static void pm_qos_flags_remove_req(struct pm_qos_flags *pqf, 154 struct pm_qos_flags_request *req) 155{ 156 s32 val = 0; 157 158 list_del(&req->node); 159 list_for_each_entry(req, &pqf->list, node) 160 val |= req->flags; 161 162 pqf->effective_flags = val; 163} 164 165/** 166 * pm_qos_update_flags - Update a set of PM QoS flags. 167 * @pqf: Set of PM QoS flags to update. 168 * @req: Request to add to the set, to modify, or to remove from the set. 169 * @action: Action to take on the set. 170 * @val: Value of the request to add or modify. 171 * 172 * Return: 1 if the aggregate constraint value has changed, 0 otherwise. 173 */ 174bool pm_qos_update_flags(struct pm_qos_flags *pqf, 175 struct pm_qos_flags_request *req, 176 enum pm_qos_req_action action, s32 val) 177{ 178 unsigned long irqflags; 179 s32 prev_value, curr_value; 180 181 spin_lock_irqsave(&pm_qos_lock, irqflags); 182 183 prev_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags; 184 185 switch (action) { 186 case PM_QOS_REMOVE_REQ: 187 pm_qos_flags_remove_req(pqf, req); 188 break; 189 case PM_QOS_UPDATE_REQ: 190 pm_qos_flags_remove_req(pqf, req); 191 fallthrough; 192 case PM_QOS_ADD_REQ: 193 req->flags = val; 194 INIT_LIST_HEAD(&req->node); 195 list_add_tail(&req->node, &pqf->list); 196 pqf->effective_flags |= val; 197 break; 198 default: 199 /* no action */ 200 ; 201 } 202 203 curr_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags; 204 205 spin_unlock_irqrestore(&pm_qos_lock, irqflags); 206 207 trace_pm_qos_update_flags(action, prev_value, curr_value); 208 209 return prev_value != curr_value; 210} 211 212#ifdef CONFIG_CPU_IDLE 213/* Definitions related to the CPU latency QoS. */ 214 215static struct pm_qos_constraints cpu_latency_constraints = { 216 .list = PLIST_HEAD_INIT(cpu_latency_constraints.list), 217 .target_value = PM_QOS_CPU_LATENCY_DEFAULT_VALUE, 218 .default_value = PM_QOS_CPU_LATENCY_DEFAULT_VALUE, 219 .no_constraint_value = PM_QOS_CPU_LATENCY_DEFAULT_VALUE, 220 .type = PM_QOS_MIN, 221}; 222 223/** 224 * cpu_latency_qos_limit - Return current system-wide CPU latency QoS limit. 225 */ 226s32 cpu_latency_qos_limit(void) 227{ 228 return pm_qos_read_value(&cpu_latency_constraints); 229} 230 231/** 232 * cpu_latency_qos_request_active - Check the given PM QoS request. 233 * @req: PM QoS request to check. 234 * 235 * Return: 'true' if @req has been added to the CPU latency QoS list, 'false' 236 * otherwise. 237 */ 238bool cpu_latency_qos_request_active(struct pm_qos_request *req) 239{ 240 return req->qos == &cpu_latency_constraints; 241} 242EXPORT_SYMBOL_GPL(cpu_latency_qos_request_active); 243 244static void cpu_latency_qos_apply(struct pm_qos_request *req, 245 enum pm_qos_req_action action, s32 value) 246{ 247 int ret = pm_qos_update_target(req->qos, &req->node, action, value); 248 if (ret > 0) 249 wake_up_all_idle_cpus(); 250} 251 252/** 253 * cpu_latency_qos_add_request - Add new CPU latency QoS request. 254 * @req: Pointer to a preallocated handle. 255 * @value: Requested constraint value. 256 * 257 * Use @value to initialize the request handle pointed to by @req, insert it as 258 * a new entry to the CPU latency QoS list and recompute the effective QoS 259 * constraint for that list. 260 * 261 * Callers need to save the handle for later use in updates and removal of the 262 * QoS request represented by it. 263 */ 264void cpu_latency_qos_add_request(struct pm_qos_request *req, s32 value) 265{ 266 if (!req) 267 return; 268 269 if (cpu_latency_qos_request_active(req)) { 270 WARN(1, KERN_ERR "%s called for already added request\n", __func__); 271 return; 272 } 273 274 trace_pm_qos_add_request(value); 275 276 req->qos = &cpu_latency_constraints; 277 cpu_latency_qos_apply(req, PM_QOS_ADD_REQ, value); 278} 279EXPORT_SYMBOL_GPL(cpu_latency_qos_add_request); 280 281/** 282 * cpu_latency_qos_update_request - Modify existing CPU latency QoS request. 283 * @req : QoS request to update. 284 * @new_value: New requested constraint value. 285 * 286 * Use @new_value to update the QoS request represented by @req in the CPU 287 * latency QoS list along with updating the effective constraint value for that 288 * list. 289 */ 290void cpu_latency_qos_update_request(struct pm_qos_request *req, s32 new_value) 291{ 292 if (!req) 293 return; 294 295 if (!cpu_latency_qos_request_active(req)) { 296 WARN(1, KERN_ERR "%s called for unknown object\n", __func__); 297 return; 298 } 299 300 trace_pm_qos_update_request(new_value); 301 302 if (new_value == req->node.prio) 303 return; 304 305 cpu_latency_qos_apply(req, PM_QOS_UPDATE_REQ, new_value); 306} 307EXPORT_SYMBOL_GPL(cpu_latency_qos_update_request); 308 309/** 310 * cpu_latency_qos_remove_request - Remove existing CPU latency QoS request. 311 * @req: QoS request to remove. 312 * 313 * Remove the CPU latency QoS request represented by @req from the CPU latency 314 * QoS list along with updating the effective constraint value for that list. 315 */ 316void cpu_latency_qos_remove_request(struct pm_qos_request *req) 317{ 318 if (!req) 319 return; 320 321 if (!cpu_latency_qos_request_active(req)) { 322 WARN(1, KERN_ERR "%s called for unknown object\n", __func__); 323 return; 324 } 325 326 trace_pm_qos_remove_request(PM_QOS_DEFAULT_VALUE); 327 328 cpu_latency_qos_apply(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); 329 memset(req, 0, sizeof(*req)); 330} 331EXPORT_SYMBOL_GPL(cpu_latency_qos_remove_request); 332 333/* User space interface to the CPU latency QoS via misc device. */ 334 335static int cpu_latency_qos_open(struct inode *inode, struct file *filp) 336{ 337 struct pm_qos_request *req; 338 339 req = kzalloc(sizeof(*req), GFP_KERNEL); 340 if (!req) 341 return -ENOMEM; 342 343 cpu_latency_qos_add_request(req, PM_QOS_DEFAULT_VALUE); 344 filp->private_data = req; 345 346 return 0; 347} 348 349static int cpu_latency_qos_release(struct inode *inode, struct file *filp) 350{ 351 struct pm_qos_request *req = filp->private_data; 352 353 filp->private_data = NULL; 354 355 cpu_latency_qos_remove_request(req); 356 kfree(req); 357 358 return 0; 359} 360 361static ssize_t cpu_latency_qos_read(struct file *filp, char __user *buf, 362 size_t count, loff_t *f_pos) 363{ 364 struct pm_qos_request *req = filp->private_data; 365 unsigned long flags; 366 s32 value; 367 368 if (!req || !cpu_latency_qos_request_active(req)) 369 return -EINVAL; 370 371 spin_lock_irqsave(&pm_qos_lock, flags); 372 value = pm_qos_get_value(&cpu_latency_constraints); 373 spin_unlock_irqrestore(&pm_qos_lock, flags); 374 375 return simple_read_from_buffer(buf, count, f_pos, &value, sizeof(s32)); 376} 377 378static ssize_t cpu_latency_qos_write(struct file *filp, const char __user *buf, 379 size_t count, loff_t *f_pos) 380{ 381 s32 value; 382 383 if (count == sizeof(s32)) { 384 if (copy_from_user(&value, buf, sizeof(s32))) 385 return -EFAULT; 386 } else { 387 int ret; 388 389 ret = kstrtos32_from_user(buf, count, 16, &value); 390 if (ret) 391 return ret; 392 } 393 394 cpu_latency_qos_update_request(filp->private_data, value); 395 396 return count; 397} 398 399static const struct file_operations cpu_latency_qos_fops = { 400 .write = cpu_latency_qos_write, 401 .read = cpu_latency_qos_read, 402 .open = cpu_latency_qos_open, 403 .release = cpu_latency_qos_release, 404 .llseek = noop_llseek, 405}; 406 407static struct miscdevice cpu_latency_qos_miscdev = { 408 .minor = MISC_DYNAMIC_MINOR, 409 .name = "cpu_dma_latency", 410 .fops = &cpu_latency_qos_fops, 411}; 412 413static int __init cpu_latency_qos_init(void) 414{ 415 int ret; 416 417 ret = misc_register(&cpu_latency_qos_miscdev); 418 if (ret < 0) 419 pr_err("%s: %s setup failed\n", __func__, 420 cpu_latency_qos_miscdev.name); 421 422 return ret; 423} 424late_initcall(cpu_latency_qos_init); 425#endif /* CONFIG_CPU_IDLE */ 426 427/* Definitions related to the frequency QoS below. */ 428 429/** 430 * freq_constraints_init - Initialize frequency QoS constraints. 431 * @qos: Frequency QoS constraints to initialize. 432 */ 433void freq_constraints_init(struct freq_constraints *qos) 434{ 435 struct pm_qos_constraints *c; 436 437 c = &qos->min_freq; 438 plist_head_init(&c->list); 439 c->target_value = FREQ_QOS_MIN_DEFAULT_VALUE; 440 c->default_value = FREQ_QOS_MIN_DEFAULT_VALUE; 441 c->no_constraint_value = FREQ_QOS_MIN_DEFAULT_VALUE; 442 c->type = PM_QOS_MAX; 443 c->notifiers = &qos->min_freq_notifiers; 444 BLOCKING_INIT_NOTIFIER_HEAD(c->notifiers); 445 446 c = &qos->max_freq; 447 plist_head_init(&c->list); 448 c->target_value = FREQ_QOS_MAX_DEFAULT_VALUE; 449 c->default_value = FREQ_QOS_MAX_DEFAULT_VALUE; 450 c->no_constraint_value = FREQ_QOS_MAX_DEFAULT_VALUE; 451 c->type = PM_QOS_MIN; 452 c->notifiers = &qos->max_freq_notifiers; 453 BLOCKING_INIT_NOTIFIER_HEAD(c->notifiers); 454} 455 456/** 457 * freq_qos_read_value - Get frequency QoS constraint for a given list. 458 * @qos: Constraints to evaluate. 459 * @type: QoS request type. 460 */ 461s32 freq_qos_read_value(struct freq_constraints *qos, 462 enum freq_qos_req_type type) 463{ 464 s32 ret; 465 466 switch (type) { 467 case FREQ_QOS_MIN: 468 ret = IS_ERR_OR_NULL(qos) ? 469 FREQ_QOS_MIN_DEFAULT_VALUE : 470 pm_qos_read_value(&qos->min_freq); 471 break; 472 case FREQ_QOS_MAX: 473 ret = IS_ERR_OR_NULL(qos) ? 474 FREQ_QOS_MAX_DEFAULT_VALUE : 475 pm_qos_read_value(&qos->max_freq); 476 break; 477 default: 478 WARN_ON(1); 479 ret = 0; 480 } 481 482 return ret; 483} 484 485/** 486 * freq_qos_apply - Add/modify/remove frequency QoS request. 487 * @req: Constraint request to apply. 488 * @action: Action to perform (add/update/remove). 489 * @value: Value to assign to the QoS request. 490 * 491 * This is only meant to be called from inside pm_qos, not drivers. 492 */ 493int freq_qos_apply(struct freq_qos_request *req, 494 enum pm_qos_req_action action, s32 value) 495{ 496 int ret; 497 498 switch(req->type) { 499 case FREQ_QOS_MIN: 500 ret = pm_qos_update_target(&req->qos->min_freq, &req->pnode, 501 action, value); 502 break; 503 case FREQ_QOS_MAX: 504 ret = pm_qos_update_target(&req->qos->max_freq, &req->pnode, 505 action, value); 506 break; 507 default: 508 ret = -EINVAL; 509 } 510 511 return ret; 512} 513 514/** 515 * freq_qos_add_request - Insert new frequency QoS request into a given list. 516 * @qos: Constraints to update. 517 * @req: Preallocated request object. 518 * @type: Request type. 519 * @value: Request value. 520 * 521 * Insert a new entry into the @qos list of requests, recompute the effective 522 * QoS constraint value for that list and initialize the @req object. The 523 * caller needs to save that object for later use in updates and removal. 524 * 525 * Return 1 if the effective constraint value has changed, 0 if the effective 526 * constraint value has not changed, or a negative error code on failures. 527 */ 528int freq_qos_add_request(struct freq_constraints *qos, 529 struct freq_qos_request *req, 530 enum freq_qos_req_type type, s32 value) 531{ 532 int ret; 533 534 if (IS_ERR_OR_NULL(qos) || !req) 535 return -EINVAL; 536 537 if (WARN(freq_qos_request_active(req), 538 "%s() called for active request\n", __func__)) 539 return -EINVAL; 540 541 req->qos = qos; 542 req->type = type; 543 ret = freq_qos_apply(req, PM_QOS_ADD_REQ, value); 544 if (ret < 0) { 545 req->qos = NULL; 546 req->type = 0; 547 } 548 549 return ret; 550} 551EXPORT_SYMBOL_GPL(freq_qos_add_request); 552 553/** 554 * freq_qos_update_request - Modify existing frequency QoS request. 555 * @req: Request to modify. 556 * @new_value: New request value. 557 * 558 * Update an existing frequency QoS request along with the effective constraint 559 * value for the list of requests it belongs to. 560 * 561 * Return 1 if the effective constraint value has changed, 0 if the effective 562 * constraint value has not changed, or a negative error code on failures. 563 */ 564int freq_qos_update_request(struct freq_qos_request *req, s32 new_value) 565{ 566 if (!req) 567 return -EINVAL; 568 569 if (WARN(!freq_qos_request_active(req), 570 "%s() called for unknown object\n", __func__)) 571 return -EINVAL; 572 573 if (req->pnode.prio == new_value) 574 return 0; 575 576 return freq_qos_apply(req, PM_QOS_UPDATE_REQ, new_value); 577} 578EXPORT_SYMBOL_GPL(freq_qos_update_request); 579 580/** 581 * freq_qos_remove_request - Remove frequency QoS request from its list. 582 * @req: Request to remove. 583 * 584 * Remove the given frequency QoS request from the list of constraints it 585 * belongs to and recompute the effective constraint value for that list. 586 * 587 * Return 1 if the effective constraint value has changed, 0 if the effective 588 * constraint value has not changed, or a negative error code on failures. 589 */ 590int freq_qos_remove_request(struct freq_qos_request *req) 591{ 592 int ret; 593 594 if (!req) 595 return -EINVAL; 596 597 if (WARN(!freq_qos_request_active(req), 598 "%s() called for unknown object\n", __func__)) 599 return -EINVAL; 600 601 ret = freq_qos_apply(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); 602 req->qos = NULL; 603 req->type = 0; 604 605 return ret; 606} 607EXPORT_SYMBOL_GPL(freq_qos_remove_request); 608 609/** 610 * freq_qos_add_notifier - Add frequency QoS change notifier. 611 * @qos: List of requests to add the notifier to. 612 * @type: Request type. 613 * @notifier: Notifier block to add. 614 */ 615int freq_qos_add_notifier(struct freq_constraints *qos, 616 enum freq_qos_req_type type, 617 struct notifier_block *notifier) 618{ 619 int ret; 620 621 if (IS_ERR_OR_NULL(qos) || !notifier) 622 return -EINVAL; 623 624 switch (type) { 625 case FREQ_QOS_MIN: 626 ret = blocking_notifier_chain_register(qos->min_freq.notifiers, 627 notifier); 628 break; 629 case FREQ_QOS_MAX: 630 ret = blocking_notifier_chain_register(qos->max_freq.notifiers, 631 notifier); 632 break; 633 default: 634 WARN_ON(1); 635 ret = -EINVAL; 636 } 637 638 return ret; 639} 640EXPORT_SYMBOL_GPL(freq_qos_add_notifier); 641 642/** 643 * freq_qos_remove_notifier - Remove frequency QoS change notifier. 644 * @qos: List of requests to remove the notifier from. 645 * @type: Request type. 646 * @notifier: Notifier block to remove. 647 */ 648int freq_qos_remove_notifier(struct freq_constraints *qos, 649 enum freq_qos_req_type type, 650 struct notifier_block *notifier) 651{ 652 int ret; 653 654 if (IS_ERR_OR_NULL(qos) || !notifier) 655 return -EINVAL; 656 657 switch (type) { 658 case FREQ_QOS_MIN: 659 ret = blocking_notifier_chain_unregister(qos->min_freq.notifiers, 660 notifier); 661 break; 662 case FREQ_QOS_MAX: 663 ret = blocking_notifier_chain_unregister(qos->max_freq.notifiers, 664 notifier); 665 break; 666 default: 667 WARN_ON(1); 668 ret = -EINVAL; 669 } 670 671 return ret; 672} 673EXPORT_SYMBOL_GPL(freq_qos_remove_notifier);