forked from mirrors/linux
		
	PM / devfreq: Lock devfreq in trans_stat_show
There is no locking in this sysfs show function so stats printing can
race with a devfreq_update_status called as part of freq switching or
with initialization.
Also add an assert in devfreq_update_status to make it clear that lock
must be held by caller.
Fixes: 39688ce6fa ("PM / devfreq: account suspend/resume for stats")
Cc: stable@vger.kernel.org
Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
			
			
This commit is contained in:
		
							parent
							
								
									d68adc8f85
								
							
						
					
					
						commit
						2abb0d5268
					
				
					 1 changed files with 9 additions and 3 deletions
				
			
		|  | @ -160,6 +160,7 @@ int devfreq_update_status(struct devfreq *devfreq, unsigned long freq) | ||||||
| 	int lev, prev_lev, ret = 0; | 	int lev, prev_lev, ret = 0; | ||||||
| 	unsigned long cur_time; | 	unsigned long cur_time; | ||||||
| 
 | 
 | ||||||
|  | 	lockdep_assert_held(&devfreq->lock); | ||||||
| 	cur_time = jiffies; | 	cur_time = jiffies; | ||||||
| 
 | 
 | ||||||
| 	/* Immediately exit if previous_freq is not initialized yet. */ | 	/* Immediately exit if previous_freq is not initialized yet. */ | ||||||
|  | @ -1397,12 +1398,17 @@ static ssize_t trans_stat_show(struct device *dev, | ||||||
| 	int i, j; | 	int i, j; | ||||||
| 	unsigned int max_state = devfreq->profile->max_state; | 	unsigned int max_state = devfreq->profile->max_state; | ||||||
| 
 | 
 | ||||||
| 	if (!devfreq->stop_polling && |  | ||||||
| 			devfreq_update_status(devfreq, devfreq->previous_freq)) |  | ||||||
| 		return 0; |  | ||||||
| 	if (max_state == 0) | 	if (max_state == 0) | ||||||
| 		return sprintf(buf, "Not Supported.\n"); | 		return sprintf(buf, "Not Supported.\n"); | ||||||
| 
 | 
 | ||||||
|  | 	mutex_lock(&devfreq->lock); | ||||||
|  | 	if (!devfreq->stop_polling && | ||||||
|  | 			devfreq_update_status(devfreq, devfreq->previous_freq)) { | ||||||
|  | 		mutex_unlock(&devfreq->lock); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 	mutex_unlock(&devfreq->lock); | ||||||
|  | 
 | ||||||
| 	len = sprintf(buf, "     From  :   To\n"); | 	len = sprintf(buf, "     From  :   To\n"); | ||||||
| 	len += sprintf(buf + len, "           :"); | 	len += sprintf(buf + len, "           :"); | ||||||
| 	for (i = 0; i < max_state; i++) | 	for (i = 0; i < max_state; i++) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Leonard Crestez
						Leonard Crestez