Introduction to CPU frequency adjustment mode and frequency reduction method

Two drivers are implemented in the kernel, one is responsible for controlling the number of cores on and off the CPU, called the hot-plug driver, and the other is responsible for adjusting the frequency of the CPU, called the DVFS driver. The driver in the kernel will automatically adjust to use several CPUs and adjust the CPU frequency according to the system load. If the load is high, increase the frequency, or open a few more cores, or open a large core. If the load drops, you can turn off the big core, turn off the core, and reduce the frequency.

The following are the open source config configuration documents of two well-known mobile phone manufacturers:

60 CONFIG_CPU_FREQ=y                                                | 446 CONFIG_CPU_FREQ=y
 61 CONFIG_CPU_FREQ_STAT_DETAILS=y                                   | 447 CONFIG_CPU_FREQ_STAT=y
 62 CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y                        | 448 CONFIG_CPU_FREQ_STAT_DETAILS=y
 63 CONFIG_CPU_FREQ_GOV_PERFORMANCE=y                                | 449 # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
 64 CONFIG_CPU_FREQ_GOV_POWERSAVE=y                                  | 450 # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set                                        
 65 CONFIG_CPU_FREQ_GOV_USERSPACE=y                                  | 451 # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
 66 CONFIG_CPU_FREQ_GOV_ONDEMAND=y  
 
 # CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
 67 CONFIG_NET=y                                                     | 453 # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
 68 CONFIG_PACKET=y                                                  | 454 CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
 69 CONFIG_UNIX=y                                                    | 455 # CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
 70 CONFIG_XFRM_MIGRATE=y                                            | 456 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
 71 CONFIG_NET_KEY=y                                                 | 457 # CONFIG_CPU_FREQ_GOV_USERSPACE is not set
 72 CONFIG_INET=y                                                    | 458 # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
 73 CONFIG_IP_MULTICAST=y                                            | 459 CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
 74 CONFIG_IP_ADVANCED_ROUTER=y                                      | 460 # CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
 75 CONFIG_IP_MULTIPLE_TABLES=y                                      | 461 # CONFIG_CPUFREQ_DT is not set
在adb shell命令下,和cpu频率相关的目录:
/sys/devices/system/cpu/cpuX, X表示cpu number.
:/sys/devices/system/cpu/cpu0/cpufreq # ls
affected_cpus              related_cpus                  scaling_governor
cpuinfo_cur_freq           scaling_available_frequencies scaling_max_freq
cpuinfo_max_freq           scaling_available_governors   scaling_min_freq
cpuinfo_min_freq           scaling_cur_freq              scaling_setspeed
cpuinfo_transition_latency scaling_driver                stats

Read-write properties of these file nodes:

cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
 936 cpufreq_freq_attr_ro(cpuinfo_min_freq);
 937 cpufreq_freq_attr_ro(cpuinfo_max_freq);
 938 cpufreq_freq_attr_ro(cpuinfo_transition_latency);
 939 cpufreq_freq_attr_ro(scaling_available_governors);
 940 cpufreq_freq_attr_ro(scaling_driver);
 941 cpufreq_freq_attr_ro(scaling_cur_freq);
 942 cpufreq_freq_attr_ro(bios_limit);
 943 cpufreq_freq_attr_ro(related_cpus);
 944 cpufreq_freq_attr_ro(affected_cpus);
 945 cpufreq_freq_attr_rw(scaling_min_freq);
 946 cpufreq_freq_attr_rw(scaling_max_freq);                                                                                                                                                   
 947 cpufreq_freq_attr_rw(scaling_governor);
 948 cpufreq_freq_attr_rw(scaling_setspeed);
 
cpuinfo_cur_freq: The current operating frequency of the CPU
cpuinfo_max_freq: This file specifies the maximum operating frequency that the processor can run (unit: kHz)
cpuinfo_min_freq: This file specifies the minimum operating frequency that the processor can run (unit: kHz)
cpuinfo_transition_latency : This file defines the time required for the processor to switch between two different frequencies (unit: nanoseconds)
scaling_available_frequencies: List of all supported primary frequencies (unit: kHz)
scaling_available_governors: This file shows the supported frequencies in the current kernel All cpufreq governor types
scaling_cur_freq: current CPU operating frequency determined by governor and cpufreq core. This frequency is the main frequency that the kernel thinks the CPU is currently running
scaling_driver: This file shows which cpufreq driver the CPU is using
scaling_governor: Through the echo command, the governor type of the current processor can be changed
scaling_max_freq: Displays the upper and lower limits of the current policy (unit: kHz) It should be noted that when changing the cpu policy, you need to set scaling_max_freq first, and then scaling_min_freq

scaling_setspeed: If the user selects the "userspace" governor, then the main frequency of the cpu can be set to a specified value. Just need this value to be between scaling_min_freq and scaling_max_freq.

Working mode: cat scaling_available_governors
:/sys/devices/system/cpu/cpu0/cpufreq # cat scaling_available_governors
ondemand userspace powersave interactive performance
CPU frequency adjustment mode:
1. Performance. Regardless of power consumption, only the highest frequency is used.
2. Interactive. Go directly to the highest frequency, and then watch the CPU load slowly decrease.
3. Powersave. Usually run at the lowest frequency, the fluency will be affected, generally do not use this!
4. Userspace. You can manually adjust the frequency in the user space.
5. Ondemand. Check the load regularly and adjust the frequency according to the load.


For this Freescale implementation:
performance is used by default, but freescale is changed to interactive after boot is completed.
device/fsl/tek_mx6/init.rc:
on property:sys.boot_completed=1
# Set default CPU frequency governor
# Set timer 40ms, min sample 60ms,hispeed at cpufreq MAX freq in freq_table at load 40%
    write /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor interactive
can finally be viewed through the scaling_governor file.


Operating frequency:
The currently supported CPU adjustment modes can be viewed through scaling_available_frequencies.
:/sys/devices/system/cpu/cpu0/cpufreq # cat scaling_available_frequencies
1092000 988000 858000 793000 637000 494000 364000 221000

Relevant data structures:
kernel-4.4$ vi ./include/linux/cpufreq.h +59
struct cpufreq_policy {
	/* CPUs sharing clock, require sw coordination */
	cpumask_var_t		cpus;	/* Online CPUs only */
	cpumask_var_t		related_cpus; /* Online + Offline CPUs */
	cpumask_var_t		real_cpus; /* Related and present */

	unsigned int		shared_type; /* ACPI: ANY or ALL affected CPUs
						should set cpufreq */
	unsigned int		cpu;    /* cpu managing this policy, must be online */

	struct clk		*clk;
	struct cpufreq_cpuinfo	cpuinfo;/* see above */

	unsigned int		min;    /* in kHz */
	unsigned int		max;    /* in kHz */
	unsigned int		cur;    /* in kHz, only needed if cpufreq
					 * governors are used */
	unsigned int		restore_freq; /* = policy->cur before transition */
	unsigned int		suspend_freq; /* freq to set during suspend */

	unsigned int		policy; /* see above */
	unsigned int		last_policy; /* policy before unplug */
	struct cpufreq_governor	*governor; /* see below */
	void			*governor_data;
	bool			governor_enabled; /* governor start/stop flag */
	char			last_governor[CPUFREQ_NAME_LEN]; /* last governor used */

	struct work_struct	update; /* if update_policy() needs to be
					 * called, but you're in IRQ context */

	struct cpufreq_user_policy user_policy;
	struct cpufreq_frequency_table	*freq_table;

	struct list_head        policy_list;
	struct kobject		kobj;
	struct completion	kobj_unregister;

	/*
	 * The rules for this semaphore:
	 * - Any routine that wants to read from the policy structure will
	 *   do a down_read on this semaphore.
	 * - Any routine that will write to the policy structure and/or may take away
	 *   the policy altogether (eg. CPU hotplug), will hold this lock in write
	 *   mode before doing so.
	 *
	 * Additional rules:
	 * - Lock should not be held across
	 *     __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
	 */
	struct rw_semaphore	rwsem;


	/*
	 * Fast switch flags:
	 * - fast_switch_possible should be set by the driver if it can
	 *   guarantee that frequency can be changed on any CPU sharing the
	 *   policy and that the change will affect all of the policy CPUs then.
	 * - fast_switch_enabled is to be set by governors that support fast
	 *   freqnency switching with the help of cpufreq_enable_fast_switch().
	 */
	bool                    fast_switch_possible;
	bool                    fast_switch_enabled;

	/* Cached frequency lookup from cpufreq_driver_resolve_freq. */
	unsigned int cached_target_freq;
	int cached_resolved_idx;

	/* Synchronization for frequency transitions */
	bool			transition_ongoing; /* Tracks transition status */
	spinlock_t		transition_lock;
	wait_queue_head_t	transition_wait;
	struct task_struct	*transition_task; /* Task which is doing the transition */

	/* cpufreq-stats */
	struct cpufreq_stats	*stats;

	/* For cpufreq driver's internal use */
	void			*driver_data;
};
Select the corresponding frequency list according to the platform and the default maximum frequency.
So there are two ways to reduce the frequency:
1. Directly compile the static modification frequency list.
2. Dynamically write through the scaling_max_freq file.


/ # cat /proc/cpufreq/cpufreq_ptpod_freq_volt
cat /proc/cpufreq/cpufreq_ptpod_freq_volt
[0] = { .cpufreq_khz = 1092000, .cpufreq_volt = 119375, .cpufreq_volt_org = 125000, },
[1] = { .cpufreq_khz = 988 = 114375, .cpufreq_volt_org = 121875, },
[2] = { .cpufreq_khz = 858000, .cpufreq_volt = 108125, .cpufreq_volt_org = 118750, },
[3] = { .cpufreq_khz = 793000, .cpufreq_volt00, org_cpufrevolt_q 1050 115000, },
[4] = { .cpufreq_khz = 637000, .cpufreq_volt = 101250, .cpufreq_volt_org = 110000, },
[5] = { .cpufreq_khz = 494000, .cpufreq_volt = 101250, .cpufreq_volt_org = 1050, }
[6] = {.cpufreq_khz = 364000, .cpufreq_volt = 101250, .cpufreq_volt_org = 100000,},
[7] = {.cpufreq_khz = 221000, .cpufreq_volt = 101250
,, / cpufreq_oppidx
cat proc / cpufreq / cpufreq_oppidx
[MT_CPU_DVFS_LITTLE / 0]
cpufreq_oppidx = 1
        OP (1092000, 119375),
        OP (988000, 114375),
        OP (858000, 108125),
        OP (79312
        (650)) ,
        OP (494000, 101250),
        OP (364000, 101250),
        OP (221000, 101250),

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326287152&siteId=291194637