drivers/hwtracing/intel_th/msu-sink.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
From: Sanman Pradhan <psanman@juniper.net>
When dma_alloc_coherent() fails part-way through
msu_sink_alloc_window(), pages allocated in earlier iterations are not
freed and the sg_table is left allocated.
The core does not recover this allocation failure. On error,
msc_buffer_win_alloc() frees only the msc_window object and does not
call the sink's ->free_window() callback, because the window was never
successfully added to the buffer's window list.
Also, msu_sink_alloc_window() increments priv->nr_sgts before the page
allocation loop completes. If the loop fails, nr_sgts remains elevated
for a window that was never fully allocated, which can eventually cause
false MAX_SGTS exhaustion.
Fix this by:
- deferring the sgts[]/nr_sgts update until after the allocation loop
succeeds; and
- unwinding all previously allocated DMA-coherent pages and freeing the
sg_table on allocation failure.
Fixes: f220df66f676 ("intel_th: msu-sink: An example msu buffer "sink"")
Cc: stable@vger.kernel.org
Signed-off-by: Sanman Pradhan <psanman@juniper.net>
---
drivers/hwtracing/intel_th/msu-sink.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/hwtracing/intel_th/msu-sink.c b/drivers/hwtracing/intel_th/msu-sink.c
index b809a7f805a9..ea3ff8415b90 100644
--- a/drivers/hwtracing/intel_th/msu-sink.c
+++ b/drivers/hwtracing/intel_th/msu-sink.c
@@ -65,19 +65,28 @@ static int msu_sink_alloc_window(void *data, struct sg_table **sgt, size_t size)
if (ret)
return -ENOMEM;
- priv->sgts[priv->nr_sgts++] = *sgt;
-
for_each_sg((*sgt)->sgl, sg_ptr, nents, i) {
block = dma_alloc_coherent(priv->dev->parent->parent,
PAGE_SIZE, &sg_dma_address(sg_ptr),
GFP_KERNEL);
if (!block)
- return -ENOMEM;
+ goto err_free_pages;
sg_set_buf(sg_ptr, block, PAGE_SIZE);
}
+ priv->sgts[priv->nr_sgts++] = *sgt;
+
return nents;
+
+err_free_pages:
+ for_each_sg((*sgt)->sgl, sg_ptr, i, ret)
+ dma_free_coherent(priv->dev->parent->parent, PAGE_SIZE,
+ sg_virt(sg_ptr), sg_dma_address(sg_ptr));
+
+ sg_free_table(*sgt);
+
+ return -ENOMEM;
}
/* See also: msc.c: __msc_buffer_win_free() */
--
2.34.1
From: Sanman Pradhan <psanman@juniper.net> Ping. Kindly requesting a review when you get a chance. https://lore.kernel.org/lkml/20260406175714.208227-1-sanman.pradhan@hpe.com/ Regards, Sanman Pradhan
© 2016 - 2026 Red Hat, Inc.