mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	async: Introduce async_schedule_dev_nocall()
In preparation for subsequent changes, introduce a specialized variant of async_schedule_dev() that will not invoke the argument function synchronously when it cannot be scheduled for asynchronous execution. The new function, async_schedule_dev_nocall(), will be used for fixing possible deadlocks in the system-wide power management core code. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> for the series. Tested-by: Youngmin Nam <youngmin.nam@samsung.com> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
		
							parent
							
								
									6aa09a5bcc
								
							
						
					
					
						commit
						7d4b5d7a37
					
				
					 2 changed files with 31 additions and 0 deletions
				
			
		|  | @ -90,6 +90,8 @@ async_schedule_dev(async_func_t func, struct device *dev) | |||
| 	return async_schedule_node(func, dev, dev_to_node(dev)); | ||||
| } | ||||
| 
 | ||||
| bool async_schedule_dev_nocall(async_func_t func, struct device *dev); | ||||
| 
 | ||||
| /**
 | ||||
|  * async_schedule_dev_domain - A device specific version of async_schedule_domain | ||||
|  * @func: function to execute asynchronously | ||||
|  |  | |||
|  | @ -243,6 +243,35 @@ async_cookie_t async_schedule_node(async_func_t func, void *data, int node) | |||
| } | ||||
| EXPORT_SYMBOL_GPL(async_schedule_node); | ||||
| 
 | ||||
| /**
 | ||||
|  * async_schedule_dev_nocall - A simplified variant of async_schedule_dev() | ||||
|  * @func: function to execute asynchronously | ||||
|  * @dev: device argument to be passed to function | ||||
|  * | ||||
|  * @dev is used as both the argument for the function and to provide NUMA | ||||
|  * context for where to run the function. | ||||
|  * | ||||
|  * If the asynchronous execution of @func is scheduled successfully, return | ||||
|  * true. Otherwise, do nothing and return false, unlike async_schedule_dev() | ||||
|  * that will run the function synchronously then. | ||||
|  */ | ||||
| bool async_schedule_dev_nocall(async_func_t func, struct device *dev) | ||||
| { | ||||
| 	struct async_entry *entry; | ||||
| 
 | ||||
| 	entry = kzalloc(sizeof(struct async_entry), GFP_KERNEL); | ||||
| 
 | ||||
| 	/* Give up if there is no memory or too much work. */ | ||||
| 	if (!entry || atomic_read(&entry_count) > MAX_WORK) { | ||||
| 		kfree(entry); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	__async_schedule_node_domain(func, dev, dev_to_node(dev), | ||||
| 				     &async_dfl_domain, entry); | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * async_synchronize_full - synchronize all asynchronous function calls | ||||
|  * | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Rafael J. Wysocki
						Rafael J. Wysocki