habanalabs: trace DMA allocations
This patch add tracepoints in the code for DMA allocation. The main purpose is to be able to cross data with the map operations and determine whether memory violation occurred, for example free DMA allocation before unmapping it from device memory. To achieve this the DMA alloc/free code flows were refactored so that a single DMA tracepoint will catch many flows. To get better understanding of what happened in the DMA allocations the real allocating function is added to the trace as well. Signed-off-by: Ohad Sharabi <osharabi@habana.ai> Reviewed-by: Oded Gabbay <ogabbay@kernel.org> Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org> Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
This commit is contained in:
parent
4eb87df3d0
commit
0263256791
|
@ -13,6 +13,8 @@
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/hwmon.h>
|
#include <linux/hwmon.h>
|
||||||
|
|
||||||
|
#include <trace/events/habanalabs.h>
|
||||||
|
|
||||||
#define HL_RESET_DELAY_USEC 10000 /* 10ms */
|
#define HL_RESET_DELAY_USEC 10000 /* 10ms */
|
||||||
|
|
||||||
enum dma_alloc_type {
|
enum dma_alloc_type {
|
||||||
|
@ -101,9 +103,10 @@ static int hl_access_sram_dram_region(struct hl_device *hdev, u64 addr, u64 *val
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *hl_dma_alloc_common(struct hl_device *hdev, size_t size, dma_addr_t *dma_handle,
|
static void *hl_dma_alloc_common(struct hl_device *hdev, size_t size, dma_addr_t *dma_handle,
|
||||||
gfp_t flag, enum dma_alloc_type alloc_type)
|
gfp_t flag, enum dma_alloc_type alloc_type,
|
||||||
|
const char *caller)
|
||||||
{
|
{
|
||||||
void *ptr;
|
void *ptr = NULL;
|
||||||
|
|
||||||
switch (alloc_type) {
|
switch (alloc_type) {
|
||||||
case DMA_ALLOC_COHERENT:
|
case DMA_ALLOC_COHERENT:
|
||||||
|
@ -117,11 +120,16 @@ static void *hl_dma_alloc_common(struct hl_device *hdev, size_t size, dma_addr_t
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trace_habanalabs_dma_alloc_enabled() && !ZERO_OR_NULL_PTR(ptr))
|
||||||
|
trace_habanalabs_dma_alloc(hdev->dev, (u64) (uintptr_t) ptr, *dma_handle, size,
|
||||||
|
caller);
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hl_asic_dma_free_common(struct hl_device *hdev, size_t size, void *cpu_addr,
|
static void hl_asic_dma_free_common(struct hl_device *hdev, size_t size, void *cpu_addr,
|
||||||
dma_addr_t dma_handle, enum dma_alloc_type alloc_type)
|
dma_addr_t dma_handle, enum dma_alloc_type alloc_type,
|
||||||
|
const char *caller)
|
||||||
{
|
{
|
||||||
switch (alloc_type) {
|
switch (alloc_type) {
|
||||||
case DMA_ALLOC_COHERENT:
|
case DMA_ALLOC_COHERENT:
|
||||||
|
@ -134,39 +142,44 @@ static void hl_asic_dma_free_common(struct hl_device *hdev, size_t size, void *c
|
||||||
hdev->asic_funcs->asic_dma_pool_free(hdev, cpu_addr, dma_handle);
|
hdev->asic_funcs->asic_dma_pool_free(hdev, cpu_addr, dma_handle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace_habanalabs_dma_free(hdev->dev, (u64) (uintptr_t) cpu_addr, dma_handle, size, caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *hl_asic_dma_alloc_coherent(struct hl_device *hdev, size_t size, dma_addr_t *dma_handle,
|
void *hl_asic_dma_alloc_coherent_caller(struct hl_device *hdev, size_t size, dma_addr_t *dma_handle,
|
||||||
gfp_t flag)
|
gfp_t flag, const char *caller)
|
||||||
{
|
{
|
||||||
return hl_dma_alloc_common(hdev, size, dma_handle, flag, DMA_ALLOC_COHERENT);
|
return hl_dma_alloc_common(hdev, size, dma_handle, flag, DMA_ALLOC_COHERENT, caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hl_asic_dma_free_coherent(struct hl_device *hdev, size_t size, void *cpu_addr,
|
void hl_asic_dma_free_coherent_caller(struct hl_device *hdev, size_t size, void *cpu_addr,
|
||||||
dma_addr_t dma_handle)
|
dma_addr_t dma_handle, const char *caller)
|
||||||
{
|
{
|
||||||
hl_asic_dma_free_common(hdev, size, cpu_addr, dma_handle, DMA_ALLOC_COHERENT);
|
hl_asic_dma_free_common(hdev, size, cpu_addr, dma_handle, DMA_ALLOC_COHERENT, caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *hl_cpu_accessible_dma_pool_alloc(struct hl_device *hdev, size_t size, dma_addr_t *dma_handle)
|
void *hl_cpu_accessible_dma_pool_alloc_caller(struct hl_device *hdev, size_t size,
|
||||||
|
dma_addr_t *dma_handle, const char *caller)
|
||||||
{
|
{
|
||||||
return hl_dma_alloc_common(hdev, size, dma_handle, 0, DMA_ALLOC_CPU_ACCESSIBLE);
|
return hl_dma_alloc_common(hdev, size, dma_handle, 0, DMA_ALLOC_CPU_ACCESSIBLE, caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hl_cpu_accessible_dma_pool_free(struct hl_device *hdev, size_t size, void *vaddr)
|
void hl_cpu_accessible_dma_pool_free_caller(struct hl_device *hdev, size_t size, void *vaddr,
|
||||||
|
const char *caller)
|
||||||
{
|
{
|
||||||
hl_asic_dma_free_common(hdev, size, vaddr, 0, DMA_ALLOC_CPU_ACCESSIBLE);
|
hl_asic_dma_free_common(hdev, size, vaddr, 0, DMA_ALLOC_CPU_ACCESSIBLE, caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *hl_asic_dma_pool_zalloc(struct hl_device *hdev, size_t size, gfp_t mem_flags,
|
void *hl_asic_dma_pool_zalloc_caller(struct hl_device *hdev, size_t size, gfp_t mem_flags,
|
||||||
dma_addr_t *dma_handle)
|
dma_addr_t *dma_handle, const char *caller)
|
||||||
{
|
{
|
||||||
return hl_dma_alloc_common(hdev, size, dma_handle, mem_flags, DMA_ALLOC_POOL);
|
return hl_dma_alloc_common(hdev, size, dma_handle, mem_flags, DMA_ALLOC_POOL, caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hl_asic_dma_pool_free(struct hl_device *hdev, void *vaddr, dma_addr_t dma_addr)
|
void hl_asic_dma_pool_free_caller(struct hl_device *hdev, void *vaddr, dma_addr_t dma_addr,
|
||||||
|
const char *caller)
|
||||||
{
|
{
|
||||||
hl_asic_dma_free_common(hdev, 0, vaddr, dma_addr, DMA_ALLOC_POOL);
|
hl_asic_dma_free_common(hdev, 0, vaddr, dma_addr, DMA_ALLOC_POOL, caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hl_dma_map_sgtable(struct hl_device *hdev, struct sg_table *sgt, enum dma_data_direction dir)
|
int hl_dma_map_sgtable(struct hl_device *hdev, struct sg_table *sgt, enum dma_data_direction dir)
|
||||||
|
|
|
@ -143,6 +143,25 @@ enum hl_mmu_enablement {
|
||||||
|
|
||||||
#define HL_MAX_DCORES 8
|
#define HL_MAX_DCORES 8
|
||||||
|
|
||||||
|
/* DMA alloc/free wrappers */
|
||||||
|
#define hl_asic_dma_alloc_coherent(hdev, size, dma_handle, flags) \
|
||||||
|
hl_asic_dma_alloc_coherent_caller(hdev, size, dma_handle, flags, __func__)
|
||||||
|
|
||||||
|
#define hl_cpu_accessible_dma_pool_alloc(hdev, size, dma_handle) \
|
||||||
|
hl_cpu_accessible_dma_pool_alloc_caller(hdev, size, dma_handle, __func__)
|
||||||
|
|
||||||
|
#define hl_asic_dma_pool_zalloc(hdev, size, mem_flags, dma_handle) \
|
||||||
|
hl_asic_dma_pool_zalloc_caller(hdev, size, mem_flags, dma_handle, __func__)
|
||||||
|
|
||||||
|
#define hl_asic_dma_free_coherent(hdev, size, cpu_addr, dma_handle) \
|
||||||
|
hl_asic_dma_free_coherent_caller(hdev, size, cpu_addr, dma_handle, __func__)
|
||||||
|
|
||||||
|
#define hl_cpu_accessible_dma_pool_free(hdev, size, vaddr) \
|
||||||
|
hl_cpu_accessible_dma_pool_free_caller(hdev, size, vaddr, __func__)
|
||||||
|
|
||||||
|
#define hl_asic_dma_pool_free(hdev, vaddr, dma_addr) \
|
||||||
|
hl_asic_dma_pool_free_caller(hdev, vaddr, dma_addr, __func__)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset Flags
|
* Reset Flags
|
||||||
*
|
*
|
||||||
|
@ -3446,15 +3465,18 @@ static inline bool hl_mem_area_crosses_range(u64 address, u32 size,
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t hl_set_dram_bar_default(struct hl_device *hdev, u64 addr);
|
uint64_t hl_set_dram_bar_default(struct hl_device *hdev, u64 addr);
|
||||||
void *hl_asic_dma_alloc_coherent(struct hl_device *hdev, size_t size, dma_addr_t *dma_handle,
|
void *hl_asic_dma_alloc_coherent_caller(struct hl_device *hdev, size_t size, dma_addr_t *dma_handle,
|
||||||
gfp_t flag);
|
gfp_t flag, const char *caller);
|
||||||
void hl_asic_dma_free_coherent(struct hl_device *hdev, size_t size, void *cpu_addr,
|
void hl_asic_dma_free_coherent_caller(struct hl_device *hdev, size_t size, void *cpu_addr,
|
||||||
dma_addr_t dma_handle);
|
dma_addr_t dma_handle, const char *caller);
|
||||||
void *hl_cpu_accessible_dma_pool_alloc(struct hl_device *hdev, size_t size, dma_addr_t *dma_handle);
|
void *hl_cpu_accessible_dma_pool_alloc_caller(struct hl_device *hdev, size_t size,
|
||||||
void hl_cpu_accessible_dma_pool_free(struct hl_device *hdev, size_t size, void *vaddr);
|
dma_addr_t *dma_handle, const char *caller);
|
||||||
void *hl_asic_dma_pool_zalloc(struct hl_device *hdev, size_t size, gfp_t mem_flags,
|
void hl_cpu_accessible_dma_pool_free_caller(struct hl_device *hdev, size_t size, void *vaddr,
|
||||||
dma_addr_t *dma_handle);
|
const char *caller);
|
||||||
void hl_asic_dma_pool_free(struct hl_device *hdev, void *vaddr, dma_addr_t dma_addr);
|
void *hl_asic_dma_pool_zalloc_caller(struct hl_device *hdev, size_t size, gfp_t mem_flags,
|
||||||
|
dma_addr_t *dma_handle, const char *caller);
|
||||||
|
void hl_asic_dma_pool_free_caller(struct hl_device *hdev, void *vaddr, dma_addr_t dma_addr,
|
||||||
|
const char *caller);
|
||||||
int hl_dma_map_sgtable(struct hl_device *hdev, struct sg_table *sgt, enum dma_data_direction dir);
|
int hl_dma_map_sgtable(struct hl_device *hdev, struct sg_table *sgt, enum dma_data_direction dir);
|
||||||
void hl_dma_unmap_sgtable(struct hl_device *hdev, struct sg_table *sgt,
|
void hl_dma_unmap_sgtable(struct hl_device *hdev, struct sg_table *sgt,
|
||||||
enum dma_data_direction dir);
|
enum dma_data_direction dir);
|
||||||
|
|
|
@ -51,15 +51,16 @@ DEFINE_EVENT(habanalabs_mmu_template, habanalabs_mmu_unmap,
|
||||||
TP_ARGS(dev, virt_addr, phys_addr, page_size, flush_pte));
|
TP_ARGS(dev, virt_addr, phys_addr, page_size, flush_pte));
|
||||||
|
|
||||||
DECLARE_EVENT_CLASS(habanalabs_dma_alloc_template,
|
DECLARE_EVENT_CLASS(habanalabs_dma_alloc_template,
|
||||||
TP_PROTO(struct device *dev, u64 cpu_addr, u64 dma_addr, size_t size),
|
TP_PROTO(struct device *dev, u64 cpu_addr, u64 dma_addr, size_t size, const char *caller),
|
||||||
|
|
||||||
TP_ARGS(dev, cpu_addr, dma_addr, size),
|
TP_ARGS(dev, cpu_addr, dma_addr, size, caller),
|
||||||
|
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
__string(dname, dev_name(dev))
|
__string(dname, dev_name(dev))
|
||||||
__field(u64, cpu_addr)
|
__field(u64, cpu_addr)
|
||||||
__field(u64, dma_addr)
|
__field(u64, dma_addr)
|
||||||
__field(u32, size)
|
__field(u32, size)
|
||||||
|
__field(const char *, caller)
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
|
@ -67,22 +68,24 @@ DECLARE_EVENT_CLASS(habanalabs_dma_alloc_template,
|
||||||
__entry->cpu_addr = cpu_addr;
|
__entry->cpu_addr = cpu_addr;
|
||||||
__entry->dma_addr = dma_addr;
|
__entry->dma_addr = dma_addr;
|
||||||
__entry->size = size;
|
__entry->size = size;
|
||||||
|
__entry->caller = caller;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("%s: cpu_addr: %#llx, dma_addr: %#llx, size: %#x",
|
TP_printk("%s: cpu_addr: %#llx, dma_addr: %#llx, size: %#x, caller: %s",
|
||||||
__get_str(dname),
|
__get_str(dname),
|
||||||
__entry->cpu_addr,
|
__entry->cpu_addr,
|
||||||
__entry->dma_addr,
|
__entry->dma_addr,
|
||||||
__entry->size)
|
__entry->size,
|
||||||
|
__entry->caller)
|
||||||
);
|
);
|
||||||
|
|
||||||
DEFINE_EVENT(habanalabs_dma_alloc_template, habanalabs_dma_alloc,
|
DEFINE_EVENT(habanalabs_dma_alloc_template, habanalabs_dma_alloc,
|
||||||
TP_PROTO(struct device *dev, u64 cpu_addr, u64 dma_addr, size_t size),
|
TP_PROTO(struct device *dev, u64 cpu_addr, u64 dma_addr, size_t size, const char *caller),
|
||||||
TP_ARGS(dev, cpu_addr, dma_addr, size));
|
TP_ARGS(dev, cpu_addr, dma_addr, size, caller));
|
||||||
|
|
||||||
DEFINE_EVENT(habanalabs_dma_alloc_template, habanalabs_dma_free,
|
DEFINE_EVENT(habanalabs_dma_alloc_template, habanalabs_dma_free,
|
||||||
TP_PROTO(struct device *dev, u64 cpu_addr, u64 dma_addr, size_t size),
|
TP_PROTO(struct device *dev, u64 cpu_addr, u64 dma_addr, size_t size, const char *caller),
|
||||||
TP_ARGS(dev, cpu_addr, dma_addr, size));
|
TP_ARGS(dev, cpu_addr, dma_addr, size, caller));
|
||||||
|
|
||||||
#endif /* if !defined(_TRACE_HABANALABS_H) || defined(TRACE_HEADER_MULTI_READ) */
|
#endif /* if !defined(_TRACE_HABANALABS_H) || defined(TRACE_HEADER_MULTI_READ) */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue