Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1fded075 authored by Adrian Hunter's avatar Adrian Hunter Committed by Vinod Koul
Browse files

dmaengine: intel_mid_dma: locking and freeing fixes



Two issues are fixed:

1. DMA descriptors are reused so when freeing lli structures
that are linked to them, the pointer must be nulled.

2. midc_scan_descriptors() must be called with the
channel lock held.

Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@linux.intel.com>
parent 0ef7e206
Loading
Loading
Loading
Loading
+6 −1
Original line number Original line Diff line number Diff line
@@ -281,6 +281,7 @@ static void midc_dostart(struct intel_mid_dma_chan *midc,
 */
 */
static void midc_descriptor_complete(struct intel_mid_dma_chan *midc,
static void midc_descriptor_complete(struct intel_mid_dma_chan *midc,
		struct intel_mid_dma_desc *desc)
		struct intel_mid_dma_desc *desc)
		__releases(&midc->lock) __acquires(&midc->lock)
{
{
	struct dma_async_tx_descriptor	*txd = &desc->txd;
	struct dma_async_tx_descriptor	*txd = &desc->txd;
	dma_async_tx_callback callback_txd = NULL;
	dma_async_tx_callback callback_txd = NULL;
@@ -311,6 +312,7 @@ static void midc_descriptor_complete(struct intel_mid_dma_chan *midc,
			pci_pool_free(desc->lli_pool, desc->lli,
			pci_pool_free(desc->lli_pool, desc->lli,
						desc->lli_phys);
						desc->lli_phys);
			pci_pool_destroy(desc->lli_pool);
			pci_pool_destroy(desc->lli_pool);
			desc->lli = NULL;
		}
		}
		list_move(&desc->desc_node, &midc->free_list);
		list_move(&desc->desc_node, &midc->free_list);
		midc->busy = false;
		midc->busy = false;
@@ -490,7 +492,9 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,


	ret = dma_async_is_complete(cookie, last_complete, last_used);
	ret = dma_async_is_complete(cookie, last_complete, last_used);
	if (ret != DMA_SUCCESS) {
	if (ret != DMA_SUCCESS) {
		spin_lock_bh(&midc->lock);
		midc_scan_descriptors(to_middma_device(chan->device), midc);
		midc_scan_descriptors(to_middma_device(chan->device), midc);
		spin_unlock_bh(&midc->lock);


		last_complete = midc->completed;
		last_complete = midc->completed;
		last_used = chan->cookie;
		last_used = chan->cookie;
@@ -566,6 +570,7 @@ static int intel_mid_dma_device_control(struct dma_chan *chan,
			pci_pool_free(desc->lli_pool, desc->lli,
			pci_pool_free(desc->lli_pool, desc->lli,
						desc->lli_phys);
						desc->lli_phys);
			pci_pool_destroy(desc->lli_pool);
			pci_pool_destroy(desc->lli_pool);
			desc->lli = NULL;
		}
		}
		list_move(&desc->desc_node, &midc->free_list);
		list_move(&desc->desc_node, &midc->free_list);
	}
	}