Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'dmaengine-fix-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine

Pull dmaengine fixes from Vinod Koul:

- email address Update for Jie Hai

- fix double increment of client_count in dma_chan_get()

- idxd driver fixes: use after free, probe error handling and callback
on wq disable

- fix for qcom gpi driver GO tre

- ptdma locking fix

- tegra & imx-sdma mem leak fix

* tag 'dmaengine-fix-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine:
ptdma: pt_core_execute_cmd() should use spinlock
dmaengine: tegra: Fix memory leak in terminate_all()
dmaengine: xilinx_dma: call of_node_put() when breaking out of for_each_child_of_node()
dmaengine: imx-sdma: Fix a possible memory leak in sdma_transfer_init
dmaengine: Fix double increment of client_count in dma_chan_get()
dmaengine: tegra210-adma: fix global intr clear
Add exception protection processing for vd in axi_chan_handle_err function
dmaengine: lgm: Move DT parsing after initialization
MAINTAINERS: update Jie Hai's email address
dmaengine: ti: k3-udma: Do conditional decrement of UDMA_CHAN_RT_PEER_BCNT_REG
dmaengine: idxd: Do not call DMX TX callbacks during workqueue disable
dmaengine: idxd: Prevent use after free on completion memory
dmaengine: idxd: Let probe fail when workqueue cannot be enabled
dmaengine: qcom: gpi: Set link_rx bit on GO TRE for rx operation

+46 -21
+1 -1
MAINTAINERS
··· 9298 9298 9299 9299 HISILICON DMA DRIVER 9300 9300 M: Zhou Wang <wangzhou1@hisilicon.com> 9301 - M: Jie Hai <haijie1@hisilicon.com> 9301 + M: Jie Hai <haijie1@huawei.com> 9302 9302 L: dmaengine@vger.kernel.org 9303 9303 S: Maintained 9304 9304 F: drivers/dma/hisi_dma.c
+4 -3
drivers/dma/dmaengine.c
··· 451 451 /* The channel is already in use, update client count */ 452 452 if (chan->client_count) { 453 453 __module_get(owner); 454 - goto out; 454 + chan->client_count++; 455 + return 0; 455 456 } 456 457 457 458 if (!try_module_get(owner)) ··· 471 470 goto err_out; 472 471 } 473 472 473 + chan->client_count++; 474 + 474 475 if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask)) 475 476 balance_ref_count(chan); 476 477 477 - out: 478 - chan->client_count++; 479 478 return 0; 480 479 481 480 err_out:
+6
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
··· 1018 1018 1019 1019 /* The bad descriptor currently is in the head of vc list */ 1020 1020 vd = vchan_next_desc(&chan->vc); 1021 + if (!vd) { 1022 + dev_err(chan2dev(chan), "BUG: %s, IRQ with no descriptors\n", 1023 + axi_chan_name(chan)); 1024 + goto out; 1025 + } 1021 1026 /* Remove the completed descriptor from issued list */ 1022 1027 list_del(&vd->node); 1023 1028 ··· 1037 1032 /* Try to restart the controller */ 1038 1033 axi_chan_start_first_queued(chan); 1039 1034 1035 + out: 1040 1036 spin_unlock_irqrestore(&chan->vc.lock, flags); 1041 1037 } 1042 1038
+13 -3
drivers/dma/idxd/device.c
··· 1172 1172 spin_unlock(&ie->list_lock); 1173 1173 1174 1174 list_for_each_entry_safe(desc, itr, &flist, list) { 1175 + struct dma_async_tx_descriptor *tx; 1176 + 1175 1177 list_del(&desc->list); 1176 1178 ctype = desc->completion->status ? IDXD_COMPLETE_NORMAL : IDXD_COMPLETE_ABORT; 1179 + /* 1180 + * wq is being disabled. Any remaining descriptors are 1181 + * likely to be stuck and can be dropped. callback could 1182 + * point to code that is no longer accessible, for example 1183 + * if dmatest module has been unloaded. 1184 + */ 1185 + tx = &desc->txd; 1186 + tx->callback = NULL; 1187 + tx->callback_result = NULL; 1177 1188 idxd_dma_complete_txd(desc, ctype, true); 1178 1189 } 1179 1190 } ··· 1401 1390 err_irq: 1402 1391 idxd_wq_unmap_portal(wq); 1403 1392 err_map_portal: 1404 - rc = idxd_wq_disable(wq, false); 1405 - if (rc < 0) 1393 + if (idxd_wq_disable(wq, false)) 1406 1394 dev_dbg(dev, "wq %s disable failed\n", dev_name(wq_confdev(wq))); 1407 1395 err: 1408 1396 return rc; ··· 1418 1408 dev_warn(dev, "Clients has claim on wq %d: %d\n", 1419 1409 wq->id, idxd_wq_refcount(wq)); 1420 1410 1421 - idxd_wq_free_resources(wq); 1422 1411 idxd_wq_unmap_portal(wq); 1423 1412 idxd_wq_drain(wq); 1424 1413 idxd_wq_free_irq(wq); 1425 1414 idxd_wq_reset(wq); 1415 + idxd_wq_free_resources(wq); 1426 1416 percpu_ref_exit(&wq->wq_active); 1427 1417 wq->type = IDXD_WQT_NONE; 1428 1418 wq->client_count = 0;
+3 -1
drivers/dma/imx-sdma.c
··· 1521 1521 sdma_config_ownership(sdmac, false, true, false); 1522 1522 1523 1523 if (sdma_load_context(sdmac)) 1524 - goto err_desc_out; 1524 + goto err_bd_out; 1525 1525 1526 1526 return desc; 1527 1527 1528 + err_bd_out: 1529 + sdma_free_bd(desc); 1528 1530 err_desc_out: 1529 1531 kfree(desc); 1530 1532 err_out:
+5 -5
drivers/dma/lgm/lgm-dma.c
··· 914 914 } 915 915 } 916 916 917 - static int ldma_cfg_init(struct ldma_dev *d) 917 + static int ldma_parse_dt(struct ldma_dev *d) 918 918 { 919 919 struct fwnode_handle *fwnode = dev_fwnode(d->dev); 920 920 struct ldma_port *p; ··· 1661 1661 p->ldev = d; 1662 1662 } 1663 1663 1664 - ret = ldma_cfg_init(d); 1665 - if (ret) 1666 - return ret; 1667 - 1668 1664 dma_dev->dev = &pdev->dev; 1669 1665 1670 1666 ch_mask = (unsigned long)d->channels_mask; ··· 1670 1674 else 1671 1675 ldma_dma_init_v3X(j, d); 1672 1676 } 1677 + 1678 + ret = ldma_parse_dt(d); 1679 + if (ret) 1680 + return ret; 1673 1681 1674 1682 dma_dev->device_alloc_chan_resources = ldma_alloc_chan_resources; 1675 1683 dma_dev->device_free_chan_resources = ldma_free_chan_resources;
+4 -3
drivers/dma/ptdma/ptdma-dev.c
··· 71 71 bool soc = FIELD_GET(DWORD0_SOC, desc->dw0); 72 72 u8 *q_desc = (u8 *)&cmd_q->qbase[cmd_q->qidx]; 73 73 u32 tail; 74 + unsigned long flags; 74 75 75 76 if (soc) { 76 77 desc->dw0 |= FIELD_PREP(DWORD0_IOC, desc->dw0); 77 78 desc->dw0 &= ~DWORD0_SOC; 78 79 } 79 - mutex_lock(&cmd_q->q_mutex); 80 + spin_lock_irqsave(&cmd_q->q_lock, flags); 80 81 81 82 /* Copy 32-byte command descriptor to hw queue. */ 82 83 memcpy(q_desc, desc, 32); ··· 92 91 93 92 /* Turn the queue back on using our cached control register */ 94 93 pt_start_queue(cmd_q); 95 - mutex_unlock(&cmd_q->q_mutex); 94 + spin_unlock_irqrestore(&cmd_q->q_lock, flags); 96 95 97 96 return 0; 98 97 } ··· 200 199 201 200 cmd_q->pt = pt; 202 201 cmd_q->dma_pool = dma_pool; 203 - mutex_init(&cmd_q->q_mutex); 202 + spin_lock_init(&cmd_q->q_lock); 204 203 205 204 /* Page alignment satisfies our needs for N <= 128 */ 206 205 cmd_q->qsize = Q_SIZE(Q_DESC_SIZE);
+1 -1
drivers/dma/ptdma/ptdma.h
··· 196 196 struct ptdma_desc *qbase; 197 197 198 198 /* Aligned queue start address (per requirement) */ 199 - struct mutex q_mutex ____cacheline_aligned; 199 + spinlock_t q_lock ____cacheline_aligned; 200 200 unsigned int qidx; 201 201 202 202 unsigned int qsize;
+1
drivers/dma/qcom/gpi.c
··· 1756 1756 tre->dword[3] = u32_encode_bits(TRE_TYPE_GO, TRE_FLAGS_TYPE); 1757 1757 if (spi->cmd == SPI_RX) { 1758 1758 tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_IEOB); 1759 + tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_LINK); 1759 1760 } else if (spi->cmd == SPI_TX) { 1760 1761 tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_CHAIN); 1761 1762 } else { /* SPI_DUPLEX */
+1
drivers/dma/tegra186-gpc-dma.c
··· 711 711 return err; 712 712 } 713 713 714 + vchan_terminate_vdesc(&tdc->dma_desc->vd); 714 715 tegra_dma_disable(tdc); 715 716 tdc->dma_desc = NULL; 716 717 }
+1 -1
drivers/dma/tegra210-adma.c
··· 221 221 int ret; 222 222 223 223 /* Clear any interrupts */ 224 - tdma_write(tdma, tdma->cdata->global_int_clear, 0x1); 224 + tdma_write(tdma, tdma->cdata->ch_base_offset + tdma->cdata->global_int_clear, 0x1); 225 225 226 226 /* Assert soft reset */ 227 227 tdma_write(tdma, ADMA_GLOBAL_SOFT_RESET, 0x1);
+3 -2
drivers/dma/ti/k3-udma.c
··· 762 762 if (uc->desc->dir == DMA_DEV_TO_MEM) { 763 763 udma_rchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val); 764 764 udma_rchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val); 765 - udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); 765 + if (uc->config.ep_type != PSIL_EP_NATIVE) 766 + udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); 766 767 } else { 767 768 udma_tchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val); 768 769 udma_tchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val); 769 - if (!uc->bchan) 770 + if (!uc->bchan && uc->config.ep_type != PSIL_EP_NATIVE) 770 771 udma_tchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); 771 772 } 772 773 }
+3 -1
drivers/dma/xilinx/xilinx_dma.c
··· 3143 3143 /* Initialize the channels */ 3144 3144 for_each_child_of_node(node, child) { 3145 3145 err = xilinx_dma_child_probe(xdev, child); 3146 - if (err < 0) 3146 + if (err < 0) { 3147 + of_node_put(child); 3147 3148 goto error; 3149 + } 3148 3150 } 3149 3151 3150 3152 if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {