1 /* 2 * itmt.c: Support Intel Turbo Boost Max Technology 3.0 3 * 4 * (C) Copyright 2016 Intel Corporation 5 * Author: Tim Chen <tim.c.chen@linux.intel.com> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; version 2 10 * of the License. 11 * 12 * On platforms supporting Intel Turbo Boost Max Technology 3.0, (ITMT), 13 * the maximum turbo frequencies of some cores in a CPU package may be 14 * higher than for the other cores in the same package. In that case, 15 * better performance can be achieved by making the scheduler prefer 16 * to run tasks on the CPUs with higher max turbo frequencies. 17 * 18 * This file provides functions and data structures for enabling the 19 * scheduler to favor scheduling on cores can be boosted to a higher 20 * frequency under ITMT. 21 */ 22 23 #include <linux/sched.h> 24 #include <linux/cpumask.h> 25 #include <linux/cpuset.h> 26 #include <asm/mutex.h> 27 #include <linux/sched.h> 28 #include <linux/sysctl.h> 29 #include <linux/nodemask.h> 30 31 static DEFINE_MUTEX(itmt_update_mutex); 32 DEFINE_PER_CPU_READ_MOSTLY(int, sched_core_priority); 33 34 /* Boolean to track if system has ITMT capabilities */ 35 static bool __read_mostly sched_itmt_capable; 36 37 /** 38 * sched_set_itmt_support() - Indicate platform supports ITMT 39 * 40 * This function is used by the OS to indicate to scheduler that the platform 41 * is capable of supporting the ITMT feature. 42 * 43 * The current scheme has the pstate driver detects if the system 44 * is ITMT capable and call sched_set_itmt_support. 45 * 46 * This must be done only after sched_set_itmt_core_prio 47 * has been called to set the cpus' priorities. 48 */ 49 void sched_set_itmt_support(void) 50 { 51 mutex_lock(&itmt_update_mutex); 52 53 sched_itmt_capable = true; 54 55 mutex_unlock(&itmt_update_mutex); 56 } 57 58 /** 59 * sched_clear_itmt_support() - Revoke platform's support of ITMT 60 * 61 * This function is used by the OS to indicate that it has 62 * revoked the platform's support of ITMT feature. 63 * 64 */ 65 void sched_clear_itmt_support(void) 66 { 67 mutex_lock(&itmt_update_mutex); 68 69 sched_itmt_capable = false; 70 71 mutex_unlock(&itmt_update_mutex); 72 } 73 74 int arch_asym_cpu_priority(int cpu) 75 { 76 return per_cpu(sched_core_priority, cpu); 77 } 78 79 /** 80 * sched_set_itmt_core_prio() - Set CPU priority based on ITMT 81 * @prio: Priority of cpu core 82 * @core_cpu: The cpu number associated with the core 83 * 84 * The pstate driver will find out the max boost frequency 85 * and call this function to set a priority proportional 86 * to the max boost frequency. CPU with higher boost 87 * frequency will receive higher priority. 88 * 89 * No need to rebuild sched domain after updating 90 * the CPU priorities. The sched domains have no 91 * dependency on CPU priorities. 92 */ 93 void sched_set_itmt_core_prio(int prio, int core_cpu) 94 { 95 int cpu, i = 1; 96 97 for_each_cpu(cpu, topology_sibling_cpumask(core_cpu)) { 98 int smt_prio; 99 100 /* 101 * Ensure that the siblings are moved to the end 102 * of the priority chain and only used when 103 * all other high priority cpus are out of capacity. 104 */ 105 smt_prio = prio * smp_num_siblings / i; 106 per_cpu(sched_core_priority, cpu) = smt_prio; 107 i++; 108 } 109 } 110