mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	dm bufio: fix deadlock with loop device
When thin-volume is built on loop device, if available memory is low, the following deadlock can be triggered: One process P1 allocates memory with GFP_FS flag, direct alloc fails, memory reclaim invokes memory shrinker in dm_bufio, dm_bufio_shrink_scan() runs, mutex dm_bufio_client->lock is acquired, then P1 waits for dm_buffer IO to complete in __try_evict_buffer(). But this IO may never complete if issued to an underlying loop device that forwards it using direct-IO, which allocates memory using GFP_KERNEL (see: do_blockdev_direct_IO()). If allocation fails, memory reclaim will invoke memory shrinker in dm_bufio, dm_bufio_shrink_scan() will be invoked, and since the mutex is already held by P1 the loop thread will hang, and IO will never complete. Resulting in ABBA deadlock. Cc: stable@vger.kernel.org Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
This commit is contained in:
		
							parent
							
								
									2e6023850e
								
							
						
					
					
						commit
						bd293d071f
					
				
					 1 changed files with 1 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -1599,9 +1599,7 @@ dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
 | 
			
		|||
	unsigned long freed;
 | 
			
		||||
 | 
			
		||||
	c = container_of(shrink, struct dm_bufio_client, shrinker);
 | 
			
		||||
	if (sc->gfp_mask & __GFP_FS)
 | 
			
		||||
		dm_bufio_lock(c);
 | 
			
		||||
	else if (!dm_bufio_trylock(c))
 | 
			
		||||
	if (!dm_bufio_trylock(c))
 | 
			
		||||
		return SHRINK_STOP;
 | 
			
		||||
 | 
			
		||||
	freed  = __scan(c, sc->nr_to_scan, sc->gfp_mask);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue