mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	lightnvm: remove nested lock conflict with mm
If a media manager tries to initialize it targets upon media manager initialization, the media manager will need to know which target types are available in LightNVM. The lists of which managers and target types are available shares the same lock. Therefore, on initialization, the nvm_lock is taken by LightNVM core, which later leads to a deadlock when target types are enumerated by the media manager. Add an exclusive lock for target types to resolve this conflict. Signed-off-by: Matias Bjørling <m@bjorling.me> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
		
							parent
							
								
									b76eb20bb0
								
							
						
					
					
						commit
						5cd907853d
					
				
					 1 changed files with 5 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -28,6 +28,7 @@
 | 
			
		|||
#include <linux/sched/sysctl.h>
 | 
			
		||||
 | 
			
		||||
static LIST_HEAD(nvm_tgt_types);
 | 
			
		||||
static DECLARE_RWSEM(nvm_tgtt_lock);
 | 
			
		||||
static LIST_HEAD(nvm_mgrs);
 | 
			
		||||
static LIST_HEAD(nvm_devices);
 | 
			
		||||
static DECLARE_RWSEM(nvm_lock);
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +38,7 @@ struct nvm_tgt_type *nvm_find_target_type(const char *name, int lock)
 | 
			
		|||
	struct nvm_tgt_type *tmp, *tt = NULL;
 | 
			
		||||
 | 
			
		||||
	if (lock)
 | 
			
		||||
		down_write(&nvm_lock);
 | 
			
		||||
		down_write(&nvm_tgtt_lock);
 | 
			
		||||
 | 
			
		||||
	list_for_each_entry(tmp, &nvm_tgt_types, list)
 | 
			
		||||
		if (!strcmp(name, tmp->name)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +47,7 @@ struct nvm_tgt_type *nvm_find_target_type(const char *name, int lock)
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
	if (lock)
 | 
			
		||||
		up_write(&nvm_lock);
 | 
			
		||||
		up_write(&nvm_tgtt_lock);
 | 
			
		||||
	return tt;
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(nvm_find_target_type);
 | 
			
		||||
| 
						 | 
				
			
			@ -55,12 +56,12 @@ int nvm_register_tgt_type(struct nvm_tgt_type *tt)
 | 
			
		|||
{
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
 | 
			
		||||
	down_write(&nvm_lock);
 | 
			
		||||
	down_write(&nvm_tgtt_lock);
 | 
			
		||||
	if (nvm_find_target_type(tt->name, 0))
 | 
			
		||||
		ret = -EEXIST;
 | 
			
		||||
	else
 | 
			
		||||
		list_add(&tt->list, &nvm_tgt_types);
 | 
			
		||||
	up_write(&nvm_lock);
 | 
			
		||||
	up_write(&nvm_tgtt_lock);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue