ipq40xx: essedma: Fix dead lock
edma_read_append_stats() gets called from two places in the driver.
The first place is the kernel timer that periodically updates
the statistics, so nothing gets lost due to overflows.
The second one it's part of the userspace ethtool ioctl handler
to provide up-to-date values.
For this configuration, the use of spin_lock() is not sufficient
and as per:
<https://mirrors.edge.kernel.org/pub/linux/kernel/people/rusty/kernel-locking/c214.html>
the locking has to be upgraded to spin_lock_bh().
Signed-off-by: Masafumi UTSUGI <mutsugi@allied-telesis.co.jp>
[folded patch into 710-, rewrote message]
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
(cherry picked from commit f1d761f95e)
			
			
This commit is contained in:
		 Masafumi UTSUGI
					Masafumi UTSUGI
				
			
				
					committed by
					
						 Christian Lamparter
						Christian Lamparter
					
				
			
			
				
	
			
			
			 Christian Lamparter
						Christian Lamparter
					
				
			
						parent
						
							cd1136e550
						
					
				
				
					commit
					bf800022b2
				
			| @@ -2775,7 +2775,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com> | |||||||
| +	int i; | +	int i; | ||||||
| +	u32 stat; | +	u32 stat; | ||||||
| + | + | ||||||
| +	spin_lock(&edma_cinfo->stats_lock); | +	spin_lock_bh(&edma_cinfo->stats_lock); | ||||||
| +	p = (uint32_t *)&(edma_cinfo->edma_ethstats); | +	p = (uint32_t *)&(edma_cinfo->edma_ethstats); | ||||||
| + | + | ||||||
| +	for (i = 0; i < EDMA_MAX_TRANSMIT_QUEUE; i++) { | +	for (i = 0; i < EDMA_MAX_TRANSMIT_QUEUE; i++) { | ||||||
| @@ -2802,7 +2802,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com> | |||||||
| +		p++; | +		p++; | ||||||
| +	} | +	} | ||||||
| + | + | ||||||
| +	spin_unlock(&edma_cinfo->stats_lock); | +	spin_unlock_bh(&edma_cinfo->stats_lock); | ||||||
| +} | +} | ||||||
| + | + | ||||||
| +static void edma_statistics_timer(unsigned long data) | +static void edma_statistics_timer(unsigned long data) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user